Die Reihenfolge der Tests in JUnit

Die Reihenfolge der Tests in JUnit

1. Überblick

StandardmäßigJUnit runs tests using a deterministic, but unpredictable order (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 Einheit 5 sindwe can use @TestMethodOrder to control the execution order of tests.

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

  1. @Order Anmerkung

  2. Alphanumeric Bestellung

  3. Zufällige Reihenfolge

2.1. Verwenden der Annotation@Order

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

Im folgenden Beispiel werden die Methoden in dieser Reihenfolge ausgeführt -firstTest(), dannsecondTest() und schließlichthirdTest():

@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 vonAlphanumeric Order

Wir können auch Tests basierend auf ihren Namen in alphanumerischer Reihenfolge durchfü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.

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

2.3. Verwenden einer benutzerdefinierten Bestellung

Schließlichwe can use our own custom order by implementing theMethodOrdererinterface.

In unserenCustomOrder ordnen wir die Tests basierend auf ihren 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 wirCustomOrder, um dieselben Tests wie in unserem vorherigen Beispiel in dieser Reihenfolge auszuführen -myATest(),myaTest() und schließlichmyBTest():

@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 vonMethodSorters.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ßlichassertOutput().

3.2. Verwenden vonMethodSorters.JVM

Eine andere Bestellstrategie istMethodSorters.JVM -this strategy utilizes the natural JVM ordering – which can be different for each run:

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

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

3.3. Verwenden vonMethodSorters.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ßlichassertOutput(), was die Ausführungsreihenfolge bestätigt, die wir mit der Annotation festgelegt haben.

4. Fazit

In diesem kurzen Lernprogramm haben wir die Möglichkeiten zum Festlegen der in JUnit verfügbaren Ausführungsreihenfolge erläutert.

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