2012-04-05 76 views
14

我有一个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; 
} 
} 

这就要求香草测试是这样的:

public class xxx { 

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

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

这可能吗?

回答

6

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

+0

我将如何编程方式检查如果断言失败? – Jonathan 2012-04-05 23:23:40

+0

好吧,我看到我可以在第一次测试中捕获AssertionError,然后调用System.exit(),但是JUnit测试不会通过或失败,只是停止运行。似乎应该有一个更优雅的方式。 – Jonathan 2012-04-05 23:34:03

+5

回复:更优雅的方式,我不相信JUnit提供此功能的开箱即用。它可以导致测试之间的耦合。理想情况下,您的测试应该彼此独立运行,不会受到其他故障的影响。如果你坚持,那么Hiro2k的建议是最好的。 – 2012-04-06 00:12:17

0

你正在运行测试使用蚂蚁?

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

+0

尽管这是一个选项 - 我通常不使用Ant(在Eclipse中使用Run As> JUnit Test)。 – Jonathan 2012-04-06 13:14:54

+0

您将如何创建“自定义测试监听器”? 我得到了haltonfailure =“true”的ant部分,但是在Suite中,如果Suite的某个测试失败,它不会停止。什么“自定义测试监听器”能够做到? – 2017-02-10 09:10:28

3

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

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

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分析并且不会执行进一步的测试。

不算漂亮,但它的工作:)

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

商祺!

10

首先,你需要的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, 
    ... 
}) 
+0

要实现这个问题,'FailureListener'不应该在任何失败时停止测试。过滤失败类型可能会更好,只会停止对特定错误进行测试。例如,创建你自己的'Exception'类,并将它扔到你的'FirstTestClass'中。然后使用'failure.getException()'来确定是否停止测试。 – artificerpi 2017-08-07 08:04:04

1

首先,你应该捕获错误并检查在进行第二次测试之前相同。

@Rule 
public ErrorCollector collector = new ErrorCollector(); 

1.添加错误。

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

2.因运行前检查。

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

参考 - ErrorCollector

相关问题