54

我目前正在使用 maven 开发一个 java 项目。作为构建过程的一部分,我们使用 maven surefire 插件来运行我们的 junit 套件。

我们的测试套件在覆盖范围和执行时间方面都在快速增长。当您最终等待十分钟才能发现测试在测试的第一分钟失败时,执行时间非常令人沮丧和耗时。

我想找到一种方法使构建过程在测试套件中的第一个错误/失败时失败。我知道这对于其他构建工具是可能的,但我一直无法找到使用 maven surefire 的方法。

我知道在surefire jira中有一个未解决的问题,但我希望有一个现有的解决方案。

4

7 回答 7

55

截至 2015 年 9 月 6 日,似乎存在-Dsurefire.skipAfterFailureCount=1.

截至 2015 年 10 月 19 日,版本 2.19 已经发布

于 2015-09-17T21:46:41.063 回答
13

据我所知,没有,这确实需要SUREFIRE-580的分辨率。如果您想更快地实现这一点,您至少应该为这个问题投票,并且可以选择提交一个补丁;)

于 2009-12-17T22:31:25.637 回答
12

可能有合适的解决方法,但这取决于您的要求,您需要使用可以处理 jvm 进程返回代码的 CI 服务器。

基本思想是完全停止 Maven 的 JVM 进程,并让操作系统知道该进程已意外停止。然后,像 Jenkins/Hudson 这样的持续集成服务器应该能够检查非零退出代码并让您知道测试失败。

第一步是确保在第一次测试失败时退出 JVM。您可以通过使用自定义RunListener(将其放在 src/test/java 中)使用 JUnit 4.7 或更高版本来做到这一点:

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 秒。如果由于单元测试,您的构建确实需要很长时间,那么您将来必须让它们运行得更快。

于 2011-10-18T07:07:49.830 回答
3

这不是问题的直接答案,但通过 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

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

于 2015-11-16T15:57:43.803 回答
3

您可以maven使用--fail-fast以下选项运行:

-ff选项对于运行交互式构建并希望在开发周期中获得快速反馈的开发人员非常有用。

一个例子可以是:

mvn clean test -ff

http://books.sonatype.com/mvnref-book/reference/running-sect-options.html

于 2017-10-11T10:55:11.003 回答
0

这并不能完全解决问题,但我的工作场所最终提出的解决方案是使用 Atlassian 的 Clover 运行与更改的代码有关的测试的专门构建。

我们有一个 Clover 构建,它运行更改代码的测试,然后启动完整的测试构建。

这已被证明是一个令人满意的解决方案。

于 2010-03-16T21:21:33.550 回答
0

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

  • 如果是多模块构建,请在命令行中添加 --fail-fast 以在第一个模块之后退出。

  • 研究故障安全以将长时间运行的集成测试转移到生命周期的不同阶段。

  • 查看基于配置文件的快速和慢速测试解决方案 - 有没有办法告诉surefire跳过某个包中的测试?.

于 2010-12-20T17:11:34.400 回答