jck28 - 小柒 - Junit5参数化与调度执行学习笔记L1

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