背景:
我们有一个用 Java 编写的相当大的 REST API,我们正在结合单元测试和功能测试对其进行测试。测试它时需要进行许多变体,特别是在功能级别。虽然单元测试位于树中,但功能测试位于单独的代码存储库中。
我们目前使用 Jacoco 进行测试覆盖,使用 TestNG 运行我们的单元测试,但我相信我的问题的答案应该适用于其他工具组合。
我们在 Jenkins 中有几个不同的工作,这些工作是由 checkin 主要项目触发的。其中包括运行 Coverity 等工具的作业以及几个不同的功能测试作业。这些作业由初始提交触发,在所有下游作业成功完成之前,初始提交不被视为“绿色”。
问题:
我们如何获取覆盖率报告(如 Jacoco 二进制文件和 TestNG xml 文件)并将它们组合起来以显示我们所有测试的总代码覆盖率?具体来说,如果它们存在于同一个作业/目录中,我们知道如何组合它们,但这些文件分布在可能在不同时间运行的多个 Jenkins 作业中。
根据我的经验,最普遍接受的处理方式是使用 Promoted Builds Plugin触发所有作业,然后在完成触发作业时拉出它们的工件。但是,当您尝试汇总一两个以上的工作时,我觉得这种扩展性不是很好。当您的主项目(旧版本等)可能有多个变体时,尤其如此。
我知道可以在 Jenkins 中对文件进行指纹识别,这样我们就知道 -.jar 与作业 A、B 和 C 中使用的版本相同。是否存在可以检索所有匹配模式的文件的插件是否存在不同的指纹文件?
另一种解决方案(可能从 ant/groovy 脚本运行)是将测试数据推送到与 git commit hash 绑定(bind)的某个目录,并在基于 roll-up 作业中检索所有此类数据在基础项目的 git commit hash 上。
有没有简单的方法可以做到这一点?有没有人想出更好的其他方法来解决这个问题?
谢谢,
迈克尔
最佳答案
面对类似的问题,调整 jacoco maven 插件配置以合并 jacoco 结果。基本上将 jacoco-unit.exec 和 jacoco-it.exec 合并为一个二进制文件,并通过管道步骤在 Jenkins 上发布合并结果。
pom.xml:
<plugin>
<inherited>false</inherited>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.agent.version}</version>
<executions>
<execution>
<id>merge-results</id>
<phase>post-integration-test</phase>
<goals>
<goal>merge</goal>
</goals>
<configuration>
<fileSets>
<fileSet>
<directory>${project.parent.build.directory}</directory>
<includes>
<include>jacoco-*.exec</include>
</includes>
</fileSet>
</fileSets>
<destFile>${project.parent.build.directory}/jacoco.exec</destFile>
</configuration>
</execution>
</executions>
</plugin>
Jenkins 文件:
echo 'Publish Jacoco trend'
step($class: 'JacocoPublisher',
execPattern: '**/jacoco.exec',
classPattern: '**/classes',
sourcePattern: '**/src/main/java',
)
但是,您仍然需要通过另一个构建步骤从多个 Jenkins 构建中获取 jacoco 二进制文件,或者明确指定它们的位置。
关于java - 合并来自多个 Jenkins 作业的测试覆盖率和测试结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39983103/
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2
Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/