23

我有一个 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 {
    ...

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

这可能吗?

4

7 回答 7

20

首先你需要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,
    ...
})
于 2015-07-14T03:59:29.240 回答
9

打电话有什么问题System.exit()

于 2012-04-05T23:04:12.737 回答
5

如果是第一次测试,则考虑将其验证移至 @BeforeClass 并在失败时抛出异常。然后只有 @AfterClass 方法会在这个异常的情况下运行。

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

于 2012-04-06T03:55:15.890 回答
4

就像您的答案一样,但@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);
   }
}

问候!

于 2015-01-05T13:01:33.977 回答
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 分析,并且不会运行进一步的测试。

不太漂亮,但它可以完成工作:)

于 2012-04-06T14:21:33.400 回答
2

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

@Rule
public ErrorCollector collector = new ErrorCollector();

1.添加错误。

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

2. 依赖运行前检查

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

参考 - ErrorCollector

于 2017-11-15T05:11:38.330 回答
0

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

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

于 2012-04-06T03:41:27.800 回答