• 【软件测试】JUnit详解


    一. Junit是什么?

    JUnit是一个用于编写和运行Java程序单元测试的开源框架
    它提供了一组注解和断言方法,以及用于执行测试的测试运行器。通过使用JUnit,开发人员可以轻松地编写自动化测试用例,验证代码的正确性,并且能够快速地发现和修复bug。JUnit的使用可以提高代码的质量和可维护性,同时也有助于进行持续集成和持续测试。它被广泛应用在Java开发领域中,成为了标准的单元测试框架之一。

    为什么学了Selenium还需要学习Junit?
    Selenium是自动化测试框架;Junit是单元测试框架.
    拿着一个技术写自动化测试用例(Selenium3)
    拿着一个技术管理已经编写好的测试用例(Junit5)

    二.Junit中常见的注解

    我们本节博客所学习的是Junit5,Junit5中的注解如下:

    注解说明
    @Test标识单元测试方法。
    @ParameterizedTest标识参数化测试方法。
    @RepeatedTest标识可重复执行的测试方法。
    @TestFactory标识动态测试方法,用于生成测试用例。
    @BeforeEach在每个测试方法之前执行。
    @AfterEach在每个测试方法之后执行。
    @BeforeAll在所有测试方法之前执行,只会执行一次。
    @AfterAll在所有测试方法之后执行,只会执行一次。
    @DisplayName设置测试类或测试方法的显示名称。
    @Disabled标识禁用的测试类或测试方法。
    @Nested声明内部测试类。
    @Tag为测试类或测试方法添加标签,用于分组和过滤。
    @Timeout设置测试方法执行超时时间。
    @ExtendWith注册扩展,用于扩展JUnit的功能。
    @RegisterExtension注册扩展实例,用于扩展JUnit的功能。

    上述表格中,其中黑体为常用的注解,也是接下来主要介绍说明的注解.

    想要使用Junit5的框架,我们首先要从中央仓库中引入Maven依赖.代码如下所示:

    <dependency>
                <groupId>org.junit.jupitergroupId>
                <artifactId>junit-jupiter-apiartifactId>
                <version>5.9.1version>
            dependency>
            <dependency>
                <groupId>org.junit.jupitergroupId>
                <artifactId>junit-jupiter-paramsartifactId>
                <version>5.9.1version>
            dependency>
            
            <dependency>
                <groupId>org.junit.jupitergroupId>
                <artifactId>junit-jupiter-paramsartifactId>
                <version>5.9.1version>
            dependency>
            <dependency>
                <groupId>org.junit.platformgroupId>
                <artifactId>junit-platform-suiteartifactId>
                <version>1.9.1version>
                <scope>testscope>
            dependency>
    
            
            <dependency>
                <groupId>org.junit.platformgroupId>
                <artifactId>junit-platform-suiteartifactId>
                <version>1.9.1version>
            dependency>
            
            <dependency>
                <groupId>org.junit.jupitergroupId>
                <artifactId>junit-jupiter-engineartifactId>
                <version>5.9.1version>
                <scope>testscope>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    1. @Test

    @Test:用于标识单元测试方法。

        @Test
        void Test01() {
            System.out.println("这是JunitTest里面的Test01");
        }
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    2. @BeforeAll & @AfterAll

    @BeforeAll:在所有测试方法之前执行,只会执行一次。
    @AfterAll:在所有测试方法之后执行,只会执行一次。

        @Test
        void Test01() {
            System.out.println("这是JunitTest里面的Test01");
        }
        @Test
        void Test02() {
            System.out.println("这是JunitTest里面的Test02");
        }
        @BeforeAll
        static void SetUp() {
            System.out.println("这是BeforeAll里面的语句");
        }
    
        @AfterAll
        static void TearDown() {
            System.out.println("这是AfterAll的语句");
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述

    3. @BeforeEach & @AfterEach

    @BeforeEach: 在每个测试方法之前执行。
    @AfterEach: 在每个测试方法之后执行。

        @Test
        void Test01() {
            System.out.println("这是JunitTest里面的Test01");
        }
        @Test
        void Test02() {
            System.out.println("这是JunitTest里面的Test02");
        }
        @BeforeEach
        void BeforeEachTest() {
            System.out.println("这是BeforeEach里面的语句");
        }
    
        @AfterEach
        void AfterEachTest() {
            System.out.println("这是AfterEach里面的语句");
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述

    4. @ParameterizedTest参数化

    @ParameterizedTest: 标识参数化测试方法。

    1. 单参数

          @ParameterizedTest
          @ValueSource(ints = {1, 2, 3})
          void Test04(int num) {
              System.out.print(num);
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5

      在这里插入图片描述

          @ParameterizedTest
          @ValueSource(strings = {"1", "2", "3"," "})
          void Test05(String number) {
              System.out.println(number);
              System.out.println("=============");
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

      如果想要打印空格可以用空字符串
      在这里插入图片描述

    2. CSV获取参数

          @ParameterizedTest
          @CsvFileSource(resources = "test01.csv")
          void Test06(String name) {
              System.out.println(name);
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5

      resource:test01.csv:

      张三1,李四1,王五1
      张三2,李四2,王五2
      张三3,李四31
      
      • 1
      • 2
      • 3

      在这里插入图片描述

    3. 方法获取参数

          public static Stream<Arguments> Generator() {
              return Stream.of(Arguments.arguments(1, "张三"),
                      Arguments.arguments(2, "李四"),
                      Arguments.arguments(3, "王五")
              );
          }	
          @ParameterizedTest
          @MethodSource("Generator")
          void Test07(int num, String name) {
              System.out.println(num + ":" + name);
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

      在这里插入图片描述

    5. @Disabled

    @Disabled: 标识禁用的测试类或测试方法。

    @Disabled
        void Test03() {
            WebDriver webDriver = new ChromeDriver();
            webDriver.get("https://www.baidu.com");
            webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(6)"));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    执行所有测试用例发现:
    在这里插入图片描述
    Test03未被执行.

    6. @Order

    @Order 注解是 JUnit 5 中用来指定测试方法执行的顺序的注解。通过给测试方法添加 @Order 注解并指定一个整数值,可以确保测试方法按照指定的顺序执行。

    import org.junit.jupiter.api.*;
    @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
    //@TestMethodOrder(MethodOrderer.Random.class)
    public class JunitTest01 {
        @Order(2)
        @Test
        void B() {
            System.out.println("B测试用例");
        }
    
        @Order(3)
        @Test
        void Test01() {
            System.out.println("这是Test01测试用例");
        }
    
        @Order(1)
        @Test
        void A() {
            System.out.println("A测试用例");
        }
    
        @Order(4)
        @Test
        void Test02() {
            System.out.println("被忽略的测试用例");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    在这里插入图片描述
    可以看到,执行顺序使我们所手动指定的顺序.
    上述例子中,@TestMethodOrder(MethodOrderer.OrderAnnotation.class) 注解指定了使用 OrderAnnotation 来排序测试方法。然后,每个测试方法都使用 @Order 注解指定了它们应该执行的顺序。
    需要注意的是:测试方法的默认执行顺序是不确定的.因此使用 @Order 注解可以提供一致和可预测的执行顺序。

    三. 测试套件

    测试套件是一种组织和执行一组测试的方式。在JUnit中,可以使用 @RunWith 注解和 Suite 类来创建测试套件。

    1. 通过class运行测试用例

    	@Suite
    	//通过class测试用例运行
    	@SelectClasses({JunitTest03.class, JunitTest.class, JunitTest01.class})
    	public class RunSuite {
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    2. 通过包运行测试用例

    import org.junit.platform.suite.api.SelectClasses;
    import org.junit.platform.suite.api.SelectPackages;
    import org.junit.platform.suite.api.Suite;
    
    @Suite
    @SelectPackages(value = {"Test09", "Test08"})
    public class RunSuite {
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    package Test08;
    
    import org.junit.jupiter.api.Test;
    
    public class Test07 {
        @Test
        void Test007() {
            System.out.println("Test08 pacage Test007");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    package Test09;
    
    import org.junit.jupiter.api.Test;
    
    public class Test09 {
        @Test
        void Test01() {
            System.out.println("package test09 test01");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    四. 断言

    JUnit 5 中,断言方法位于 org.junit.jupiter.api.Assertions 类中。

    使用断言可以在测试中验证预期结果是否与实际结果相符。如果断言失败,则测试将被标记为失败,并提供有关错误的详细信息。这有助于快速定位和修复问题。

    断言方法说明
    assertEquals(expected, actual)验证两个对象是否相等。可以用于比较基本数据类型、对象和数组。
    assertTrue(condition)验证条件是否为真。如果条件为真,则测试通过;否则,测试失败。
    assertFalse(condition)验证条件是否为假。如果条件为假,则测试通过;否则,测试失败。
    assertNull(actual)验证对象是否为 null。如果对象为 null,则测试通过;否则,测试失败。
    assertNotNull(actual)验证对象是否不为 null。如果对象不为 null,则测试通过;否则,测试失败。
    assertSame(expected, actual)验证两个对象引用是否相同。即判断两个对象是否指向同一个内存地址。
    assertNotSame(unexpected, actual)验证两个对象引用是否不相同。
    assertArrayEquals(expectedArray, actualArray)验证两个数组是否相等。用于比较数组的元素是否相等。
    assertThrows(expectedType, executable)验证代码块是否抛出了特定类型的异常。
    assertTimeout(duration, executable)验证代码块是否在指定的时间内执行完成,超过指定时间则测试失败。
    import org.junit.jupiter.api.Test;
    import static org.junit.jupiter.api.Assertions.*;
    
    public class MyTest {
    
        @Test
        public void test() {
            String str = "Hello, World!";
            int number = 42;
            boolean condition = true;
    
            assertEquals("Hello, World!", str);
            assertTrue(number > 0);
            assertFalse(condition);
            assertNull(null);
            assertNotNull(str);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    上述例子中.assertFalse(condition);即测试中验证预期结果与实际结果不相符.
    在这里插入图片描述

  • 相关阅读:
    LegalQA 数据集 样例数据
    mybatis-plus通用业务分页查询封装
    高德地图 JS API用于绘画船舶轨迹
    const成员函数 以及 取地址及const取地址操作符重载
    如何防止内部员工数据外泄?
    如何编译linux驱动ko
    QT添加菜单栏-工具栏-中心区域-状态栏-dock 示范
    group_concat多行合并成一行
    抗疫逆行者网页作业 感动人物HTML网页代码成品 网页作业带JS下拉菜单 最美逆行者网页模板 致敬疫情感动人物网页设计制作
    C#根据中文首字母排序
  • 原文地址:https://blog.csdn.net/qq_61138087/article/details/133682885