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?
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).
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
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.
Testen Sie JUnit-Testgruppen . Aus der Dokumentation:
@TestGroup("integration")
public class MyIntegrationTest {
@ClassRule
public static TestGroupRule rule = new TestGroupRule();
...
}
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.
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.
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.