Skip to content

Junit5参数化用例(一)

JUnit5 参数化用例(一)

JUnit5 参数化

通常,会遇到这样的情况,同一个测试案例,改变的只是测试时候输入的参数不同。按照之前的做法,可能会是通过每个输入参数都写一个测试,或者将测试参数封装到集合中循环遍历执行测试。在新版的 Junit5 中,已经提供了一种更加便捷的方式来进行。它们与常规的@Test 方法一样被声明,但是使用 @ParameterizedTest 注释。

参数化环境的配置

为了使用 JUnit 5 的参数化测试(parameterized tests)。需要在 Junit Platform 的基础上,导入另外的 junit-jupiter-params 包。

  • pom 文件配置
<!--        JUnit5参数化依赖 添加后需要更新依赖-->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-params</artifactId>
            <version>5.8.1</version>
            <scope>test</scope>
        </dependency>
  • 更新配置后记得更新依赖 点击右上角更新的小标志 更新成功后内容不再标红

JUnit5 简单参数化 @ValueSource

  • 参数化用例的时候使用的注解由 @Test 换成 @ParameterizedTest(同时存在 并不会有问题,但是 Test 的存在)
  • 单参数化注解 @ValueSource
  • 注意: 如果 @Test 和 @ParameterizedTest 同时使用则会多执行一次

@ValueSource 支持的参数类型

单参数注解支持以下类型的单参数数据的参数化,注意:@ValueSource 不允许传入 Null 值和 Empty 值。从 JUnit 5.4 开始,我们可以使用@NullSource、@EmptySource 和 @NullAndEmptySource 注解可以分别将单个 null 值、单个 Empty 和 Null 和 Empty 传递给参数化测试方法。

参数 参数的类型
shorts short
bytes byte
ints int
longs long
floats float
doubles double
chars char
booleans boolean
strings java.lang.String
classes java.lang.Class
  • 代码实例
package junit5.params;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

public class ValueSourceDemoTest {
    //使用Test的测试方法
    @Test
    void hogwarts(){
        System.out.println("hogwarts");
    }

    //参数化的测试方法
    @ParameterizedTest
    // 1.将Test注解换为ParameterizedTest注解 声明测试类是一个参数化的测试类
    // 2传递测试数据
    //使用单参数注解@VaLueSource传递参数化的数据内容 @ValueSource 可以往测试方法中传递一个数据或者迭代器。
    //传递参数的过程中,需要通过 ValueSource定义的关键字进行类型声明
    @ValueSource(strings = {"张三", "李四", "王五"})
    //3,在测试方法上面添加形参,接受参数化的数据
    void ValueSourceDemo(String name){
        System.out.println(name);
    }
}
  • 实例
  • 执行对比结果可以看到我们运行单个测试多次,但每次运行仅仅是参数不同。

单参数不适用的场景

有时候,测试方法可能需要同时使用多个参数进行测试,而不是分别为每个参数写一个测试方法。使用多参数测试可以在一个测试方法中同时传入多个参数进行测试。为了解决这些情况,可以使用 JUnit 5 的 @CsvSource 注解来实现多参数的参数化测试。 @CsvSource 可以接受一个包含多个参数的字符串数组,每个字符串数组中的值将作为参数传递给测试方法。在下面我们将将介绍多参的参数化的两种方式:@CsvFileSource、@CsvFileSource

JUnit5 多参数的参数化 @CsvSource

  • 多参数参数化注解 @CsvSource。

    @CsvSource 通过指定的分隔符实现参数化。 @CsvSource 可以接受一个包含多个参数的字符串数组,每个字符串数组中的值将作为参数传递给测试方法。@CsvSource 注解中的参数是默认使用逗号分隔的。如果参数值中包含逗号,则需要使用双引号将其括起来。也可以使用delimiterString自定义分隔符

  • 代码实例
public class CsvParamDemoTest {
    // @ParameterizedTest 注解指明为参数化测试用例
    @ParameterizedTest
    // @CsvSource 注解指定数据源为 csv 数据,csv默认分隔符为 ,
    @CsvSource({"张三,3", "李四,15", "王五,8"})
    void testParamCsv1(String name, Integer age) {
        assertEquals(name.length(),2);
        assertTrue(age > 2);
    }

    // @ParameterizedTest 注解指明为参数化测试用例
    @ParameterizedTest
    // @CsvSource 注解指定数据源为 csv 数据,delimiterString 指定数据的分割符
    @CsvSource(value = {"张三|3", "李四|15", "王五|8"}, delimiterString = "|")
    void testParamCsv2(String name, Integer age) {
        assertEquals(name.length(), 2);
        assertTrue(age > 2);
    }
}
  • 在代码中我们使用多参数化得的方式每次传入两个参数 name、age 进行测试,断言 name 的长度为 2,年龄大于 2。在第二个测试方法中使用了delimiterString自定义了分隔符,测试数据两个方法均相同。
  • 执行对比结果 可以看到我们成功对测试方法执行了多次,每次传入两个参数,两个测试方法尽在参数的分隔符上有差别,但执行效果是相同的。
JUnit5 CsvFile 的参数化 @CsvFileSource

通过使用 @CsvFileSource,可以从给定的 CSV 文件中读取数据,并将其中的值作为参数传递给测试方法。

在测试方法中,使用从 CSV 文件中读取的参数进行测试。这样,在每次执行测试方法时,将从 CSV 文件中读取一行数据作为参数传递给测试方法。

需要注意的是,CSV 文件应放置在项目的 resources 目录下或者在类路径下可访问的位置。在 @CsvFileSource 注解中使用的路径应以 "/" 开头,以指定从类路径中读取资源文件。

使用 @CsvFileSource 注解,我们可以更灵活地使用外部 CSV 文件进行参数化测试,从而提高测试的可维护性和扩展性。

@CsvFileSource 支持指定的分隔符进行参数化

  • 数据格式
  1. 新建数据文件
    • data.csv 使用 , 分隔的
    • data2.csv 使用 | 分隔的
张三,3
李四,15
王五,8
张三|3
李四|15
王五|8
  1. 从 csv 文件中读取数据信息。
    • 读取数据文件使用 , 分隔的
    • 读取数据文件使用 | 分隔的
  • 代码实例
注意文件名前需要添加 / 表示根路径(test/resources 为资源的根目录)

如:路径如下图所示 则可以写为:

@CsvFileSource(resources = "/data/data.csv")

  • 代码示例
public class CsvFileParamDemoTest {
    // @ParameterizedTest 注解指明为参数化测试用例
    @ParameterizedTest
    // @CsvFileSource 注解指定数据源为 csv 数据,csv默认分隔符为 ,
    @CsvFileSource(resources = "/data/data.csv")
    void testParamCsvFile(String name, Integer age) {
        assertEquals(name.length(), 2);
        assertTrue(age > 2);
    }

    // @ParameterizedTest 注解指明为参数化测试用例
    @ParameterizedTest
    // @CsvFileSource 注解指定数据源为 csv 数据,delimiterString 指定数据的分割符
    @CsvFileSource(resources = "/data/data2.csv", delimiterString = "|")
    void testParamCsvFile2(String name, Integer age) {
        assertEquals(name.length(), 2);
        assertTrue(age > 2);
    }
}
  • 执行结果如图所示 测试数据读取成功 data.csv 与 data2.csv 中的数据仅为分隔符上的不同,读取效果无差别,但如果在 csv 文件中使用非逗号的分隔符,记得在方法前使用 delimiterString 指定数据的分割符。