Soft Asserts-测试用例的软断言

本文介绍了Java中的硬断言和软断言在测试用例中的作用,区分了两者在断言失败后的处理方式,并展示了TestNG、JUnit5和AssertJ中如何使用软断言进行更详细的错误检查。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

断言是测试用例的一部分,也是测试工程师开发测试用例的核心。断言通常集成在单元测试和集成测试中,分为硬断言和软断言。

图片

硬断言是我们狭义上听到的普通断言:当用例运行后得到的[实际]结果与预期结果不匹配时,测试框架将停止测试执行并抛出断言错误。如下面的案例,测试执行在第一个失败时停止,即使测试中有更多的断言也不会继续执行。

import org.assertj.core.api.SoftAssertions;
import org.junit.jupiter.api.Test;

class HardAssertionTest {

    @Test
    void hardAssertion() {
        var person = Person.builder().name("John").phoneNumber(null).age(16).build();

        assertThat(person.getName()).isNotBlank();
        assertThat(person.getPhoneNumber()).isNotNull();
        assertThat(person.getAge()).isGreaterThan(18);
    }
}

第10行断言失败,则第11行和第12行的断言将不会被执行。

java.lang.AssertionError:
Expecting actual not to be null

通常来说,硬断言在断言失败情况下终止测试执行是无可厚非的。但是在某些情况下,我们想知道被断言的“对象”里哪些属性是不符合预期的,这样使用软断言将解决这个问题。

什么是软断言?

软断言:当一个测试用例中存在多个断言,当有一个断言失败时,会执行后续的断言。

支持软断言的工具通常使用下面的伪代码实现。

SoftAssertion softAssertion = new SoftAssertion()
 
softAssertion.assertSomething...
softAssertion.assertAnotherThing...
softAssertion.assertTheLastThing...
 
softAssertion.assertThenAll();

什么情况下使用软断言?

当测试用例有多个断言时候,应该使用软断言。因为知道所有断言是否与预期结果一致,可以减少多次运行测试以了解哪些不通过。

当测试用例有不止一条断言时,软断言就要到位了。

支持软断言的工具

TestNG

TestNG有一个SoftAssert类,它的功能与前面介绍的伪代码相同:它对断言进行分组,并在我们调用特定方法时立即进行验证。

图片

来看一个软断言的案例:

public class SoftAssertTestNGTest {

    @Test
    public void testNGSoftAssertion() {
        var person = Person.builder().name("John").phoneNumber(null).age(16).build();
        SoftAssert softAssert = new SoftAssert();

        softAssert.assertEquals(person.getName(), "John");
        softAssert.assertNotNull(person.getPhoneNumber(), "Phone number cannot be null");
        softAssert.assertEquals(person.getAge(), 25, "Age should be equal");

        softAssert.assertAll();
    }
}

在例子中,我们断言:phoneNumber不能为空,年龄必须等于25。

  • 第8到10行使用softAssertion在断言方法之前,告诉代码它属于SoftAssertion类。可以使用TestNG支持的任何断言方法实现。

  • 第12行调用assertAll ()方法,该方法将运行与softAssertion引用关联的所有断言

我们可以看到显示一个断言失败,而TestNG没有停止测试执行,而是运行所有的断言,显示所有的失败。

java.lang.AssertionError: The following asserts failed:
    Phone number cannot be null
Expected :25
Actual   :16
<Click to see difference>

JUnit 5

JUnit 5使用assertAll()方法作为软断言方法。它不需要使用外部特定类,它已经是断言类的一部分。我们需要做的就是静态方式导入它。

例子:

import org.junit.jupiter.api.Test;

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

class SoftAssertionJunit5Test {
    @Test
    void softAssertionUsingJUnit5() {
        var person = Person.builder().name("John").phoneNumber(null).age(16).build();

        assertAll("person",
                () -> assertNotNull(person.getName(), "Name must not be null"),
                () -> assertNotNull(person.getPhoneNumber(), "Phone number should not be null"),
                () -> assertEquals(18., person.getAge(), "Age must be 18")
        );
    }
}
  • 第12行显示了使用两个参数的assertAll()方法

    • 一个标题

    • 一个流式的可执行的命令,即断言方法

  • 第13到15行显示了stream的用法,每个stream用于我们必须应用的任何断言

执行结果如下:

import org.junit.jupiter.api.Test;

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

class SoftAssertionJunit5Test {
    @Test
    void softAssertionUsingJUnit5() {
        var person = Person.builder().name("John").phoneNumber(null).age(16).build();

        assertAll("person",
                () -> assertNotNull(person.getName(), "Name must not be null"),
                () -> assertNotNull(person.getPhoneNumber(), "Phone number should not be null"),
                () -> assertEquals(18., person.getAge(), "Age must be 18")
        );
    }
}

AssertJ

AssertJ断言库提供了软断言的不同方法,并可以创建自己的断言:

  • 调用assertAll ()

  • 使用autocloseableoftassertion

  • 使用静态方法assertsoft

我们可以使用所有这些不同的方法来应用它,并在AssertJ页面上查看所有示例。这里可以看到assertsoft静态方法的使用案例。

import org.assertj.core.api.SoftAssertions;
import org.junit.jupiter.api.Test;

class SoftAssertionTest {

    @Test
    void softAssertionUsingAssertJ() {
        var person = Person.builder().name("John").phoneNumber(null).age(16).build();

        SoftAssertions.assertSoftly(softly -> {
            softly.assertThat(person.getName()).isNotBlank();
            softly.assertThat(person.getPhoneNumber()).isNotNull();
            softly.assertThat(person.getAge()).isGreaterThan(18);
        });
    }
}

异常输出如下:

java.lang.AssertionError:
Expecting actual not to be null
at SoftAssertionTest.lambda$assertJSoftAssertion$0(SoftAssertionTest.java:16)
 
java.lang.AssertionError:
Expecting actual:
  16
to be greater than:
  18
at SoftAssertionTest.lambda$assertJSoftAssertion$0(SoftAssertionTest.java:17)
 
org.assertj.core.error.AssertJMultipleFailuresError:
Multiple Failures (2 failures)
-- failure 1 --
Expecting actual not to be null
at SoftAssertionTest.lambda$assertJSoftAssertion$0(SoftAssertionTest.java:16)
-- failure 2 --
Expecting actual:
  16
to be greater than:
  18
at SoftAssertionTest.lambda$assertJSoftAssertion$0(SoftAssertionTest.java:17)
  • AssertionErrors列表及其完整的堆栈信息

  • 带有断言失败的摘要信息

最后:下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值