Skip to content

Junit5执行顺序

JUnit5 执行顺序

指定顺序使用场景

在测试过程中,我们遇到以下情况,则需要指定测试用例执行的顺序。

  • 测试方法之间存在依赖关系,需要按照特定的顺序执行以确保正确的执行。
  • 初始化和清理操作:测试方法需要在特定的顺序下进行初始化和清理操作。
  • 并发测试:在进行并发测试时,可能需要控制测试方法的执行顺序,以避免并发执行导致的竞态条件或冲突。
  • 测试报告和结果分析:有些时候,按照特定的顺序执行测试方法可以让测试报告更加清晰和易于分析。

排序方式

  • 方法排序
  • 类排序
  • Suite
  • 官方网站没有明确说明默认排序的具体规则

方法排序的类型

类型 说明
OrderAnnotation(重点) @Order 注解指定排序
DisplayName 根据显示名称排序
Random 随机排序
MethodName 根据方法名称排序

方法排序-Order 注解指定排序
  • 使用格式
//测试类前添加
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
//测试方法前添加
@Order()

指定排序方式为通过 Order 注解排序

  • 代码示例
package junit5.order;

import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
//设定排序方法为注解指定排序
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
//使用Order注解将顺序执行改为逆序执行
class OrderedTestsDemo {

    @Test
    @Order(3)
    void HogwartsOne() {
        System.out.println("第一条测试用例");
    }
    @Test
    @Order(2)
    void HogwartsTwo() {
        System.out.println("第二条测试用例");
    }

    @Test
    @Order(1)
    void HogwartsThree() {
        System.out.println("第三条测试用例");
    }
}
  • 可以看到使用 Order 注解将执行顺序改变为倒叙执行
    • 不添加 Order 注解时 执行方法为顺序执行
    • 添加 Order 注解后

方法排序-通过 DisplayName 排序

使用 DisplayName 注解可以在定义显示名称的同时定义执行顺序。

  • 使用格式
//测试类前添加
@TestMethodOrder(MethodOrderer.DisplayName.class)
//测试方法前添加
@DisplayName("a用例")
  • 代码示例
package junit5.order;

import org.junit.jupiter.api.*;

//设定排序方法为注解指定排序
@TestMethodOrder(MethodOrderer.DisplayName.class)
class OrderExampleTest {

    @Test
    @DisplayName("c用例")
    void firstCase() {
        System.out.println("第一条用例");
    }
    @Test
    @DisplayName("b用例")
    void secondCase() {
        System.out.println("第二条用例");
    }
    @Test
    @DisplayName("a用例")
    void thirdCase() {
        System.out.println("第三条用例");
    }
}
  • 未指定执行顺序时
  • 使用 DisplayName 指定顺序后 执行顺序将按照DisplayName中的 ASCII 码进行排序。

方法排序-随机排序
  • 使用格式
//只需要在测试类前添加
@TestMethodOrder(MethodOrderer.Random.class)
  • 代码示例
package com.hogwarts.JUnit5;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
//设计排序类型为随机排序
@TestMethodOrder(MethodOrderer.Random.class)
class orderExampleTest {
    @Test
    void firstCase() {
        System.out.println("第一条用例");
    }
    @Test
    void secondCase() {
        System.out.println("第二条用例");
    }
    @Test
    void thirdCase() {
        System.out.println("第三条用例");
        }
}
  • 未指定执行顺序时
  • 使用随机顺序 只需在测试类前添加TestMethodOrder注解 执行顺序将按照随机生成的顺序执行。

方法排序-MethodName 排序

根据方法名称的 ASCII 码进行排序,可以按照以下格式对测试方法命名:

HogwartsA  HogwartsB  HogwartsC
AHogwarts  BHogwarts  CHogwarts
请注意,如果测试方法名称以数字开头,则会按照数字的顺序进行排序。
  • 代码示例
package junit5.order;

import org.junit.jupiter.api.*;

//设定排序方法为注解指定排序
@TestMethodOrder(MethodOrderer.MethodName.class)
class OrderExampleTest {
    @Test
    void bCase() {
        System.out.println("第二条用例");
    }
    @Test
    void aCase() {
        System.out.println("第一条用例");
    }
    @Test
    void cCase() {
        System.out.println("第三条用例");
    }
}
  • 使用方法名指定执行顺序 需要注意方法的命名格式 方法的执行顺序会按照方法名 ASCII 码的顺序执行

类排序的类型

类排序与方法排序的类型基本一致,只是在使用上有些许差别,注意,在根据方法名进行排序时我们使用的类型是 MethodName ,在根据类名排序时使用的是 ClassName。 | 类型 | 说明 | | --------------- | ------------------------------------------------------ | | OrderAnnotation(重点) | @Order 注解指定排序 | | DisplayName | 根据显示名称排序 | | Random | 随机排序 | | ClassName | 根据类名排序 |


类排序-DisplayName 名称排序

使用 DisplayName 名称排序需要结合@DisplayName 可以在定义显示名称的同时定义执行顺序。多类执行需要结合@Nested 注解。

  • 使用格式
//测试类前添加 注意与方法排序时的区别
@TestClassOrder(ClassOrderer.DisplayName.class)
//子测试类前添加
@Nested
@DisplayName("a测试类")
  • 代码示例
package com.hogwarts.JUnit5;
import org.junit.jupiter.api.*;
// 指定类执行顺序的方式,DisplayName表示通过DisplayName排序
@TestClassOrder(ClassOrderer.DisplayName.class)
class orderExampleTest {
// 因为是多类执行,所以需要结合@Nested注解
    @Nested
    @DisplayName("b")
    class PrimaryTests {
        @Test
        void test1() {
            System.out.println("第一条用例");
        }
    }
    @Nested
    @DisplayName("a")
    class SecondaryTests {
        @Test
        void test2() {
            System.out.println("第二条用例");
        }
    }
}
  • 未指定测试类的执行顺序时
  • 使用 DisplayName 名称指定执行顺序时,类的显示名称修改为 DisplayName 中的内容,同时执行顺序也会按照显示名称的 ASCII 码执行。

类排序-Order 注解指定排序

使用Order 注解指定排序的方式与方法排序中使用Order的方法类似,需要结合@Order 注解使用。同样的多类执行需要结合@Nested 注解。

package junit5.order;

import org.junit.jupiter.api.*;

// 指定类执行顺序的方式,DisplayName表示通过DisplayName排序
//@TestClassOrder(ClassOrderer.DisplayName.class)

//使用`Order` 注解指定排序的方式与方法排序中使用`Order`的方法类似,需要结合@Order注解使用。
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
class OrderExampleTest {
    // 因为是多类执行,所以需要结合@Nested注解
    @Nested
    @Order(1)
    class PrimaryTests {
        @Test
        void test1() {
            System.out.println("第一条用例");
        }
    }
    @Nested
    @Order(2)
    class SecondaryTests {
        @Test
        void test2() {
            System.out.println("第二条用例");
        }
    }
}
  • 未指定测试类的执行顺序时
  • 使用Order 注解指定执行顺序后,将会按照@Order中数字的顺序执行

类排序-随机排序

同样与方法排序中使用Random的方法类似,只需在类前添加

@TestClassOrder(ClassOrderer.Random.class)
  • 代码示例
package junit5.order;

import org.junit.jupiter.api.*;

// 指定类执行顺序的方式,DisplayName表示通过DisplayName排序
//@TestClassOrder(ClassOrderer.DisplayName.class)

//使用`Order` 注解指定排序的方式与方法排序中使用`Order`的方法类似,需要结合@Order注解使用。
//@TestClassOrder(ClassOrderer.OrderAnnotation.class)

// 指定类执行顺序的方式,Random代表随机
//@TestClassOrder(ClassOrderer.Random.class)


class OrderExampleTest {
    // 因为是多类执行,所以需要结合@Nested注解
    @Nested
    class PrimaryTests {
        @Test
        void test1() {
            System.out.println("第一条用例");
        }
    }
    @Nested
    class SecondaryTests {
        @Test
        void test2() {
            System.out.println("第二条用例");
        }
    }

    @Nested
    class ThirdTests {
        @Test
        void test2() {
            System.out.println("第三条用例");
        }
    }
}
  • 使用类名随机排序,每次执行时,测试类执行的先后顺序不同。

类排序-根据类名排序

与方法排序类似,根据类名排序同样是根据类名的 ASCII 进行排序。可以按照以下格式对测试类命名:

HogwartsA  HogwartsB  HogwartsC
AHogwarts  BHogwarts  CHogwarts
请注意,如果测试类名称以数字开头,则会按照数字的顺序进行排序。
  • 代码示例
package com.hogwarts.JUnit5;
import org.junit.jupiter.api.*;

// 指定类执行顺序的方式,ClassName代表指定为类名排序
@TestClassOrder(ClassOrderer.ClassName.class)
class orderExampleTest {
// 因为是多类执行,所以需要结合@Nested注解
    @Nested
    class HogwartsA {
        @Test
        void test1() {
            System.out.println("第一条用例");
        }
    }
    @Nested
    class HogwartsB {
        @Test
        void test2() {
            System.out.println("第二条用例");
        }
    }

    @Nested
    class HogwartsC {
        @Test
        void test2() {
            System.out.println("第三条用例");
        }
    }
}
  • 未指定执行顺序时
  • 使用类名指定执行顺序 需要注意类的命名格式 方法的执行顺序会按照类名名 ASCII 码的顺序执行

使用默认配置指定顺序

当我们的测试文件过多时,对每个文件进行配置不免会造成代码冗余,这时在配置文件中添加配置信息会方便很多。

步骤:

  1. 新建配置文件(路径:src/main/resources/junit-platform.properties)

  2. 在配置文件中写入对应的配置信息

  3. 可以分别指定方法的默认配置和类的默认配置


配置默认方法的执行顺序

在配置文件中配置默认方法执行顺序的格式,改变不同执行顺序只需修改$之后的排序方法。

  • 配置格式
junit.jupiter.testmethod.order.default = org.junit.jupiter.api.MethodOrderer$MethodName
  • 修改执行顺序的方法后记得在测试文件中添加相应的注释,如通过Order注解指定方法执行的顺序,则需要在测试方法前使用@Order注解指定顺序,如果采用指定的方法为通过DisplayName排序,则需要搭配@DisplayName注释使用。
#默认排序方式为随机排序
junit.jupiter.testmethod.order.default = org.junit.jupiter.api.MethodOrderer$Random
#默认排序方式为通过方法名排序
junit.jupiter.testmethod.order.default = org.junit.jupiter.api.MethodOrderer$MethodName
#默认排序方式为通过Order注解指定
junit.jupiter.testmethod.order.default = org.junit.jupiter.api.MethodOrderer$OrderAnnotation
#默认排序方式为通过DisplayName排序
junit.jupiter.testmethod.order.default = org.junit.jupiter.api.MethodOrderer$DisplayName
  • 这里我们以随机排序为例,在配置文件中指定随机方法
  • 测试文件代码示例
package junit5.order;

import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
//设定排序方法为注解指定排序
class OrderedTestsDemo {

    @Test
    void HogwartsOne() {
        System.out.println("第一条测试用例");
    }
    @Test
    void HogwartsTwo() {
        System.out.println("第二条测试用例");
    }

    @Test
    void HogwartsThree() {
        System.out.println("第三条测试用例");
    }
}
  • 第一次执行
  • 第二次执行

配置默认类的执行顺序

在配置文件中配置默认类执行顺序的格式与配置方法的执行顺序类似,改变不同执行顺序也只需修改$之后的排序方法,配置默认类的执行顺序可以和配置默认方法的执行顺序结合使用。

注意

使用 Order 排序方法和 DisplayName 排序方法时不要忘记在测试文件中结合相应的注释

#默认排序方式为随机排序
junit.jupiter.testclass.order.default = org.junit.jupiter.api.ClassOrderer$Random
#默认排序方式为通过类名排序
junit.jupiter.testclass.order.default = org.junit.jupiter.api.ClassOrderer$ClassName
#默认排序方式为通过DisplayName排序
junit.jupiter.testclass.order.default = org.junit.jupiter.api.ClassOrderer$DisplayName
#默认排序方式为通过Order注解指定
junit.jupiter.testclass.order.default = org.junit.jupiter.api.ClassOrderer$OrderAnnotation
  • 这里我们配置默认方法的执行顺序和默认类的执行顺序均采用随机顺序 如果测试文件中有指定过执行顺序,记得注释掉。

  • 代码示例
package junit5.order;

import org.junit.jupiter.api.*;

class OrderExampleTest {
    // 因为是多类执行,所以需要结合@Nested注解
    @Nested
    class HogwartsA {
        @Test
        void testA1() {
            System.out.println("A类中第1条用例");
        }
        @Test
        void testA2() {
            System.out.println("A类中第2条用例");
        }
    }
    @Nested
    class HogwartsB {
        @Test
        void testB1() {
            System.out.println("B类中第1条用例");
        }
        @Test
        void testB2() {
            System.out.println("B类中第2条用例");
        }

    }

    @Nested
    class HogwartsC {
        @Test
        void testC1() {
            System.out.println("C类中第1条用例");
        }
        @Test
        void testC2() {
            System.out.println("C类中第2条用例");
        }
    }
}
  • 第一次随机执行时的顺序
  • 第二次随机执行时的顺序 第二次与第一次执行是的方法顺序、类顺序均不相同