2012-04-05 74 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

相關問題