webentwicklung-frage-antwort-db.com.de

Gruppieren von JUnit-Tests

Gibt es eine Möglichkeit, Tests in JUnit zu gruppieren, sodass ich nur einige Gruppen ausführen kann?

Oder ist es möglich, einige Tests mit Anmerkungen zu versehen und sie dann global zu deaktivieren?

Ich benutze JUnit 4 , ich kann TestNG nicht verwenden.

edit: @RunWith und @SuiteClasses funktionieren hervorragend. Aber ist es möglich, nur einige Tests in der Testklasse auf diese Weise zu kommentieren? Oder muss ich die gesamte Testklasse kommentieren?

39
Jakub Arnold

Möchten Sie Tests innerhalb einer Testklasse gruppieren oder Testgruppen gruppieren? Ich werde das letztere annehmen.

Es hängt davon ab, wie Sie Ihre Tests ausführen. Wenn Sie sie von Maven ausführen, können Sie genau angeben, welche Tests Sie einschließen möchten. Siehe die Maven todsichere Dokumentation .

Im Allgemeinen ist es jedoch so, dass ich einen Baum von Testsuiten habe. Eine Testsuite in JUnit 4 sieht ungefähr so ​​aus:

 @RunWith(Suite.class)
 @SuiteClasses(SomeUnitTest1.class, SomeUnitTest2.class)
 public class UnitTestsSuite {
 }

Vielleicht habe ich also eine FunctionTestsSuite und eine UnitTestsSuite und dann eine AllTestsSuite, die die beiden anderen enthält. Wenn Sie sie in Eclipse ausführen, erhalten Sie eine sehr schöne hierarchische Ansicht.

Das Problem bei diesem Ansatz ist, dass es ziemlich umständlich ist, wenn Sie Tests auf mehrere verschiedene Arten schneiden möchten. Es ist jedoch immer noch möglich (Sie können zum Beispiel einen Satz von Suites haben, der auf Modul basiert, und dann ein weiteres Slicing nach Testtyp).

8
waxwing

JUnit 4.8 unterstützt die Gruppierung:

public interface SlowTests {}
public interface IntegrationTests extends SlowTests {}
public interface PerformanceTests extends SlowTests {}

Und dann...

public class AccountTest {

    @Test
    @Category(IntegrationTests.class)
    public void thisTestWillTakeSomeTime() {
        ...
    }

    @Test
    @Category(IntegrationTests.class)
    public void thisTestWillTakeEvenLonger() {
        ...
    }

    @Test
    public void thisOneIsRealFast() {
        ...
    }
}

Und zuletzt,

@RunWith(Categories.class)
@ExcludeCategory(SlowTests.class)
@SuiteClasses( { AccountTest.class, ClientTest.class })
public class UnitTestSuite {}

Genommen von hier: http://weblogs.Java.net/blog/johnsmart/archive/2010/04/25/grouping-tests-using-junit-categories-0

Arquillian unterstützt auch die Gruppierung: https://github.com/weld/core/blob/master/tests-arquillian/src/test/Java/org/jboss/weld/tests/Categories.Java

73
Ondra Žižka

JUnit (4.5+) hat zwei Möglichkeiten, um die globale Deaktivierung zu verhindern. Die neue Methode setzt die Annahme voraus, dassThat. Wenn Sie dies in die @BeforeClass (oder die @Before) einer Testklasse eingeben und die Bedingung fehlschlägt, wird der Test ignoriert. In diesem Zustand können Sie eine Systemeigenschaft oder etwas anderes setzen, das global ein- oder ausgeschaltet werden kann.

Die andere Alternative besteht darin, einen benutzerdefinierten Läufer zu erstellen, der die globale Eigenschaft versteht und an den entsprechenden Läufer delegiert. Dieser Ansatz ist viel spröder (da die internen JUnit4-Läufer instabil sind und von Release zu Release geändert werden können), sie hat jedoch den Vorteil, dass sie in einer Klassenhierarchie vererbt und in einer Unterklasse überschrieben werden kann. Dies ist auch der einzig realistische Weg, wenn Sie ältere JUnit38-Klassen unterstützen müssen.

Hier ist etwas Code für den benutzerdefinierten Runner. Was getAppropriateRunnerForClass betrifft, bestand die Art und Weise, wie ich es implementierte, mit einer separaten Anmerkung, die dem benutzerdefinierten Läufer mitteilt, was mit ihm ausgeführt werden soll. Die einzige Alternative war etwas sprödes Copy-Paste aus dem JUnit-Code.

private class CustomRunner implements Runner
 private Runner runner;

    public CustomRunner(Class<?> klass, RunnerBuilder builder) throws Throwable {
        if (!isRunCustomTests()) {
            runner = new IgnoredClassRunner(klass);
        } else {
            runner = getAppropriateRunnerForClass(klass, builder);
    }

    public Description getDescription() {
        return runner.getDescription();
    }

    public void run(RunNotifier notifier) {
        runner.run(notifier);
    }
}

BEARBEITEN: Das Tag @RunWith funktioniert nur für eine ganze Klasse. Um diese Begrenzung zu umgehen, können Sie die Testmethoden in eine statische innere Klasse verschieben und diese kommentieren. Auf diese Weise haben Sie den Vorteil der Anmerkung mit der Organisation der Klasse. Das hilft jedoch nicht bei @Before- oder @BeforeClass-Tags. Sie müssen diese in der inneren Klasse neu erstellen. Es kann die Methode der äußeren Klasse aufrufen, müsste jedoch eine eigene Methode als Hook verwenden.

9
Yishai

Testen Sie JUnit-Testgruppen . Aus der Dokumentation:

@TestGroup("integration")
public class MyIntegrationTest {
   @ClassRule
   public static TestGroupRule rule = new TestGroupRule();

   ...
}
  • Führen Sie eine einfache Testgruppe aus: -Dtestgroup = Integration
  • Führen Sie mehrere Testgruppen aus: -Dtestgroup = group1, group2
  • Führen Sie alle Testgruppen aus: -Dtestgroup = all
3
Bit-Man

Sie können test Suite Objekte erstellen, die Testgruppen enthalten. Alternativ kann Ihre IDE (wie Eclipse) die Ausführung aller in einem bestimmten Paket enthaltenen Tests unterstützen.

1
Kevin

In JUnit 5 können Sie @Tag für Filtertests entweder auf Klassen- oder Methodenebene angeben. analog zu Testgruppen in TestNG oder Kategorien in JUnit 4

Aus dem javadoc

tags werden verwendet, um zu filtern, welche Tests für einen bestimmten Test ausgeführt werden planen. Beispielsweise kann ein Entwicklungsteam Tests mit Werten wie .__ kennzeichnen. als "fast", "slow", "ci-server" usw. und liefern dann eine Liste der Tags an für den aktuellen Testplan verwendet werden, möglicherweise abhängig von der aktuelle Umgebung.

Sie können beispielsweise eine Testklasse mit einem "slow"@Tag deklarieren, der für alle Methoden geerbt wird, und diese ggf. für einige Methoden überschreiben:

import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

@Tag("slow") 
public class FooTest{

   // 
   @Test
   void loadManyThings(){ 
        ...
   }

   @Test
   void loadManyManyThings(){ 
        ...
   }


   @Test
   @Tag("fast")
   void loadFewThings(){ 
        ...
   }

}

Sie können dieselbe Logik für andere Testklassen anwenden.
Auf diese Weise gehören Testklassen (und auch Methoden) zu einem bestimmten Tag. 

Als bewährtes Verfahren, anstatt @Tag("fast") und @Tag("slow") in den Testklassen zu kopieren und einzufügen, können Sie benutzerdefinierte Anmerkungen erstellen.
Zum Beispiel : 

import Java.lang.annotation.ElementType;
import Java.lang.annotation.Retention;
import Java.lang.annotation.RetentionPolicy;
import Java.lang.annotation.Target;

import org.junit.jupiter.api.Tag;

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Tag("slow")
public @interface Fast {
}

und benutze es als:

@Test
@Slow
void slowProcessing(){ 
    ...
}   

Um den mit einem bestimmten Tag markierten Test während der Textausführung zu aktivieren oder zu deaktivieren, können Sie sich auf die Dokumentation maven-surefire-plugin verlassen:

Verwenden Sie groups, um Tags oder Tag-Ausdrücke einzuschließen.

Um Tags oder Tag-Ausdrücke auszuschließen, verwenden Sie entweder excludedGroups.

Konfigurieren Sie einfach das Plugin in Ihrer pom.xml entsprechend Ihren Anforderungen (Beispiel des Dokuments):

 <build>
     <plugins>
         ...
         <plugin>
             <groupId>org.Apache.maven.plugins</groupId>
             <artifactId>maven-surefire-plugin</artifactId>
             <version>2.22.0</version>
             <configuration>
                 <groups>acceptance | !feature-a</groups>
                 <excludedGroups>integration, regression</excludedGroups>
             </configuration>
         </plugin>
     </plugins> 
</build> 

Zur Information wird die Testziel-Dokumentation nicht aktualisiert. 

1
davidxxx

Sie können Test Suite ( http://qaautomated.blogspot.in/2016/09/junit-test-suits-and-test-execution.html ) oder Junit-Kategorien verwenden ( http: // qaautomated.blogspot.in/2016/09/junit-categories.html ) zum effektiven Gruppieren Ihrer Testfälle.

0
anuja jain