JUNIT5测试框架实践二

接JUNIT5测试框架实践一(JUNIT5测试框架实践一)

内容概述

image

如下为重点代码实现:

一、参数化(不同参数个数实现方法)

1、参数类型为 Int 型

1)参数方法

static Stream<Arguments> calculatortest01(){
        return Stream.of(
                Arguments.arguments(Arrays.asList(1,2,3),6),
                Arguments.arguments(Arrays.asList(12,22,34),50),
                Arguments.arguments(Arrays.asList(2,3),5)
        );
    }

2)测试方法

    @ParameterizedTest(name = ARGUMENTS_WITH_NAMES_PLACEHOLDER)
    @MethodSource()
    public void calculatortest01(List<Integer> a, int c){
        result = calculator.sum(a.stream().mapToInt(Integer::intValue).toArray());
        //result1 = calculator.sum(a.stream().toArray(Integer::new));
        //junit5
//        assertEquals(20,result);
        assertThat("计算结果01错误",result,is(equalTo(c)));
    }

2、参数类型为 String 型

1)参数方法

static Stream<Arguments> str1Test(){
         return Stream.of(
                 Arguments.arguments(Arrays.asList("hello","JUnit5"),"hello JUnit5"),
                 Arguments.arguments(Arrays.asList("中国","欢迎","您"),"中国 欢迎 您"),
                 Arguments.arguments(Arrays.asList("这里","是","北京","天安门"),"这里 是 北京 天安门")
         );
     }

2)测试方法

    void str1Test(List<String> stringList,String strRe){
        //list --> String[]
        str1Result = calculator.concatStr(stringList.stream().toArray(String[]::new));
        assertEquals(strRe,str1Result,"message");
    }

二、合并不同类型的断言方法(通过flag内容区分执行哪个测试方法)

1、参数方法

static Stream<Arguments> conbinTest(){
        return Stream.of(
				//第一个方法的参数
                Arguments.arguments(true, Arrays.asList(1,1),2),
                Arguments.arguments(true, Arrays.asList(1,1,4),6),
                Arguments.arguments(true, Arrays.asList(1,1,4,9,6),21),
				//第二个方法的参数
                Arguments.arguments(false, Arrays.asList(1,100),0),
                Arguments.arguments(false, Arrays.asList(1,100,5),0),
                Arguments.arguments(false, Arrays.asList(21,3,100,33),0)
        );

2、测试方法

 @ParameterizedTest
    @MethodSource()
    void conbinTest(boolean flag, List<Integer> numlist,int re){
        if(flag){
            result = calculator.sum(numlist.stream().mapToInt(Integer::intValue).toArray());
            logger.info("计算结果:{}",result);
            assertThat("加法成功",result,is(equalTo(re)));
        }else {
            Exception exception = assertThrowsExactly(NumberFormatException.class,
                    () -> calculator.sum(numlist.stream().mapToInt(Integer::intValue).toArray())
                    );
            String string = exception.getMessage().toString();
            assertThat("断言失败",string,is(containsString("integer is 100")));
        }

三、自定义注解

1、新增注解接口 P0test

//创建p0标签   组合@Test 及 @Tag 标签
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Test
@Tag("p0")
public @interface  P0test {

}

2、应用注解

//引用P0test标签,相当于应用了@Test + @Tag("p0") 标签
//    @Test
    @P0test
    @DisplayName("100连减01")
    public void subtest1_1(){
        result  = calculator.subtract(20,30,30);
        assertThat("100连续减去",result,is(lessThanOrEqualTo(20)));
    }

3、新建suit类测试正确性

@Suite
@SelectClasses({
        com.ceshiren.num.SubTest1.class,
        com.ceshiren.num.SubTest2.class
})
@IncludeTags("p0") //引用Tag标签
public class Suit2Test {
}

四、引用参数对象,使用注解@AggregateWith(适用于多参数测试)

1、实体类(添加get\set方法、添加全参和无参构造函数)

public class SumData {
    private boolean flag;
    private List<Integer> numlist;
    private int re;

2、实体类SumData的aggregateArguments结构化

public class ListAggregator implements ArgumentsAggregator {
    @Override
    public Object aggregateArguments(ArgumentsAccessor accessor, ParameterContext context) throws ArgumentsAggregationException {
        //list --实体类对象SumData
        //access[boolean flag, List<Integer> numlist,int re]
        boolean flag = accessor.getBoolean(0);
        List<Integer> numlist = (List<Integer>) accessor.get(1);
        int re = accessor.getInteger(2);
        SumData sumData = new SumData(flag,numlist,re);
        return sumData;
    }
}

3、参数方法

static Stream<Arguments> conbin1Test(){
        return Stream.of(
                Arguments.arguments(true, Arrays.asList(1,1),2),
                Arguments.arguments(true, Arrays.asList(1,1,4),6),
                Arguments.arguments(true, Arrays.asList(1,1,4,9,6),21),

                Arguments.arguments(false, Arrays.asList(1,100),0),
                Arguments.arguments(false, Arrays.asList(1,100,5),0),
                Arguments.arguments(false, Arrays.asList(21,3,100,33),0)
        );

4、测试方法

        @ParameterizedTest
        @MethodSource("conbin1Test")
        void conbin2Test (@AggregateWith(ListAggregator.class) SumData sumdata){
            if (sumdata.isFlag()) {
                result = calculator.sum(sumdata.getNumlist().stream().mapToInt(Integer::intValue).toArray());
                logger.info("计算结果:{}", result);
                assertThat("加法成功", result, is(equalTo(sumdata.getRe())));
            } else {
                Exception exception = assertThrowsExactly(NumberFormatException.class,
                        () -> calculator.sum(sumdata.getNumlist().stream().mapToInt(Integer::intValue).toArray())
                );
                String string = exception.getMessage().toString();
                assertThat("断言失败", string, is(containsString("integer is 100")));
            }
        }

四、多断言(聚合所有断言-assertAll(heading, executables))

public void subtest1_1(){
        ArrayList<Executable> list = new ArrayList<>();
        result  = calculator.subtract(20,30,30);
        //问题:一个断言失败,就不再运行后续的代码---解决方法:assertAll运行断言列表
        list.add(() ->assertThat("100连续减去",result,is(lessThanOrEqualTo(10))));
        System.out.println("第二次业务逻辑运算");
        int sum = calculator.sum(1,2,3);
        list.add(() ->assertThat("100连续减去",result,is(lessThanOrEqualTo(10))));
        System.out.println("如下执行断言列表");
        assertAll(list);
    }

五、yaml 文件解析

1、添加yaml文件

datas:
  - a: 1
    b: 1
    result: 2
    message: 有效2个整数【1,1】
  - a: 98
    b: 98
    result: 196
    message: 有效边界值相加【98,98】
  - a: -98
    b: 98
    result: 0
    message: 有效边界值相加【-98,98】
  - a: 98
    b: -98
    result: 0
    message: 有效边界值相加【98,-98】
  - a: -98
    b: -98
    result: -196
    message: 有效边界值相加【-98,-98】
  - a: 100
    b: 0
    result: 0
    message: 无效边界值相加【100,0】
  - a: -100
    b: -1
    result: 0
    message: 无效边界值相加【-100,-1】
  - a: 2
    b: 100
    result: 0
    message: 无效边界值相加【2,100】
  - a: 1
    b: -100
    result: 0
    message: 无效边界值相加【1,-100】

2、编写实体类

1)DataInfo.java(内层数据对象)

public class DataInfo {
    //实体类的成员变量名就是map里面的key
    private int a;
    private int b;
    private int result;
    private String message;
//添加get、set方法及构造函数
}

2)Datas.java ( yaml 倒数第二层信息)

public class DataInfo {
    //实体类的成员变量名就是map里面的key
    private int a;
    private int b;
    private int result;
    private String message;
//添加get、set方法及构造函数
}

3、新建 YamlParameterSource 类,从 yaml 中读取数据

public class YamlParameterSource {
    static Stream<DataInfo> parameterYaml(){
        //yaml文件解析为stream流提供给测试方法
        Datas datas = getYaml();
        List<DataInfo> dataInfos = datas.getDatas();
        return dataInfos.stream();
    }
	//读取yaml文件返回Datas实体类
    private static Datas getYaml(){
        Datas dataList = null;
        ObjectMapper mapper  = new ObjectMapper(new YAMLFactory());
        TypeReference<Datas> type = new TypeReference<Datas>() {};
        //按预定义格式读取yaml文件中的内容
        try {
            dataList = mapper.readValue(new File("src/test/resources/data.yaml"),type);

        } catch (IOException e) {
            e.printStackTrace();
        }
        return dataList;
    }
}

4、测试方法

    public Calculator calculator = new Calculator("YamlFactory测试");
    @ParameterizedTest
    //前提:public修饰数据源方法
    //数据源在其他类中,需要引用格式为:包名.类名#数据源的方法名
    @MethodSource("com.ceshiren.source.YamlParameterSource#parameterYaml")
    void parameterYaml(DataInfo dataInfo){
        if(dataInfo.getMessage().startsWith("有效")){
        int sum = calculator.sum(dataInfo.getA(), dataInfo.getB());
        assertAll(
                () -> assertEquals(dataInfo.getResult(),sum,dataInfo.getMessage())
        );
        } else if(dataInfo.getMessage().startsWith("无效")){
//            System.out.println("进入无效判定");
            Exception exception = assertThrowsExactly(NumberFormatException.class,
                    () -> calculator.sum(dataInfo.getA(),dataInfo.getB())
            );
            String string = exception.getMessage().toString();
            assertThat(dataInfo.getMessage(), string, is(containsString("integer is 100")));
        }
    }

六、动态生成测试用例

1、yaml文件

resultList:
  - caseName : 'case_1_1'
    result : true
  - caseName : 'case_1_2'
    result : false
  - caseName : 'case_2_1'
    result : true
  - caseName : 'case_2_2'
    result : false
  - caseName: 'case_1_1'
    result: true
  - caseName: 'case_1_2'
    result: false
  - caseName: 'case_2_1'
    result: true
  - caseName: 'case_2_2'
    result: false
  - caseName: 'case_1_1'
    result: true
  - caseName: 'case_1_2'
    result: false
  - caseName: 'case_2_1'
    result: true
  - caseName: 'case_2_2'
    result: false

2、动态测试创建

1)创建ShellResult类(yaml 文件中最后一层数据)

public class ShellResult {
    private String caseName;
    private Boolean result;
添加set和get、tostring

2)创建ResultList类(yaml 文件中倒数第二层数据)

public class ResultList {
    private List<ShellResult> resultList;
添加get、set方法

3)工厂法动态生成测试用例并运行

//读取yaml文件数据
private ResultList getResutlelist(){
        ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
        TypeReference<ResultList> typeReference = new TypeReference<ResultList>() {};
        try {
            resutlelist = mapper.readValue(new File("src/test/resources/shell_test_result.yaml"),typeReference);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return resutlelist;
    }

// 动态测试
    @TestFactory
    Collection<DynamicTest> shellDynamicTest(){
        Collection<DynamicTest> dynamicTests = new ArrayList<>();
        ResultList resultList = getResutlelist();
        resultList.getResultList().forEach(
                ShellResult -> {
                    DynamicTest dynamicTest = DynamicTest.dynamicTest(ShellResult.getCaseName(),() -> {
                        assertTrue(ShellResult.getResult());
                    });
                    dynamicTests.add(dynamicTest);
                }

        );
        return dynamicTests;
    }