Die Reihenfolge der Tests in JUnit

1. Übersicht

Standardmäßig führt JUnit Tests in einer deterministischen, aber unvorhersehbaren Reihenfolge aus ( MethodSorters.DEFAULT ).

In den meisten Fällen ist dieses Verhalten vollkommen in Ordnung und akzeptabel. Es gibt jedoch Fälle, in denen wir eine bestimmte Bestellung durchsetzen müssen.

2. Testauftrag in JUnit 5

In JUnit 5 können wir @TestMethodOrder verwenden , um die Ausführungsreihenfolge von Tests zu steuern .

Wir können unseren eigenen MethodOrderer verwenden , wie wir später sehen werden, oder wir können einen von drei integrierten Ordnern auswählen:

  1. @Order Annotation
  2. Alphanumerische Reihenfolge
  3. Zufällige Reihenfolge

2.1. Verwenden der @ Order Annotation

Wir können die Annotation @Order verwenden , um Tests zu erzwingen, die in einer bestimmten Reihenfolge ausgeführt werden.

Im folgenden Beispiel werden die Methoden in dieser Reihenfolge ausgeführt: firstTest () , secondTest () und schließlich threeTest () :

@TestMethodOrder(OrderAnnotation.class) public class OrderAnnotationUnitTest { private static StringBuilder output = new StringBuilder(""); @Test @Order(1) public void firstTest() { output.append("a"); } @Test @Order(2) public void secondTest() { output.append("b"); } @Test @Order(3) public void thirdTest() { output.append("c"); } @AfterAll public static void assertOutput() { assertEquals(output.toString(), "abc"); } }

2.2. Verwenden der alphanumerischen Reihenfolge

Wir können auch Tests basierend auf ihren Namen in alphanumerischer Reihenfolge ausführen:

@TestMethodOrder(Alphanumeric.class) public class AlphanumericOrderUnitTest { private static StringBuilder output = new StringBuilder(""); @Test public void myATest() { output.append("A"); } @Test public void myBTest() { output.append("B"); } @Test public void myaTest() { output.append("a"); } @AfterAll public static void assertOutput() { assertEquals(output.toString(), "ABa"); } }

Beachten Sie, dass bei der alphanumerischen Reihenfolge zwischen Groß- und Kleinschreibung unterschieden wird, sodass zuerst Groß- und Kleinbuchstaben stehen.

Die Tests werden in dieser Reihenfolge ausgeführt: myATest () , myBTest () und schließlich myaTest () .

2.3. Verwenden einer benutzerdefinierten Bestellung

Schließlich können wir unsere eigene benutzerdefinierte Reihenfolge verwenden, indem wir die MethodOrderer- Schnittstelle implementieren .

In unserem CustomOrder ordnen wir die Tests anhand ihrer Namen in einer alphanumerischen Reihenfolge ohne Berücksichtigung der Groß- und Kleinschreibung an:

public class CustomOrder implements MethodOrderer { @Override public void orderMethods(MethodOrdererContext context) { context.getMethodDescriptors().sort( (MethodDescriptor m1, MethodDescriptor m2)-> m1.getMethod().getName().compareToIgnoreCase(m2.getMethod().getName())); } }

Dann verwenden wir CustomOrder , um dieselben Tests wie in unserem vorherigen Beispiel in dieser Reihenfolge auszuführen - myATest () , myaTest () und schließlich myBTest () :

@TestMethodOrder(CustomOrder.class) public class CustomOrderUnitTest { // ... @AfterAll public static void assertOutput() { assertEquals(output.toString(), "AaB"); } }

3. Testauftrag in JUnit 4

Wenn Sie noch JUnit 4 verwenden, unterscheiden sich die APIs zum Bestellen von Tests geringfügig.

Lassen Sie uns die Optionen durchgehen, um dies auch in früheren Versionen zu erreichen.

3.1. Verwenden von MethodSorters.DEFAULT

Diese Standardstrategie vergleicht Testmethoden anhand ihrer Hashcodes. Im Falle einer Hash-Kollision wird die lexikografische Reihenfolge verwendet:

@FixMethodOrder(MethodSorters.DEFAULT) public class DefaultOrderOfExecutionTest { private static StringBuilder output = new StringBuilder(""); @Test public void secondTest() { output.append("b"); } @Test public void thirdTest() { output.append("c"); } @Test public void firstTest() { output.append("a"); } @AfterClass public static void assertOutput() { assertEquals(output.toString(), "cab"); } }

Wenn wir die Tests in der obigen Klasse ausführen, werden wir sehen, dass sie alle bestanden haben, einschließlich assertOutput () .

3.2. Verwenden von MethodSorters.JVM

Eine andere Bestellstrategie ist MethodSorters.JVM - diese Strategie verwendet die natürliche JVM-Reihenfolge - die für jeden Lauf unterschiedlich sein kann:

@FixMethodOrder(MethodSorters.JVM) public class JVMOrderOfExecutionTest { // same as above }

Jedes Mal, wenn wir die Tests in dieser Klasse ausführen, erhalten wir ein anderes Ergebnis.

3.3. Verwenden von MethodSorters.NAME_ASCENDING

Schließlich kann diese Strategie zum Ausführen von Tests in ihrer lexikografischen Reihenfolge verwendet werden:

@FixMethodOrder(MethodSorters.NAME_ASCENDING) public class NameAscendingOrderOfExecutionTest { // same as above @AfterClass public static void assertOutput() { assertEquals(output.toString(), "abc"); } }

Wenn wir die Tests in dieser Klasse ausführen, sehen wir ebenfalls, dass sie alle bestanden werden, einschließlich assertOutput () , was die Ausführungsreihenfolge bestätigt, die wir mit der Annotation festgelegt haben.

4. Fazit

In diesem kurzen Tutorial haben wir die Möglichkeiten zum Festlegen der in JUnit verfügbaren Ausführungsreihenfolge beschrieben.

Und wie immer finden Sie die in diesem Artikel verwendeten Beispiele auf GitHub.