如果特定测试失败,则停止JUnit套件

时间:2012-04-05 22:28:09

标签: 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$
    return suite;
}
}

然后调用这样的vanilla测试:

public class xxx {

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

我有一种情况,如果在第一次测试中出现错误或失败,我想停止运行测试套件的其余部分。但是其他错误/失败是可以的,套件应该完成尽可能多的其他测试。基本上,第一次测试失败将表明运行其余测试是不安全的。

这可能吗?

7 个答案:

答案 0 :(得分:13)

首先你需要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);
    }
}

运行你的套房:

@RunWith(StopOnFailureSuite.class)
@Suite.SuiteClasses({
    FirstTestClass.class,
    SecondTestClass.class,
    ...
})

答案 1 :(得分:8)

致电System.exit()有什么问题?

答案 2 :(得分:4)

如果是第一次测试,则考虑将其验证移至@BeforeClass并在失败时抛出异常。然后,只有@AfterClass方法才会出现此异常。

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

答案 3 :(得分:3)

基于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(不是异常),因此它会捕获断言错误。它还会重新抛出错误,以便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分析,并且不会运行其他测试。

不太漂亮,但它能完成这项工作:)

答案 4 :(得分:2)

与您的答案相似,但在集成测试中使用@Before,我做了类似的事情:

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);
   }
}

问候!

答案 5 :(得分:1)

首先,您应该在运行第二次测试之前发现错误并检查相同内容。

@Rule
public ErrorCollector collector = new ErrorCollector();

<强> 1。添加错误。

collector.addError(new Throwable("first thing went wrong"));

<强> 2。在依赖运行之前检查。

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

参考 - ErrorCollector

答案 6 :(得分:0)

您是否正在使用ant运行测试?

您可以编写自定义测试侦听器。您可以在ant http://ant.apache.org/manual/Tasks/junit.html(enableTestListenerEvents)中设置它。