云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

亚马逊云_T430服务器_高性能

小七 141 0

为行为驱动开发集成apachespark和cumber

这是FIS Global的客座博客数据处理中最困难的场景之一是确保数据是正确的和预期的。我们可以采取各种测试方法来解决这个问题,但这些方法通常限制了团队中的协作量,并且不能直接回答"我如何证明一切都有效"的问题使用行为驱动开发(BDD)模式来开发我们的转换可以使整个团队能够参与并专注于结果。黄瓜项目(黄瓜.io)为在大多数项目中实现BDD方法提供了一个易于使用的框架。当结合apachespark进行数据处理和Cucumber时(黄瓜.io),我们进行了令人信服的组合,以保持系统的规模,并可以证明数据被正确处理。这不仅可以帮助开发团队,还可以引入其他方法来成功测试通常很难证明的场景,例如机器学习。为什么是黄瓜和阿帕奇火花?当今大多数软件都是以敏捷的方式协作完成的。这意味着我们有一个健康的混合专业人士,他们有着不同的视角,尝试着进行构建软件的团队运动。项目面临的最大问题之一是工程师和领域专家之间的低质量沟通。Cucumber允许我们以一种简单的、基于语言的方法编写软件的一部分,使所有团队成员都能轻松地阅读单元测试。我们的重点是详细说明我们希望系统返回的结果。团队中的非技术成员可以轻松地创建、读取和验证系统的测试。通常apachespark是处理数据的众多组件中的一个,这可以鼓励多个测试框架。Cucumber可以帮助我们提供一致的单元测试策略,当项目可能扩展到apachespark之后进行数据处理。我们创建了一个可读的敏捷验收框架,而不是在子项目之间混合不同的单元测试策略。这是在创造一种"自动化验收测试"的形式。最重要的是,我们能够创建开发过程中生成的"实时文档"。单元测试不是一个单独的文档过程,而是一个可读的文档,它可以使外部各方可读。每次更新代码时,文档都会更新。这是真正的双赢。我们成功的秘诀为了成功,我们需要一个配方。成功的BDD数据转换项目一杯阿帕奇火花1杯黄瓜.io2杯IntelliJ(如果你觉得IntelliJ太咸,就用Eclipse代替)½杯数据块。首先,添加到基于Java的项目Maven文件中https://cumber.io/docs/reference/jvm\java)信息库克斯黄瓜-java81.2.5款测试我们还需要设置Junit Runner来识别黄瓜。包mypackage;进口cucumber.api.cucumber选项;进口黄瓜.api.junit黄瓜;进口org.junit.runner.运行;@奔跑(黄瓜。等级)@黄瓜选项(plugin={"漂亮"html:target/黄瓜"})公共类RunCukesTest{}为了增加乐趣,依赖注入可以添加一些香料到你的食谱。虽然Scala可以作为Spark的一个项目使用,但是我们发现Java项目对于cumber来说效果更好。JVM允许我们与每种语言的接口进行交互。我们需要创建一个.feature文件,这个文件是用一种叫做Gherkin的可执行语言编写的。这将有一个简单的格式:特色:吃点好东西场景:吃点冰淇淋给我一个蛋卷冰淇淋当我吃冰淇淋蛋卷的时候那我就应该高兴了我们可以注意到这里有一些关键字在起作用:给定、何时、然后、特性和场景。这些关键字可以用任何方式使用,标准化的几个关键字是为了使可读性。功能文件真正告诉读者正在做什么。下一步您将需要混合步骤定义。步骤定义是如何或者基本上是Java代码。一个很酷的好处是Cucumber可以根据特性文件为您提供放入步骤定义中的方法。最后也是最重要的一步是实际编写数据转换。为此,我们需要我们的杀手锏。阿帕奇·斯帕克。Apache Spark killer在我们的数据处理中所做的根本改变是什么。到目前为止,数据处理对我们来说是一个批处理过程。我们会把数据放进去,等一段时间,然后进行处理。在这个过程的最后,可能需要等待一段时间,我们可以验证结果。围绕这种方法,我们有许多类型的"单元测试",但都非常薄弱,而且常常被忽视。质量是在系统中假设的,而不是保证。使用apachespark,我们可以执行数据处理并立即验证。事实上,我们保证了速度。我们能够将数据处理封装在统一的测试框架中,保证速度,并立即知道结果。我们现在可以证明和保证质量。当你将这一点扩展到Spark来完成机器学习任务时,这一点在传统上很难及时证明,那么快速移动的能力就会加速。数据处理场景我们选择使用一个相当简单但可能很常见的场景。当数据生产者生成数据时,我们通常关心数据是何时生成的。出于我们的目的,我们假设时间总是以Epoch时间(Unix时间)记录,并且生成它的机器与所有已知的时间同步完全一致。我们的消费者,我们的墙内的用户,关心的是以一种更易读的方式拥有时间。为了简单起见,我们假设他们总是希望时间发生在太平洋夏令时。类提取类(sparkSession:sparkSession){val TIMESTAMP_FORMAT="yyyy-MM-dd HH:MM:ss"def RunExtractJob(sourceFilePath:String,destinationFilePath:String):单位={val sourceDataFrame:DataFrame=GetJsonDataFrame(sourceFilePath)val extractedDataFrame:DataFrame=提取数据帧(sourceDataFrame)SaveJsonDataFrame(extractedDataFrame,destinationFilePath)}def GetJsonDataFrame(filePath:String):数据帧={sparkSession.read.json(文件路径)}def ExtractDataFrame(数据帧:数据帧):数据帧={进口sparkSession隐式._数据帧.withColumn("timestampGmt",来自\u unixtime($"unixTimestamp")).withColumn("timestampLtz",日期格式(($"UnixtTimeStamp"+($"timezoneOffset"*60*60)).cast(TimestampType,TIMESTAMP_格式))}def SaveJsonDataFrame(dataFrame:dataFrame,filePath:String):单位={dataFrame.write.json(文件路径)}}当,给予,然后,和Gherkin是我们的语言解析器,它为记录"可执行规范"提供了一个轻量级结构。它的主要目标是可读性。对于这个场景,我们将编写以下单元测试:@提取@TempFileCleanup@ApacheSpark特点:Json日志提取过程背景:一般系统设置假设系统是UTC时间场景:将历元时间基本提取到可读的本地时区如果有一个文件"srcFolder/示例.json"以下几行:|{"logId":1,"unixTimestamp":1459482142,"时区偏移":-6}||{"logId":2,"unixTimestamp":1459482142,"时区偏移":-2}|调用RunExtractJob方法时|源文件夹| srcFolder/*||目标文件夹| dstFolder|然后在"dstFolder"文件夹中会有一个"\u SUCCESS"文件文件夹"dstFolder"将包含包含以下数据帧行的json文件:|logId | unixTimestamp |时区偏移| timestamp gmt | timestampLtz||1 | 1459482142 |-6 | 2016-04-01 03:42:22 | 2016-03-31 21:42:22||2 | 1459482142 |-2 | 2016-04-01 03:42:22 | 2016-04-01 01:42:22|加快速度这就是真正的魔法发生的地方。我们的小黄瓜文件是写出来的,可以清楚地向我们的团队解释。因此,我们需要执行它,并找出我们易于理解的文件将如何执行单元测试。因此,如果我们运行它,我们将得到一些输出:@给定("^系统以UTC时间$")public void the_system_is_in_UTC_time()抛出可丢弃的{//在这里编写代码,将上面的短语转化为具体的操作抛出新的PendingException();}Cucumber框架已经自动生成了我们需要实现的方法。现在我们需要将特性文件与运行单元测试的实际调用挂接在一起。所以我们来填一下。公共类提取StepDefinitions{@给定("^系统以UTC时间$")public void theSystemMissingMTTime()抛出可抛出的{时区.setDefault(时区.获取时区("UTC");}@给定("^there a file\"([^"]*)\"包含以下行:$")public void thereIsAFileWithTheFollowingLines(字符串属性路径,列表行)抛出可抛出的{File File=新文件(Helpers.getTempPath(属性路径));文件.getParentFile().mkdirs();PrintWriter writer=新建PrintWriter(文件.getAbsolutePath(),"UTF-8");for(字符串str:lines){作家.println(结构修剪());}writer.close();}@当("^方法(RunExtractJob | RunExtractJobV2)用$"调用时)public void theMethodRunExtractJobGetsCalledWith(String jobName,Maparguments)抛出Throwable{如果(作业名.compareTo("RunExtractJob")==0){新建ExtractionClass(Helpers.testSparkSession).RunExtractJob(Helpers.getTempPath(参数.get("源文件夹"),Helpers.getTempPath(参数.get("目标文件夹"));}否则如果(作业名.compareTo("RunExtractJobV2")==0){新抽取类v2(测试辅助程序).RunExtractJob(Helpers.getTempPath(参数.get("源文件夹"),Helpers.getTempPath(参数.get("目标文件夹"),参数.get("时区偏移"));}else{throw new PendingException();}…这似乎是在JUnit中简单地实现单元测试的额外工作。但是如果我们单独在JUnit中实现,我们的测试将只有系统的开发人员才能完全读取。钩子真的不需要太多额外的工作,而黄瓜实际上通过创造完成这项工作所需的树桩而有所帮助。我们所做的是创建一种方法,以敏捷的方式为系统的用户记录我们的系统。我们可以删除额外的工作,以记录在其他地方,因为我们已经做了工作。我们也可以做