什么是Junit?

JUnit 是一种测试框架,它允许开发人员编写测试用例、运行测试用例、分析测试结果和报告测试结果。在 JUnit 中,测试用例被称为“case”,每个测试用例都包含一组测试方法。测试方法的名称必须以“test”开头,例如“testAdd()”。

Junit需要从注解参数化测试套件三个方面去理解。

JUnit 特点和用法

  • 易于使用:JUnit 非常容易上手,它提供了简单的命令行界面,可以方便地创建、运行和调试单元测试。

  • 支持多类测试:JUnit 可以在同一测试套件中测试多个类,这使得测试更加容易和高效。

  • 支持断言:JUnit 提供了各种断言,如 assertTrue()、assertFalse()、assertNotNull() 和 assertSame() 等,可以帮助开发人员更方便地测试代码。

  • 可扩展性:JUnit 支持自定义测试套件和测试场景,开发人员可以根据需要进行扩展。

  • 支持多种测试格式:JUnit 支持 Junit3、Junit4 和 JUnit5 等多种测试框架,并且可以与其他测试框架集成。

Junit5常见的注解

在正常的类中,如果我们想要运行一个方法,需要我们在main方法中调用这个方法,但是现在我们在方法上添加下面的注解之后,就可以将该方法运行起来。

注解

说明

@Test

表示当前的这个方法为一个测试用例

@Disabled

标识禁用的测试类或者测试方法

@BeforeAll

在所有的测试方法之前执行,并只会执行一次

@BeforeEach

在每个测试方法之前执行

@AfterAll

在所有的测试方法执行完成之后执行,只会执行一次

@AfterEach

在每个测试方法之后执行

@DisplayName

用于为测试类或测试方法提供说明

@Nested

用于创建嵌套测试类。(注解在测试类的内部类上)

@Tag

@Tag

@TestFactory

标记一种方法是动态测试的测试工场

@ParameterizedTest

标识参数化测试方法

@order

设置测试方法的执行顺序

什么是参数化?

  • 参数化是指在测试用例需要传入参数时,使用的传输手段

  • 使用时需要引入 junit-jupiter-params 依赖

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-params</artifactId>
    <version>5.9.3</version>
    <scope>compile</scope>
</dependency>

参数化通过以下四种方式传输数据:

  • 单参数

  • 多参数

  • CSV文件获取参数

  • 方法获取参数

单参数

  • 使用 @ParameterizedTest 注解

  • 使用 @ValueSource 注解,在注解中填入需要传递的单个或多个测试用例

  • 通过方法参数接收,每次接收一个测试用例

@ParameterizedTest
@ValueSource(ints = {1, 2, 3})
public void oneParameter(int i) {
    System.out.println("oneParameter: " + i);
}

多参数

  • 使用 @ParameterizedTest 注解

  • 使用 @CsvSource 注解,在注解中填入需要传递的多个测试用例

  • 通过方法参数接收,每次接收的测试用例数量由参数个数决定

@ParameterizedTest
@CsvSource(value = {"张三,12", "李四,13", "王五,14"})
public void multipleParameter(String name, int age) {
    System.out.println("csvFileParameter: " + name + "->" + age);
}

CSV文件获取参数

  • 使用 @ParameterizedTest 注解

  • 使用 @CsvFileSource 注解,传入 csv 文件

  • 在 resources 目录中,创建对应的 csv 文件,csv 文件每一行为一个参数,参数之间使用 ‘,’ 分隔

  • 通过方法参数接收测试用例,每次接收一行

test.scv
张三,12
李四,13
王五,14
----------------------------------------------------------------
@ParameterizedTest
@CsvFileSource(resources = "/test.csv")
public void csvFileParameter(String name, int age) {
    System.out.println("csvFileParameter: " + name + "->" + age);
}

方法获取参数

  • 使用 @ParameterizedTest 注解

  • 使用 @MethodSource 注解,指定方法名

  • 创建传输参数的方法发,方法必须为 static

  • 通过方法参数接收测试用例

public static Stream<Arguments> methodSource() {
    return Stream.of(
            Arguments.of("张三", 12),
            Arguments.of("李四", 13),
            Arguments.of("王五", 14)
    );
}
 
@ParameterizedTest
@MethodSource(value = "methodSource")
public void methodParameter(String name, int age) {
    System.out.println("csvFileParameter: " + name + "->" + age);
}

测试用例执行顺序如何控制?

  • 使用注解 @TestMethodOrder,不使用该注解时,测试用例的执行顺序是不确定的

  • 使用注解 @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 修饰类,表示该类中的测试用例可更改优先级。

  • 再使用注解 @Order(优先级) 修饰方法,并将代表优先级的数字填入参数中,数字 1 表示最高优先级。

  • 使用注解 @TestMethodOrder(MethodOrderer.Random.class) 修饰类,表示该类中的测试用例将被随机执行

什么是测试套件?

  • 测试套件是用于将多个测试用例的类同时运行的工具(相当于将众多测试打包)。

  • 使用测试套件时,需要引入以下两个依赖:

    • junit-platform-suite :测试套件

    • junit-jupiter-engine :测试套件引擎

  • 使用注解 @Suite() 修饰类,表示启用测试套件。

  • 可以使用两种方式将测试用例打包为测试套件:

    • 可以通过 载入类名 运行测试用例:使用注解 @SelectClasses({类名.class...}) ,在注解中传入需要测试的类。

    • 可以通过 载入包名 运行测试用例:将多个测试用例类放入同一个包中,使用注解@SelectPackages({包名...}),在注解中传入需要测试的包。

<!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-suite -->
<dependency>
    <groupId>org.junit.platform</groupId>
    <artifactId>junit-platform-suite</artifactId>
    <version>1.9.2</version>
    <scope>test</scope>
</dependency>
 
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine -->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.9.2</version>
    <scope>test</scope>
</dependency>
 
public class Test01 {
    @Test
    void Test01(){
        System.out.println("Test01");
    }
}
 
public class Test02 {
    @Test
    void Test02(){
        System.out.println("Test02");
    }
}
​
//设置该类为套件测试的主类
@Suite
//选择要运行的测试包
@SelectPackages(value = {"Test01", "Test02"})
public class RunSuite {
​
}