1,参数化用例
导入maven依赖:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
2,单参数化注解
- 参数化用例的时候使用的注解由 @Test 换成 @ParameterizedTest
- 单参数化注解 @ValueSource
- 注意: 如果 @Test 和 @ParameterizedTest 同时使用则会多执行一次
代码示例:
package parameterizedTestDemo;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ValueSourceTest {
@ParameterizedTest //注解指明为参数化测试用例
@ValueSource(strings = {"张三","阿雅","李四"}) //单参数注解,示例中为String类型参数化
public void valueSource(String name){
System.out.println(name);
assertEquals(name.length(),2);
}
@ParameterizedTest
@ValueSource(ints = {1,2,3,4,5})
public void valueSourceInt(int digit){
System.out.println(digit);
}
}
3,多参数化注解
- 多参数参数化注解 @CsvSource。
- @CsvSource 通过指定的分隔符实现参数化。
代码示例:
package parameterizedTestDemo;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
public class CsvSourceTest {
@ParameterizedTest
//多参数参数化注解 @CsvSource注解指定数据源为 csv 数据,csv默认分隔符为 ,
@CsvSource({"张三,20,65","李四,25,80","王五,18,74"})
public void csvSource(String name ,Integer age,Long score){
System.out.println("姓名:"+name +" \t年龄:"+age +" \t成绩:"+ score);
}
@ParameterizedTest
//@CsvSource 通过指定的分隔符实现参数化,delimiterString - 指定数据的分割符
@CsvSource(value = {"雪莉|20|65","庭庭|25|80","朝阳|18|74"}, delimiterString = "|")
public void csvSourceOne(String name ,Integer age,Long score){
System.out.println("姓名:"+name +" \t年龄:"+age +" \t成绩:"+ score);
}
}
4, 多参数文件参数化注解 @CsvFileSource
- 在项目的 test/resources 中新增测试数据 csv 文件
- @CsvFileSource 支持指定的分隔符进行参数化
代码示例:
package parameterizedTestDemo;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class CsvFileSourceTest {
@ParameterizedTest
//文件名前必须要加/ - 标识resources根目录
@CsvFileSource(resources = "/data.csv")
public void csvFileSource(String name ,Integer age, Long score){
System.out.println("姓名:"+name +" \t年龄:"+age +" \t成绩:"+ score);
assertTrue(score > 60);
}
@ParameterizedTest
@CsvFileSource(resources = "/data2.csv", delimiterString = "|")
public void csvFileSourceTwo(String name ,Integer age, Long score){
System.out.println("姓名:"+name +" \t年龄:"+age +" \t成绩:"+ score);
assertTrue(score > 60);
}
}
5, @MethodSource 参数化
- 通过@MethodSource注解引用方法作为参数化的数据源信息
- 在 @MethodSource 注解的参数必须是静态的工厂方法,除非测试类被注释为
@TestInstance(Lifecycle.PER_CLASS)
- 静态工厂方法的返回值需要和测试方法的参数对应
- 如果在 @MethodSource 注解中未指明方法名,会自动调用与测试方法同名的静态方法
package MethodSourceDemo;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.stream.Stream;
public class MethodSourceTest {
@ParameterizedTest //注解指明为参数化用例
@MethodSource("strProvider") //在@MethodSource中指定工厂方法名称,必须是静态的工厂方法
void localMehtod(String name){ //单参数方法String
System.out.println(name);
}
//静态的工厂方法,在@MethodSource被指定
//因为测试方法传参为String,所以Stream<>流里必须指定为String
static Stream<String> strProvider(){
return Stream.of("苹果","凤梨");
}
//单参数方法int
@ParameterizedTest
@MethodSource("intProvider")
void localMethodTwo(int age){
System.out.println(age);
}
static Stream<Integer> intProvider(){
return Stream.of(1,3,5);
}
//有多个参数和种类, 包含字符串、整型,官方推荐用Arguments
@ParameterizedTest
@MethodSource("multiMehthod")
void localMultiMethod(String name ,int age,int score){
System.out.println("姓名:"+name +" \t年龄:"+age +" \t成绩:"+ score);
}
static Stream<Arguments> multiMehthod(){
return Stream.of(
Arguments.arguments("吉卜力",18,95),
Arguments.arguments("三吉彩花",25,78),
Arguments.arguments("上户彩",38,90)
);
}
// 在 @MethodSource 不指明方法名,框架会找同名的无参数方法
@ParameterizedTest
@MethodSource
void localMultiMethod(String name ,int age){
System.out.println("姓名:"+name +" \t年龄:"+age );
}
static Stream<Arguments> localMultiMethod(){
return Stream.of(
Arguments.arguments("李彩桦",35),
Arguments.arguments("洪玲",42),
Arguments.arguments("彩蝶",21)
);
}
}
6, 枚举参数的参数化
- 使用枚举类作为测试数据。
- 枚举参数参数化注解 @EnumSource。
- 必须与 @ParameterizedTest 结合使用。
package MethodSourceDemo;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import java.util.EnumSet;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.params.provider.EnumSource.Mode.EXCLUDE;
import static org.junit.jupiter.params.provider.EnumSource.Mode.MATCH_ALL;
public class EnumSourceTest {
public enum HogwartsUnit{
Harry("Harry",18),
AD("AD",19),
AD2("AD2",12);
private final String name;
private final int age;
private HogwartsUnit(String name , int age){
this.name = name;
this.age = age;
}
}
@ParameterizedTest //指明为参数化用例
@EnumSource //指明为枚举类型
//枚举类作为参数传入测试方法
void enumTest(HogwartsUnit unit){
assertTrue(EnumSet.of(HogwartsUnit.Harry,HogwartsUnit.AD,HogwartsUnit.AD2).contains(unit));
}
@ParameterizedTest
@EnumSource(names = "Harry") //可以通过name参数指定使用的枚举值
void enumTest2(HogwartsUnit unit){
assertTrue(EnumSet.of(HogwartsUnit.Harry,HogwartsUnit.AD).contains(unit));
}
// 可以通过mode 参数指定规则
// EXCLUDE 代表取反,即指定名称不等于的场景
// MATCH_ALL 代表通过正则进行匹配
@ParameterizedTest
@EnumSource(mode=EXCLUDE ,names = "Harry") //指定名称不为Harry的枚举值
void enumTest3(HogwartsUnit unit){
assertTrue(EnumSet.of(HogwartsUnit.Harry,HogwartsUnit.AD).contains(unit));
}
@ParameterizedTest
@EnumSource(mode=MATCH_ALL ,names = ".*ry")
void enumTest4(HogwartsUnit unit){
assertTrue(EnumSet.of(HogwartsUnit.Harry,HogwartsUnit.AD).contains(unit));
}
}
7,特殊参数的参数化
- 自动化测试过程中,需要验证某些特殊场景时,需要传空或者传null
- null 参数的参数化注解 @NullSource 注解
- 参数为空的参数化注解 @EmptySource 注解
- 需要 null 和空都进行参数化,使用 @NullAndEmptySource 注解
- 还有其他参数可以用@ValueSource继续提供
package MethodSourceDemo;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EmptySource;
import org.junit.jupiter.params.provider.NullAndEmptySource;
import org.junit.jupiter.params.provider.NullSource;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class NullAndEmptyTest {
@ParameterizedTest
// @NullSource 注解表示使用null参数进行测试输入
@NullSource
void testNullSource(String param) {
// 断言入参为null
System.out.println(param);
assertNull(param);
}
@ParameterizedTest
// @NullSource 注解表示使用null参数进行测试输入
@EmptySource
void testEmptySource(String param) {
// 断言入参为null
assertTrue(param.isEmpty());
}
@ParameterizedTest
// @NullAndEmptySource 注解结合了 @EmptySource 与 @NullSource
@NullAndEmptySource
void testEmptyNullSource(String param) {
// 断言参数是空的
assertTrue(param == null || param.isEmpty());
}
@ParameterizedTest
// @NullAndEmptySource 注解结合了 @EmptySource 与 @NullSource
@NullAndEmptySource
// 如果还有其他参数可以用@ValueSource继续提供
@ValueSource(strings = {""})
void testEmptyNullAndValueSource(String param) {
// 断言参数是空的
assertTrue(param == null || param.isEmpty());
}
}