有没有一种方法可以让junit使用maven surefire插件“快速失败”?

nhhxz33t  于 2023-01-21  发布在  Maven
关注(0)|答案(8)|浏览(165)

我目前正在用maven做一个java项目,我们使用maven surefire插件来运行我们的junit套件,作为构建过程的一部分。
我们的测试套件在覆盖率和执行时间上都在快速增长。当你最终等了十分钟才发现一个测试在测试的第一分钟就失败了时,执行时间是非常令人沮丧和耗时的。
我想找到一种方法来使构建过程在测试套件中的第一个错误/失败时失败。我知道这对于其他构建工具是可能的,但是我一直无法找到一种方法来用maven surefire做到这一点。
我知道surefire jira中有an unresolved ticket for this functionality,但我希望有一个现有的解决方案。

ctehm74n

ctehm74n1#

截至2015年9月6日,似乎有-Dsurefire.skipAfterFailureCount=1
截至2015年10月19日version 2.19 has been released

vsikbqxv

vsikbqxv2#

据我所知,没有,这确实需要SUREFIRE-580的解决方案,如果你想让这个问题更快地发生,你至少应该投票支持这个问题,并且,可选地,提交一个补丁;)

uplii1fm

uplii1fm3#

可能有一个合适的变通方法,但这取决于您的需求,并且您需要使用一个可以处理JVM进程返回代码的CI服务器。
基本思想是完全停止Maven的JVM进程,让操作系统知道进程意外停止,然后,像Jenkins/哈德逊这样的持续集成服务器应该能够检查非零退出代码,并让您知道测试失败。
第一步是确保在第一次测试失败时退出JVM,您可以在JUnit 4.7或更高版本中使用定制的RunListener(将其放在src/test/java中)来完成此操作:

package org.example
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
public class FailFastListener extends RunListener {
        public void testFailure(Failure failure) throws Exception {
                System.err.println("FAILURE: " + failure);
                System.exit(-1);
        }
}

然后,您需要配置该类,以便surefire将其注册到JUnit 4 Runner。编辑您的pom.xml并将listener配置属性添加到maven-surefire-plugin。您还需要配置surefire,使其不派生新的JVM进程来执行测试。否则,它将继续执行下一个测试用例。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.10</version>
    <configuration>
        <forkMode>never</forkMode>
        <properties>
            <property>
                <name>listener</name>
                <value>org.example.FailFastListener</value>
            </property>
        </properties>
    </configuration>
</plugin>

如果这没有帮助,我会尝试派生maven surefire junit提供者插件。
顺便说一句,根据定义,单元测试应该运行得比0.1秒快。如果你的构建真的因为单元测试而花费了这么长的时间,你将不得不在将来让它们运行得更快。

sy5wg1nm

sy5wg1nm4#

您可以使用--fail-fast选项运行maven
-ff选项对于运行交互式构建、希望在开发周期中获得快速反馈的开发人员非常有用。
一个例子可以是:
mvn clean test -ff
http://books.sonatype.com/mvnref-book/reference/running-sect-options.html

bqucvtff

bqucvtff5#

这并不是问题的直接答案,但是通过grep提供maven的输出也是很有用的,可以去除大部分内容,帮助您查看测试失败的地方。
就像这样:

mvn test | grep -w 'Running\|Tests'

它产生如下输出(对于我的代码):

Running scot.mygov.pp.test.dashboard.DashboardJsonSerDesCRUDTest
Tests run: 26, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.029 sec
Running scot.mygov.pp.test.dashboard.DashboardBaselineCRUDTest
Tests run: 26, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.026 sec
Running scot.mygov.pp.test.dashboard.DashboardDatabaseValidationTest
Tests run: 7, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.264 sec
Running scot.mygov.pp.test.dashboard.DashboardServiceWebServiceIsolationCRUDTest
Tests run: 26, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.032 sec

更容易看出失败的第一个错误在哪里。

pw136qt2

pw136qt26#

如果不完全符合您的需要,有几种方法可以加快速度:

wsewodh2

wsewodh27#

这并没有完全解决问题,但我的工作场所最终提出的解决方案是使用Atlassian的三叶草来运行专门的构建,这些构建只是与更改的代码有关的测试。
我们有一个三叶草构建版本,它为更改的代码运行测试,然后启动完整的测试构建版本。
这已证明是一个令人满意的解决办法。

ergxz8rk

ergxz8rk8#

对于Junit 5,可以使用以下要点快速失败:
https://gist.github.com/alexec/7e065b4049a8787fa9ac3f2ca522acf3
您先使用@ExtendWith(FailFast.class)标注测试类,然后使用测试。使用@Order(2)标注的测试仅在任何@Order(1)成功时运行。

相关问题