Frage Before und After Suite Ausführung hook in jUnit 4.x


Ich versuche Setup und Teardown für eine Reihe von Integrationstests vorzubereiten, mit jUnit 4.4, um die Tests durchzuführen. Der Teardown muss zuverlässig laufen. Ich habe andere Probleme mit TestNG, also suche ich zurück zu jUnit. Welche Hooks stehen für die Ausführung zur Verfügung, bevor Tests ausgeführt werden und alle Tests abgeschlossen sind?

Hinweis: Wir verwenden Maven 2 für unseren Build. Ich habe versucht, Maven zu verwenden pre- & post-integration-test Phasen, aber wenn ein Test fehlschlägt, stoppt Maven und läuft nicht post-integration-testDas ist keine Hilfe.


76
2017-09-17 13:07


Ursprung


Antworten:


Ja, es ist möglich, vor und nach Tests in einer Testsuite zuverlässig Auf- und Abbaumethoden durchzuführen. Lassen Sie mich im Code demonstrieren:

package com.test;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class)
@SuiteClasses({Test1.class, Test2.class})
public class TestSuite {

    @BeforeClass
    public static void setUp() {
        System.out.println("setting up");
    }

    @AfterClass
    public static void tearDown() {
        System.out.println("tearing down");
    }

}

Ihre Test1-Klasse würde also etwa so aussehen:

package com.test;

import org.junit.Test;


public class Test1 {
    @Test
    public void test1() {
        System.out.println("test1");
    }

}

... und Sie können sich vorstellen, dass Test2 ähnlich aussieht. Wenn Sie TestSuite ausführen, erhalten Sie:

setting up
test1
test2
tearing down

Sie können also sehen, dass das Setup / Abriss nur vor bzw. nach allen Tests durchgeführt wird.

Der Haken: Das funktioniert nur, wenn Sie die Testsuite ausführen und Test1 und Test2 nicht als einzelne JUnit-Tests ausführen. Du hast erwähnt, dass du Maven benutzt, und das Maven Surefire-Plugin lässt Tests gerne einzeln und nicht in einer Suite laufen. In diesem Fall würde ich empfehlen, eine Superklasse zu erstellen, die jede Testklasse erweitert. Die Superklasse enthält dann die mit Annotationen versehenen Methoden @BeforeClass und @AfterClass. Obwohl nicht ganz so sauber wie die obige Methode, denke ich, dass es für Sie arbeiten wird.

Was das Problem mit fehlgeschlagenen Tests betrifft, können Sie maven.test.error.ignore so einstellen, dass der Build bei fehlgeschlagenen Tests fortgesetzt wird. Dies wird nicht als fortlaufende Übung empfohlen, aber es sollte Sie funktionieren, bis alle Ihre Tests bestanden haben. Weitere Informationen finden Sie unter Maven todsichere Dokumentation.


107
2017-10-07 02:51



Ein Kollege von mir schlug Folgendes vor: Sie können einen benutzerdefinierten RunListener verwenden und die Methode testRunFinished () implementieren: http://junit.sourceforge.net/javadoc/org/junit/runner/notification/RunListener.html#testRunFinished (org.junit.runner.Result)

Um den RunListener zu registrieren, konfigurieren Sie einfach das todsichere Plugin wie folgt: http://maven.apache.org/surefire/maven-surefire-plugin/examples/junit.html Abschnitt "Verwenden benutzerdefinierter Listener und Reporter"

Diese Konfiguration sollte auch vom Failsafe-Plugin ausgewählt werden. Diese Lösung ist großartig, weil Sie keine Suites, Lookup-Test-Klassen oder ähnliches angeben müssen - es lässt Maven seine Magie vollbringen und wartet darauf, dass alle Tests beendet werden.


31
2018-02-07 17:29



Du kannst den ... benutzen Annotation @ClassRule in JUnit 4.9+ wie Ich habe in einer Antwort eine andere Frage beschrieben.


11
2017-10-03 18:15



Mithilfe von Anmerkungen können Sie Folgendes tun:

import org.junit.*;
import static org.junit.Assert.*;
import java.util.*;

class SomethingUnitTest {
    @BeforeClass
    public static void runBeforeClass()
    {

    }

    @AfterClass
    public static void runAfterClass()
    {  

    }

    @Before  
    public void setUp()
    {

    }

    @After
    public void tearDown()
    {

    }

    @Test
    public void testSomethingOrOther()
    {

    }

}

8
2017-09-17 13:32



Hier, wir

  • Upgrade auf JUnit 4.5,
  • schrieb Anmerkungen, um jede Testklasse oder -methode zu markieren, die einen funktionierenden Dienst benötigten,
  • schrieb Handler für jede Annotation, die statische Methoden enthielten, um den Aufbau und den Abbau des Dienstes zu implementieren,
  • Der übliche Runner wurde erweitert, um die Anmerkungen zu Tests zu finden, und die statischen Handlermethoden an den entsprechenden Punkten in die Testausführungskette eingefügt.

3
2018-04-01 18:13



Vorausgesetzt, dass alle Ihre Tests eine "technische" Klasse erweitern und sich im selben Paket befinden, können Sie einen kleinen Trick machen:

public class AbstractTest {
  private static int nbTests = listClassesIn(<package>).size();
  private static int curTest = 0;

  @BeforeClass
  public static void incCurTest() { curTest++; }

  @AfterClass
  public static void closeTestSuite() {
      if (curTest == nbTests) { /*cleaning*/ }             
  }
}

public class Test1 extends AbstractTest {
   @Test
   public void check() {}
}
public class Test2 extends AbstractTest {
   @Test
   public void check() {}
}

Beachten Sie, dass diese Lösung viele Nachteile hat:

  • muss alle Tests des Pakets ausführen
  • muss eine Klasse "techincal" ableiten
  • Sie können @BeforeClass und @AfterClass nicht innerhalb von Unterklassen verwenden
  • Wenn Sie nur einen Test im Paket ausführen, wird die Reinigung nicht durchgeführt
  • ...

Zur Information: listClassesIn () => Wie finden Sie alle Unterklassen einer bestimmten Klasse in Java?


3
2017-09-27 15:51



Zum Beispiel: "Wir verwenden Maven 2 für unseren Build. Ich habe versucht, mavens Pre- und Post-Integrationstest-Phasen zu verwenden, aber wenn ein Test fehlschlägt, stoppt Maven und führt keinen Post-Integration-Test durch das ist keine Hilfe. "

Sie können das Failsafe-Plugin stattdessen versuchen, ich denke, es hat die Möglichkeit, sicherzustellen, dass Bereinigung unabhängig von Setup oder Zwischenstatus auftritt


2
2017-12-07 14:54