Skip to content

Junit5多断言处理

JUnit5 多断言处理

什么是多断言?

集中断言是指将多个断言聚合在一起进行测试的一种技术。传统的断言方式只能单独执行每个断言,并且一旦有一个断言失败,该测试就会停止。相比之下,集中断言可以一次性执行多个断言,并生成所有失败的断言的详细错误信息。


为什么要使用集中断言?

  • 场景:
    • 有一个方法存在多个断言,但是其中一个断言失败了,后面的步骤和断言都没有执行,怎么办?
  • JUnit5 的普通断言,当一个断言失败会直接跳出正在执行的测试方法,导致后面的断言无法执行

    • 脚本容错性较低
  • 这个时候就需要用到集中断言

集中断言使用场景

  1. 单元测试:在编写单元测试时,使用集中断言可以组合多个相关的断言,验证测试函数的多个方面。这样可以减少重复的代码,并提高测试代码的可读性。

  2. 复杂对象验证:当需要验证复杂对象的多个属性或状态时,使用集中断言可以组合多个断言来验证各个属性或状态。例如,可以使用集中断言来验证对象的属性是否符合预期,以及对象的状态是否正确。

  3. 多个条件验证:有时候我们需要在一个测试方法中验证多个条件,而不仅仅是一个断言。使用集中断言可以将这些条件组合在一起,使得测试方法的逻辑更加清晰和易于理解。

  4. 逻辑复杂的测试场景:在某些测试场景中,测试结果可能是多个条件的组合判断。使用集中断言可以将这些条件组合在一起,方便地进行复杂输出的验证。


集中断言的 3 种使用方式

  • 拆开多个测试方法,每个测试方法进行一个断言。(会造成大量重复代码,此方案被否)
  • 使用软断言,即使一个断言失败,仍会进行进行余下的断言,然后统一输出所有断言结果。
  • 使用lambda表达式执行多个断言

    • lambda表达式执行语法块

实施方案:

可以使用JUnit5提供的Java 8 lambdas的断言方法,当一个断言失败,剩下的断言依然会执行,脚本的容错性增强。


软断言、集中断言

前提条件

  • 声明一个业务类,方便我们后序进行测试
  • 业务类代码,计算器,进行简单的加法运算
package com.ceshiren.utils;

import org.slf4j.Logger;


import java.util.Arrays;
import java.util.UUID;
import java.util.stream.IntStream;

import static java.lang.invoke.MethodHandles.lookup;
import static org.slf4j.LoggerFactory.getLogger;

public class Calculator {
    //获得具有所需名称的记录器
    public static int result = 0;

    public static int add(int x ,int y) throws InterruptedException {
        result = x + y;
        Thread.sleep(1000);
        return result;

    }
}
}

未使用集中断言

  • 代码示例
package com.ceshiren.arresttest;

import com.ceshiren.utils.Calculator;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class CalculatorTest {
    @Test
    //不推荐的断言方是,一旦断言失败,后续的断言不会继续执行
    void test1() throws InterruptedException {
        int add1 = Calculator.add(1, 4);
        System.out.println("失败的用例");
        assertEquals(9, add1);
        //断言错误后不会继续执行
        System.out.println("成功的用例");
        int add2 = Calculator.add(5, 4);
        assertEquals(9, add2);
    }
}
  • 我们的两个断言在执行完第一个断言失败后就不会继续向下执行。
1.直接assertAll

直接使用 assertAll 进行断言的方法

    @Test
    //使用asserAll进行集中断言
    void test2() throws InterruptedException {
        int result = Calculator.add(1, 4);
        int result01 = Calculator.add(3, 4);
        int result03 = Calculator.add(3, 4);
        assertAll("加法计算结果校验",//heading用来添加描述信息
                //如果需要执行的操作很多,可以使用代码块
                () -> {
                    System.out.println("lambda表达式执行语法块");
                    assertEquals(6, result);
                },
                () -> assertEquals(7, result01),//只有一个操作可以直接写
                () -> assertEquals(8, result03)
        );
    }
  • 在我们设置的三个断言中有两个失败断言,assertAll 中的第一个餐胡为 heading,一般用来添加描述信息,如果其中有一个断言失败了,assertAll方法会抛出一个MultipleFailuresError异常,其中包含了所有失败断言的错误信息。这些错误信息会显示每个失败断言的详细信息,包括失败断言的位置、描述和实际值等。

2. 声明ArrayList<Executable>

另一种方法是我们借助 list 进行断言,将需要进行的断言先存放在数组中,最后进行统一断言。

    @Test
        //使用asserAll进行集中断言
    void test3() throws InterruptedException {
        ArrayList<Executable> assertList = new ArrayList<>();//声明个数组用来存放中间结果
        for(int i=0;i<10;i++){
            int result = Calculator.add(1,i);
            System.out.println("加法计算结果: "+ result);
            int finalI = i;
            //将中间结果保存到list中,以备后面统一断言
            assertList.add(()->assertEquals(finalI,result));
        }
        //将存放在list内的断言内容统一断言
        assertAll("加法计算结果校验",assertList.stream());//统一断言
    }
  • 将断言内容存放在 list 内最后进行统一断言同样可以达到我们集中断言的效果,即使出现断言失败的情况也会继续执行后续断言。