Maven Surefire 插件 + 并行构建
Maven Surefire plugin + parallel build
在我们相当大的项目(大约 600 个 maven 模块)中,我们决定尝试 maven 的并行构建功能。所以我安装了 maven 3.3 并尝试 运行 单元测试。
我发现有时我们的单元测试会失败。如果我 运行 模块 'alone' 它可以工作,当然如果我们 运行 maven 'sequentially' (没有 -T 选项)它也可以工作。
所以,我认为这是由于有时测试会干扰,可能是某些静态代码或共享实例导致了这些失败。
我的问题是,运行 我的项目的单元测试的最佳方式是什么?
我知道在每次测试 运行ning 时生成 JVM 的选项,但由于我们有数千个单元测试,我担心这样的构建会永远持续下去:)
据我所知,有 3 种可能的解决方案:
只需跳过测试,compile/package/install 一切并行。然后 运行 分别测试。这种方法对 jenkins 来说是可行的,但对于刚习惯 运行 mvn install
的开发人员来说,我可能会很麻烦
以某种方式扩展 surefire 插件,如果失败,它会自动重新运行 N 次单元测试。如果测试失败,比如 50% 次——它真的很不稳定,应该会导致整个构建失败。由于两个原因,我不想使用 @RunWith 注释:a。有很多测试要用这个注解更新,我们没有基础 class 之类的东西。 b.一些测试已经包含此注释(例如电源模拟或 junit 规则)
以某种方式将 surefire 插件扩展到不同 class 加载程序中的 运行 测试。由于 Maven 似乎 运行 具有相同 classloader 的多个模块(我刚刚进行了 2 个打印 classloader 地址的测试,所以我想到了这个解决方案在两个不同的子模块中并确保 classloader 相同,地址相同)。这个解决方案看起来很有趣但相对复杂。
在深入研究这些解决方案并与我的经理交谈之前,
如果有人可以评论其中一个 solutions/provide 另一个,我将不胜感激。我只是不想重新发明轮子,希望能节省一些时间:)
非常感谢
运行将每个测试 class 放在单独的 JVM 中怎么样? (并可能在其他测试中重用分叉的 JVM)。
老实说,你好像没试过。查看文档 https://maven.apache.org/surefire/maven-surefire-plugin/examples/fork-options-and-parallel-execution.html
只是示例的复制粘贴:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<configuration>
<forkCount>3</forkCount>
<reuseForks>true</reuseForks>
<argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
<systemPropertyVariables>
<databaseSchema>MY_TEST_SCHEMA_${surefire.forkNumber}</databaseSchema>
</systemPropertyVariables>
<workingDirectory>FORK_DIRECTORY_${surefire.forkNumber}</workingDirectory>
</configuration>
</plugin>
顺便说一下,surefire 可以重新运行 失败的测试:https://maven.apache.org/surefire/maven-surefire-plugin/examples/rerun-failing-tests.html。就是怕你设置不了门槛。
也不是分叉会使调试(例如,附加调试器)变得非常困难。
根据我的经验,并非所有的 surefire 设置都与 forking 兼容,因此您可能需要在调整配置时逐步进行,以了解哪些是实际工作的,哪些是没有。
在我们相当大的项目(大约 600 个 maven 模块)中,我们决定尝试 maven 的并行构建功能。所以我安装了 maven 3.3 并尝试 运行 单元测试。
我发现有时我们的单元测试会失败。如果我 运行 模块 'alone' 它可以工作,当然如果我们 运行 maven 'sequentially' (没有 -T 选项)它也可以工作。
所以,我认为这是由于有时测试会干扰,可能是某些静态代码或共享实例导致了这些失败。
我的问题是,运行 我的项目的单元测试的最佳方式是什么? 我知道在每次测试 运行ning 时生成 JVM 的选项,但由于我们有数千个单元测试,我担心这样的构建会永远持续下去:)
据我所知,有 3 种可能的解决方案:
只需跳过测试,compile/package/install 一切并行。然后 运行 分别测试。这种方法对 jenkins 来说是可行的,但对于刚习惯 运行 mvn install
的开发人员来说,我可能会很麻烦
以某种方式扩展 surefire 插件,如果失败,它会自动重新运行 N 次单元测试。如果测试失败,比如 50% 次——它真的很不稳定,应该会导致整个构建失败。由于两个原因,我不想使用 @RunWith 注释:a。有很多测试要用这个注解更新,我们没有基础 class 之类的东西。 b.一些测试已经包含此注释(例如电源模拟或 junit 规则)
以某种方式将 surefire 插件扩展到不同 class 加载程序中的 运行 测试。由于 Maven 似乎 运行 具有相同 classloader 的多个模块(我刚刚进行了 2 个打印 classloader 地址的测试,所以我想到了这个解决方案在两个不同的子模块中并确保 classloader 相同,地址相同)。这个解决方案看起来很有趣但相对复杂。
在深入研究这些解决方案并与我的经理交谈之前, 如果有人可以评论其中一个 solutions/provide 另一个,我将不胜感激。我只是不想重新发明轮子,希望能节省一些时间:)
非常感谢
运行将每个测试 class 放在单独的 JVM 中怎么样? (并可能在其他测试中重用分叉的 JVM)。
老实说,你好像没试过。查看文档 https://maven.apache.org/surefire/maven-surefire-plugin/examples/fork-options-and-parallel-execution.html
只是示例的复制粘贴:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<configuration>
<forkCount>3</forkCount>
<reuseForks>true</reuseForks>
<argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
<systemPropertyVariables>
<databaseSchema>MY_TEST_SCHEMA_${surefire.forkNumber}</databaseSchema>
</systemPropertyVariables>
<workingDirectory>FORK_DIRECTORY_${surefire.forkNumber}</workingDirectory>
</configuration>
</plugin>
顺便说一下,surefire 可以重新运行 失败的测试:https://maven.apache.org/surefire/maven-surefire-plugin/examples/rerun-failing-tests.html。就是怕你设置不了门槛。
也不是分叉会使调试(例如,附加调试器)变得非常困难。
根据我的经验,并非所有的 surefire 设置都与 forking 兼容,因此您可能需要在调整配置时逐步进行,以了解哪些是实际工作的,哪些是没有。