有没有一种方法可以“快速失败”?对于带有 Maven Surefire 插件的 junit?
我目前正在使用maven 开发一个java 项目。我们使用 Maven Surefire 插件来运行我们的 junit 套件作为构建过程的一部分。
我们的测试套件在覆盖范围和执行时间方面都在快速增长。当您等待十分钟才发现测试在测试的第一分钟失败时,执行时间非常令人沮丧且耗时。
我想找到一种方法,使构建过程在测试套件中出现第一个错误/失败时失败。我知道这对于其他构建工具是可能的,但我一直无法找到使用 Maven Surefire 来做到这一点的方法。
我知道在 Surefire jira 中有 此问题的未解决票证Surefire jira 中的功能,但我希望有一个现有的解决方案。
I'm currently working on a java project using maven. We use the maven surefire plugin to run our junit suite as part of the build process.
Our test suite is rapidly growing, in both coverage and execution time. The execution time is very frustrating and time consuming when you end up waiting ten minutes to find out that a test failed in the first minute of testing.
I would like to find a way to make the build process fail upon the first error/failure in the test suite. I know that this is possible for other build tools, but I have been unable to find a way to do this with maven surefire.
I know that there is an unresolved ticket for this functionality in the surefire jira, but I'm hoping that there is an existing solution out there for this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
截至 2015 年 9 月 6 日 似乎有,
-Dsurefire.skipAfterFailureCount=1
。截至 2015 年 10 月 19 日 2.19版本已发布。
As of September 6th 2015 it appears there is,
-Dsurefire.skipAfterFailureCount=1
.As of October 19th 2015 version 2.19 has been released.
可能有合适的解决方法,但这取决于您的要求,并且您需要使用可以处理 jvm 进程返回代码的 CI 服务器。
基本思想是完全停止 Maven 的 JVM 进程,并让操作系统知道该进程已意外停止。然后,像 Jenkins/Hudson 这样的持续集成服务器应该能够检查非零退出代码并让您知道测试失败了。
第一步是确保 Surefire 在第一次测试失败时退出 JVM。您可以使用 JUnit 4.7 或更高版本,通过使用自定义
RunListener
(将其放入 src/test/java 中)来实现此目的:然后,您需要配置该类,以便 Surefire 将其注册到 JUnit 4 Runner 。编辑
pom.xml
并将listener
配置属性添加到 maven-surefire-plugin。您还需要将surefire 配置为不派生新的JVM 进程来执行测试。否则,它将继续进行下一个测试用例。如果这没有帮助,我会尝试分叉 Maven Surefire junit 提供程序插件。
顺便说一句,根据定义,单元测试的运行速度应该快于 0.1 秒。如果您的构建由于单元测试而确实花费了很长时间,那么您将来必须让它们运行得更快。
There may be a suitable workaround, but it depends on your requirements and you need to use a CI server which can handle jvm process return codes.
The basic idea is to stop Maven's JVM process altogether and let the OS know that the process has stopped unexpectedly. Then, a continuous integration server like Jenkins/Hudson should be able to check for a non-zero exit code and let you know that a test has failed.
The first step is to make surefire exit the JVM at the first test failure. You can do that with JUnit 4.7 or higher by using a custom
RunListener
(put it in src/test/java):Then, you need to configure that class so surefire will register it with the JUnit 4 Runner. Edit your
pom.xml
and add thelistener
configuration property to the maven-surefire-plugin. You will also need to configure surefire to not fork a new JVM process for executing the tests. Otherwise, it will just go on with the next test cases.If this does not help, I'd try to fork the maven surefire junit provider plugin.
Btw, unit tests, by definition, should run faster than 0.1 seconds. If your build really takes so long due to the unit tests, you will have to make them run faster in the future.
据我所知,不,这确实需要解决
As far as I know, no, and this really requires the resolution of SUREFIRE-580. If you want to make this happen faster, you should at least vote for the issue and, optionally, submit a patch ;)
您可以使用
--fail-fast
选项运行maven
:例如:
mvn clean test -ff
http://books.sonatype.com/mvnref-book/reference/running-sect-options.html
You can run
maven
with--fail-fast
option:an example can be:
mvn clean test -ff
http://books.sonatype.com/mvnref-book/reference/running-sect-options.html
这不是问题的直接答案,但通过 grep 提供 Maven 的输出也很有用,可以去掉大部分内容并帮助您查看测试失败的位置。
像这样:
产生这样的输出(对于我的代码):
更容易看到第一个失败错误在哪里。
This isn't a direct answer to the question, but it can also be useful to feed the output of maven through grep, to strip out most stuff and help you to see where the test failures are.
Like this:
Which produces output (for my code) like this:
Much easier to see where the first error of failure is.
对于 Junit 5,您可以使用以下要点快速失败:
https://gist.github.com/alexec/ 7e065b4049a8787fa9ac3f2ca522acf3
您使用
@ExtendWith(FailFast.class)
注释了您的测试类,然后是您的测试。仅当任何@Order(1)
成功时,才会运行带有@Order(2)
注释的测试。For Junit 5, you can fail fast using this gist:
https://gist.github.com/alexec/7e065b4049a8787fa9ac3f2ca522acf3
You annotated your tests classes with
@ExtendWith(FailFast.class)
and then your test. Test annotated with@Order(2)
only runs if any@Order(1)
succeeded.如果不完全符合您的需要,可以采用几种加快速度的方法:
如果是多模块构建,请添加
--fail-fast 到命令行以在第一个模块之后退出。
研究故障保护以长期发展
运行集成测试
生命周期的不同阶段。
研究基于配置文件的快速和慢速测试解决方案 -
有办法吗告诉 Surefire 跳过某个包中的测试?。
A few ways to speed it up if not exactly what you need:
If it's a multi module build, add
--fail-fast to the command line to drop out after the first module.
Look into failsafe to move long
running integration tests onto a
different phase of the lifecycle.
Look into a profile based solution for fast and slow tests -
Is there a way to tell surefire to skip tests in a certain package?.
这并不能完全解决问题,但我的工作场所最终提出的解决方案是使用 Atlassian 的 Clover 运行与更改的代码相关的测试的专门构建。
我们有一个 Clover 构建,可以运行更改后的代码的测试,然后启动完整的测试构建。
事实证明这是一个令人满意的解决方案。
This doesn't solve the question exactly, but the solution that my workplace ultimately came up with was to use Atlassian's Clover to run specialized builds of just tests pertaining to changed code.
We have a Clover build that runs the tests for the changed code and in turn kicks off the full test build.
This has proven to be a satisfactory solution.