Java 在特定测试失败时停止JUnit套件

Java 在特定测试失败时停止JUnit套件,java,junit,Java,Junit,我有一个JUnit测试套件,格式如下: @RunWith(Suite.class) @Suite.SuiteClasses( { xx.class, yy.cass }) public class AllTests { public static Test suite() { TestSuite suite = new TestSuite(AllTests.class.getName()); //$JUnit-BEGIN$ //$JUnit-END$ ret

我有一个JUnit测试套件,格式如下:

@RunWith(Suite.class)
@Suite.SuiteClasses( { xx.class, yy.cass })

public class AllTests {

public static Test suite() {
    TestSuite suite = new TestSuite(AllTests.class.getName());
    //$JUnit-BEGIN$

    //$JUnit-END$
    return suite;
}
}
然后,这将调用以下常规测试:

public class xxx {

@Test
public void test () throws {
    ...
public class FooTest {

   private static boolean bar;

   @BeforeClass
   public static void setUpBeforeClass() throws Exception {
         bar = false;
   }

   @Before
   public void setUp() throws Exception {
         assertTrue(bar);
   }

   @Test
   public void test() {
         System.out.println("something");
         assertTrue(true);
   }

   @Test
   public void test1() {
         System.out.println("Something2");
         assertTrue(true);
   }
}
在这种情况下,如果在第一次测试中出现错误或失败,我希望停止测试套件的其余部分的运行。但是其他测试中的错误/失败是可以的,套件应该完成尽可能多的其他测试。基本上,第一次测试失败表明运行其余测试是不安全的


这可能吗?

调用
System.exit()
有什么问题?

是否使用ant运行测试


您可以编写自定义测试侦听器。您可以在Ant(EnabLeTestListEngEvices事件)中设置此项。

< P>如果是<强>第一次/强>测试,那么考虑将其验证移动到@ BeeExpLASS,如果失败则抛出异常。然后,在出现此异常的情况下,只有@AfterClass方法将运行


当然,这样您就缺少了在测试设置方法中创建的所有夹具工件。

基于Hiro2k的答案(谢谢!),我使用了以下解决方案。这是一个有点黑客,但它的工作

可以阻止其他测试运行的测试位于@Suite.SuiteClasses列表的顶部。然后,该测试具有以下内容:

private static boolean shouldStopRestOfSuite = false;

    @Test
    public void test () throws Throwable {
    try {
            ... run some test code...
    }
    catch (Throwable e) {
        shouldStopRestOfSuite = true;
        throw e;
    }
}
请注意,上面的代码确实需要捕获Throwable(而不是exception),以便捕获断言错误。它还会重新抛出错误,以便JUnit记录下来进行分析

还有另一种测试方法:

@Test
public void testKillIfNeeded () throws Exception {
    if (!shouldStopRestOfSuite) {
        return;
    }

    System.out.println ("Test suite killed due to dangerous error / failure");
    System.exit(1);
}
上面的代码是第二次运行的,将终止JUnit进程

使用此方法,如果出现问题,JUnit测试不会在失败/错误时结束,但是JUnit会记录失败/错误以供分析,并且不会运行进一步的测试


不太漂亮,但它确实起作用了:)

喜欢你的答案,但在集成测试中使用
@之前,我做了如下操作:

public class xxx {

@Test
public void test () throws {
    ...
public class FooTest {

   private static boolean bar;

   @BeforeClass
   public static void setUpBeforeClass() throws Exception {
         bar = false;
   }

   @Before
   public void setUp() throws Exception {
         assertTrue(bar);
   }

   @Test
   public void test() {
         System.out.println("something");
         assertTrue(true);
   }

   @Test
   public void test1() {
         System.out.println("Something2");
         assertTrue(true);
   }
}

问候

首先需要junit RunListener:

import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
import org.junit.runner.notification.RunNotifier;

public class FailureListener extends RunListener {

    private RunNotifier runNotifier;

    public FailureListener(RunNotifier runNotifier) {
        super();
        this.runNotifier=runNotifier;
    }

    @Override
    public void testFailure(Failure failure) throws Exception {
        super.testFailure(failure);
        this.runNotifier.pleaseStop();
    }
}
然后准备一套:

public class StopOnFailureSuite extends Suite {

    public StopOnFailureSuite(Class<?> klass, Class<?>[] suiteClasses) throws InitializationError {
        super(klass, suiteClasses);
    }

    public StopOnFailureSuite(Class<?> klass) throws InitializationError {
        super(klass, klass.getAnnotation(SuiteClasses.class).value());
    }

    @Override
    public void run(RunNotifier runNotifier) {
        runNotifier.addListener(new FailureListener(runNotifier));
        super.run(runNotifier);
    }
}

首先,在运行第二个测试之前,您应该捕获一个错误并进行检查

@Rule
public ErrorCollector collector = new ErrorCollector();
1。添加错误。

collector.addError(new Throwable("first thing went wrong"));
2。在相关运行之前进行检查

collector.checkThat(getResult(), not(containsString("ERROR!")));

引用-

我如何通过编程检查断言是否失败?好的,我看到我可以在第一次测试中捕获断言错误,然后调用System.exit(),但是JUnit测试不会通过或失败,只要停止运行即可。似乎应该有一种更优雅的方式。Re:一种更优雅的方式,我不相信JUnit提供了这种开箱即用的功能。这可能导致测试之间的耦合。理想情况下,您的测试应该彼此独立运行,并且不受其他故障的影响。如果你坚持,那么Hiro2k的建议是最好的。是的,我不想参与整个辩论,但如果你真的想要一种更优雅的方式,那么你必须找到一种方法,将测试与运行顺序分离。如果你使用cucumber并配置了钩子类,使用System.exit(0)或1,它不会转到after和before方法,在某些情况下,这些方法处理终止实例和完成报告。尽管这是一个选项-我通常不使用Ant(在Eclipse中使用Run As>JUnit Test)。您将如何创建“自定义测试侦听器”?我得到了带有haltonfailure=“true”的ant部分,但在一个套件中,如果其中一个套件的测试失败,它不会停止。“定制测试监听器”能做什么?为了实现问题的要求,
FailureListener
不应停止任何失败的测试。最好过滤故障类型,只停止对特定错误的测试。例如,创建自己的
异常
类,并将其放入
第一个测试类
。然后使用
failure.getException()
来确定是否停止测试。这绝对适合我所寻找的。如果测试失败率超过30%,我希望停止测试,而不是特定的错误,我使用的是Cucumber BDD。我只需要重写run函数并添加listener,这可以通过@beforeachtest(){assertFalse(“测试已中止。”,shouldStopRestOfSuite);}之类的命令来减少笨拙。我用
assumeTrue()
替换了
assertTrue()