• 软断言你也学不会


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

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

    1. import org.assertj.core.api.SoftAssertions;
    2. import org.junit.jupiter.api.Test;
    3. class HardAssertionTest {
    4. @Test
    5. void hardAssertion() {
    6. var person = Person.builder().name("John").phoneNumber(null).age(16).build();
    7. assertThat(person.getName()).isNotBlank();
    8. assertThat(person.getPhoneNumber()).isNotNull();
    9. assertThat(person.getAge()).isGreaterThan(18);
    10. }
    11. }

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

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

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

    什么是软断言?

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

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

    1. SoftAssertion softAssertion = new SoftAssertion()
    2. softAssertion.assertSomething...
    3. softAssertion.assertAnotherThing...
    4. softAssertion.assertTheLastThing...
    5. softAssertion.assertThenAll();

    什么情况下使用软断言?

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

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

    支持软断言的工具

    TestNG

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

    来看一个软断言的案例:

    1. public class SoftAssertTestNGTest {
    2. @Test
    3. public void testNGSoftAssertion() {
    4. var person = Person.builder().name("John").phoneNumber(null).age(16).build();
    5. SoftAssert softAssert = new SoftAssert();
    6. softAssert.assertEquals(person.getName(), "John");
    7. softAssert.assertNotNull(person.getPhoneNumber(), "Phone number cannot be null");
    8. softAssert.assertEquals(person.getAge(), 25, "Age should be equal");
    9. softAssert.assertAll();
    10. }
    11. }

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

    • 第8到10行使用softAssertion在断言方法之前,告诉代码它属于SoftAssertion类。可以使用TestNG支持的任何断言方法实现。
    • 第12行调用assertAll ()方法,该方法将运行与softAssertion引用关联的所有断言

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

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

    JUnit 5

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

    例子:

    1. import org.junit.jupiter.api.Test;
    2. import static org.junit.jupiter.api.Assertions.assertAll;
    3. import static org.junit.jupiter.api.Assertions.assertEquals;
    4. import static org.junit.jupiter.api.Assertions.assertNotNull;
    5. class SoftAssertionJunit5Test {
    6. @Test
    7. void softAssertionUsingJUnit5() {
    8. var person = Person.builder().name("John").phoneNumber(null).age(16).build();
    9. assertAll("person",
    10. () -> assertNotNull(person.getName(), "Name must not be null"),
    11. () -> assertNotNull(person.getPhoneNumber(), "Phone number should not be null"),
    12. () -> assertEquals(18., person.getAge(), "Age must be 18")
    13. );
    14. }
    15. }
    • 第12行显示了使用两个参数的assertAll()方法
      • 一个标题
      • 一个流式的可执行的命令,即断言方法
    • 第13到15行显示了stream的用法,每个stream用于我们必须应用的任何断言

    执行结果如下:

    1. org.opentest4j.AssertionFailedError: Phone number should not be null ==> expected: not <null>
    2. at org.example.SoftAssertionJunit5Test.lambda$softAssertionUsingJUnit5$1(SoftAssertionJunit5Test.java:17)
    3. org.opentest4j.AssertionFailedError: Age must be 18 ==>
    4. Expected :18.0
    5. Actual :16.0
    6. at org.example.SoftAssertionJunit5Test.lambda$softAssertionUsingJUnit5$2(SoftAssertionJunit5Test.java:18)
    7. org.opentest4j.MultipleFailuresError: person (2 failures)
    8. org.opentest4j.AssertionFailedError: Phone number should not be null ==> expected: not <null>
    9. org.opentest4j.AssertionFailedError: Age must be 18 ==> expected: <18.0> but was: <16.0>

    AssertJ

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

    • 调用assertAll ()
    • 使用autocloseableoftassertion
    • 使用静态方法assertsoft

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

    1. import org.assertj.core.api.SoftAssertions;
    2. import org.junit.jupiter.api.Test;
    3. class SoftAssertionTest {
    4. @Test
    5. void softAssertionUsingAssertJ() {
    6. var person = Person.builder().name("John").phoneNumber(null).age(16).build();
    7. SoftAssertions.assertSoftly(softly -> {
    8. softly.assertThat(person.getName()).isNotBlank();
    9. softly.assertThat(person.getPhoneNumber()).isNotNull();
    10. softly.assertThat(person.getAge()).isGreaterThan(18);
    11. });
    12. }
    13. }

    异常输出如下:

    1. java.lang.AssertionError:
    2. Expecting actual not to be null
    3. at SoftAssertionTest.lambda$assertJSoftAssertion$0(SoftAssertionTest.java:16)
    4. java.lang.AssertionError:
    5. Expecting actual:
    6. 16
    7. to be greater than:
    8. 18
    9. at SoftAssertionTest.lambda$assertJSoftAssertion$0(SoftAssertionTest.java:17)
    10. org.assertj.core.error.AssertJMultipleFailuresError:
    11. Multiple Failures (2 failures)
    12. -- failure 1 --
    13. Expecting actual not to be null
    14. at SoftAssertionTest.lambda$assertJSoftAssertion$0(SoftAssertionTest.java:16)
    15. -- failure 2 --
    16. Expecting actual:
    17. 16
    18. to be greater than:
    19. 18
    20. at SoftAssertionTest.lambda$assertJSoftAssertion$0(SoftAssertionTest.java:17)
    • AssertionErrors列表及其完整的堆栈信息
    • 带有断言失败的摘要信息
  • 相关阅读:
    C++标准模板(STL)- 类型支持 (数值极限,min,lowest,max)
    组合电路、触发器、时序电路
    PMP商业分析概述
    九泰智库 | 医械周刊- Vol.23
    Shell脚本中常见的几种变量类型
    mysql中的悲观锁和乐观锁
    【Nginx25】Nginx学习:连接限制和请求限制
    Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案
    SQL Server 2016(分离和附加数据库)
    P1074 [NOIP2009 提高组] 靶形数独
  • 原文地址:https://blog.csdn.net/csd11311/article/details/133514177