2012-04-05 15 views
14

Mam zestaw testów JUnit w postaci:Zatrzymanie JUnit pakiet szczególności jeśli test nie powiedzie

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

To wywołuje wanilii testy takie jak ten:

public class xxx { 

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

Mam sytuacji gdzie ja jak zatrzymać resztę zestawu testów, jeśli wystąpił błąd lub niepowodzenie w pierwszym teście. Ale błędy/niepowodzenia w innych są w porządku, a pakiet powinien wykonać jak najwięcej innych testów. Zasadniczo pierwsze niepowodzenie testu wskazuje, że nie jest bezpiecznie uruchomić resztę.

Czy to możliwe?

Odpowiedz

6

Co jest nie tak z dzwonieniem pod numer System.exit()?

+0

Jak programowo sprawdzić, czy twierdzenie nie powiodło? – Jonathan

+0

OK, widzę, że mogłem złapać AssertionError w pierwszym teście, a następnie wywołać System.exit(), ale wtedy test JUnit nie przejdzie lub nie powiedzie się, po prostu przestań działać. Wygląda na to, że powinien być bardziej elegancki sposób. – Jonathan

+5

Re: Bardziej elegancki sposób, nie wierzę, że JUnit zapewnia tę funkcjonalność po wyjęciu z pudełka. Może prowadzić do sprzężenia między testami. W idealnej sytuacji testy powinny przebiegać niezależnie od siebie i nie mogą być zakłócane przez inne awarie. Jeśli nalegasz, sugestia Hiro2k jest najlepsza. –

0

Czy przeprowadzasz testy za pomocą mrówki?

Możesz napisać niestandardowy testowiec. Możesz ustawić to w ant http://ant.apache.org/manual/Tasks/junit.html (enableTestListenerEvents).

+0

Chociaż jest to opcja - generalnie nie używam Ant (używając polecenia Uruchom jako> Test JUnit w środowisku Eclipse). – Jonathan

+0

Jak utworzyć "niestandardowy słuchacz testowy"? Dostaję część mrówki z haltonfailure = "true", ale w pakiecie nie zatrzymuje się, jeśli jeden z testów w pakiecie nie powiedzie się. Co może zrobić "niestandardowy słuchacz testowy"? –

3

Jeśli to jest test najpierw, rozważ przemieszczenie jego walidacji do @BeforeClass i wyrzuć wyjątek, jeśli się nie powiedzie. Wówczas tylko metoda @AfterClass byłaby uruchomiona w przypadku tego wyjątku.

Oczywiście w ten sposób brakuje wszystkich artefaktów urządzeń utworzonych w metodach konfiguracji testów.

3

Na podstawie odpowiedzi z Hiro2k (dzięki!) Skorzystałem z następującego rozwiązania. To trochę hack, ale działa.

Test, który może uniemożliwić wykonywanie innych testów, znajduje się na górze listy @ Suite.SuiteClasses. Że badanie ma wówczas następujący:

private static boolean shouldStopRestOfSuite = false; 

    @Test 
    public void test() throws Throwable { 
    try { 
      ... run some test code... 
    } 
    catch (Throwable e) { 
     shouldStopRestOfSuite = true; 
     throw e; 
    } 
} 

Uwaga powyższa nie trzeba złapać Throwable (nie wyjątek), więc łapie błędy twierdzenie. Ponownie generuje błąd, więc jest on rejestrowany przez JUnit do analizy.

Potem jest inna metoda badania:

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

    System.out.println ("Test suite killed due to dangerous error/failure"); 
    System.exit(1); 
} 

Powyższy prowadzony jest drugi i zabije proces JUnit.

Przy użyciu tej metody test JUnit nie zakończy się niepowodzeniem/błędem, jeśli wystąpi problem, ale błąd/błąd zostanie zarejestrowany do analizy przez JUnit i nie będą przeprowadzane żadne dalsze testy.

Nie jest zbyt ładne, ale spełnia swoje zadanie :)

2

jak odpowiedź, ale stosując @Before w teście integracyjnym, zrobiłem coś takiego:

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

Pozdrawiam!

10

Najpierw trzeba 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(); 
    } 
} 

Następnie przygotować Suite:

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

i uruchomić pakiet:

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

Aby zaimplementować to, o co pyta, 'FailureListener' nie powinien przestać testować na żadnej awarii. Lepszym rozwiązaniem może być filtrowanie typu awarii i zatrzymywanie testów tylko w przypadku określonego błędu. na przykład, tworzymy własną klasę 'Exception' i wyrzucamy ją do' FirstTestClass'. Następnie użyj 'failure.getException()', aby określić, czy zatrzymać test. – artificerpi

1

Po pierwsze należy złapać błąd i sprawdź tak samo, zanim wykonasz drugi test.

@Rule 
public ErrorCollector collector = new ErrorCollector(); 

1. Dodać błąd.

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

2. Sprawdź przed biegiem zależnej.

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

Reference - ErrorCollector

Powiązane problemy