The Order of Tests in JUnit – JUnit中测试的顺序

最后修改: 2017年 11月 26日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

By default, JUnit runs tests using a deterministic but unpredictable order (MethodSorters.DEFAULT).

默认情况下,JUnit使用一个确定但不可预测的顺序运行测试MethodSorters.DEFAULT)。

In most cases, that behavior is perfectly fine and acceptable. But there are cases when we need to enforce a specific ordering.

在大多数情况下,这种行为是完全可以接受的。但在有些情况下,我们需要强制执行一个特定的命令。

2. Test Order in JUnit 5

2.JUnit 5中的测试顺序

In JUnit 5, we can use @TestMethodOrder to control the execution order of tests.

在JUnit 5中,我们可以使用@TestMethodOrder来控制测试的执行顺序。

We can use our own MethodOrderer, as we’ll see later.

我们可以使用我们自己的MethodOrderer,后面我们会看到。

Or we can select one of three built-in orderers:

或者我们可以从三个内置的订购者中选择一个。

  1. Alphanumeric Order
  2. @Order Annotation
  3. Random Order

2.1. Using Alphanumeric Order

2.1.使用字母数字顺序

JUnit 5 comes with a set of built-in MethodOrderer implementations to run tests in alphanumeric order.

JUnit 5带有一套内置的MethodOrderer实现,以字母数字顺序运行测试。

For example, it provides MethodOrderer.MethodName to sort test methods based on their names and their formal parameter lists:

例如,它提供了MethodOrderer.MethodName根据测试方法的名称和它们的正式参数列表来排序

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

Similarly, we can use MethodOrderer.DisplayName to sort methods alphanumerically based on their display names.

同样,我们可以使用MethodOrderer.DisplayName根据方法的显示名称按字母数字排序。

Please keep in mind that MethodOrderer.Alphanumeric is another alternative. However, this implementation is deprecated and will be removed in 6.0.

请记住,MethodOrderer.Alphanumeric是另一种选择。然而,这个实现已被废弃,并将在6.0中被删除。

2.2. Using the @Order Annotation

2.2.使用@Order注释

We can use the @Order annotation to enforce tests to run in a specific order.

我们可以使用@Order注解来强制测试以特定顺序运行。

In the following example, the methods will run firstTest(), then secondTest() and finally thirdTest():

在下面的例子中,这些方法将运行firstTest(),然后secondTest(),最后thirdTest()

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

2.3. Using Random Order

2.3.使用随机命令

We can also order test methods pseudo-randomly using the MethodOrderer.Random implementation:

我们还可以使用MethodOrderer.Random实现来伪随机地排列测试方法。

@TestMethodOrder(MethodOrderer.Random.class)
public class RandomOrderUnitTest {

    private static StringBuilder output = new StringBuilder("");

    @Test
    void myATest() {
        output.append("A");
    }

    @Test
    void myBTest() {
        output.append("B");
    }

    @Test
    void myCTest() {
        output.append("C");
    }

    @AfterAll
    public static void assertOutput() {
        assertEquals("ACB", output.toString());
    }

}

As a matter of fact, JUnit 5 uses System.nanoTime() as the default seed to sort the test methods. This means that the execution order of the methods may not be the same in repeatable tests.

事实上,JUnit 5使用System.nanoTime()作为默认种子对测试方法进行排序。这意味着在可重复测试中,方法的执行顺序可能不一样。

However, we can configure a custom seed using the junit.jupiter.execution.order.random.seed property to create repeatable builds.

然而,我们可以使用junit.jupiter.execution.order.random.seed属性配置一个自定义种子,以创建可重复的构建。

We can specify the value of our custom seed in the junit-platform.properties file:

我们可以在junit-platform.properties文件中指定我们自定义种子的值。

junit.jupiter.execution.order.random.seed=100

2.4. Using a Custom Order

2.4.使用自定义订单

Finally, we can use our own custom order by implementing the MethodOrderer interface.

最后,我们可以通过实现MethodOrderer接口来使用我们自己的自定义命令。

In our CustomOrder, we’ll order the tests based on their names in a case-insensitive alphanumeric order:

在我们的CustomOrder中,我们将根据他们的名字以不区分大小写的字母数字顺序排列测试。

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()));
    }
}

Then we’ll use CustomOrder to run the same tests from our previous example in the order myATest(), myaTest() and finally myBTest():

然后我们将使用CustomOrder 来运行我们之前的例子中相同的测试,顺序是myATest()myaTest()和最后myBTest()

@TestMethodOrder(CustomOrder.class)
public class CustomOrderUnitTest {

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

2.5. Set Default Order

2.5.设置默认顺序

JUnit 5 provides a convenient way to set a default method orderer through the junit.jupiter.testmethod.order.default parameter.

JUnit 5提供了一种方便的方法,通过junit.jupiter.testmethod.order.default 参数来设置一个默认的方法命令器。

Similarly, we can configure our parameter in the junit-platform.properties file:

同样地,我们可以在junit-platform.properties文件中配置我们的参数。

junit.jupiter.testmethod.order.default = org.junit.jupiter.api.MethodOrderer$DisplayName

The default orderer will be applied to all tests that aren’t qualified with @TestMethodOrder.

默认排序器将被应用于所有未使用@TestMethodOrder的测试。

Another important thing to mention is that the specified class must implement the MethodOrderer interface.

另一件要提到的重要事情是,指定的类必须实现MethodOrderer接口。

3. Test Order in JUnit 4

JUnit 4中的测试顺序

For those still using JUnit 4, the APIs for ordering tests are slightly different.

对于那些仍然使用JUnit 4的人来说,订购测试的API略有不同。

Let’s go through the options to achieve this in previous versions as well.

让我们来看看在以前的版本中也有哪些选项可以实现这一点。

3.1. Using MethodSorters.DEFAULT

3.1.使用MethodSorters.DEFAULT

This default strategy compares test methods using their hash codes.

这个默认的策略是使用它们的哈希代码来比较测试方法。

In case of a hash collision, the lexicographical order is used:

在发生哈希碰撞的情况下,会使用按字母顺序排列。

@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");
    }
}

When we run the tests in the class above, we will see that they all pass, including assertOutput().

当我们运行上述类中的测试时,我们会看到它们都通过了,包括assertOutput()

3.2. Using MethodSorters.JVM

3.2.使用MethodSorters.JVM

Another ordering strategy is MethodSorters.JVM.

另一个排序策略是MethodSorters.JVM

This strategy utilizes the natural JVM ordering, which can be different for each run:

这种策略利用了JVM的自然排序,每次运行都可能不同

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

Each time we run the tests in this class, we get a different result.

每次我们运行这个类的测试时,都会得到不同的结果。

3.3. Using MethodSorters.NAME_ASCENDING

3.3.使用MethodSorters.NAME_ASCENDING

Finally, this strategy can be used for running tests in their lexicographic order:

最后,这一策略可用于按词典顺序运行测试。

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

When we run the tests in this class, we see that they all pass, including assertOutput(). This confirms the execution order that we set with the annotation.

当我们运行这个类中的测试时,我们看到它们都通过了,包括assertOutput()。这证实了我们用注解设置的执行顺序。

4. Conclusion

4.结论

In this quick article, we went through the ways of setting the execution order available in JUnit.

在这篇快速文章中,我们浏览了JUnit中可用的设置执行顺序的方法。

As always, the examples used in this article can be found over on GitHub.

一如既往,本文中所使用的例子可以在GitHub上找到over