【软件测试】JUnit详解

文章目录

  • [一. Junit是什么?](#一. Junit是什么?)
  • 二.Junit中常见的注解
    • [1. @Test](#1. @Test)
    • [2. @BeforeAll & @AfterAll](#2. @BeforeAll & @AfterAll)
    • [3. @BeforeEach & @AfterEach](#3. @BeforeEach & @AfterEach)
    • [4. @ParameterizedTest参数化](#4. @ParameterizedTest参数化)
    • [5. @Disabled](#5. @Disabled)
    • [6. @Order](#6. @Order)
  • [三. 测试套件](#三. 测试套件)
    • [1. 通过class运行测试用例](#1. 通过class运行测试用例)
    • [2. 通过包运行测试用例](#2. 通过包运行测试用例)
  • [四. 断言](#四. 断言)

一. 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依赖.代码如下所示:

xml 复制代码
<dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.9.1</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-params</artifactId>
            <version>5.9.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-params -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-params</artifactId>
            <version>5.9.1</version>
        </dependency>
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-suite</artifactId>
            <version>1.9.1</version>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-suite -->
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-suite</artifactId>
            <version>1.9.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.9.1</version>
            <scope>test</scope>
        </dependency>

1. @Test

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

java 复制代码
    @Test
    void Test01() {
        System.out.println("这是JunitTest里面的Test01");
    }

2. @BeforeAll & @AfterAll

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

java 复制代码
    @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的语句");
    }

3. @BeforeEach & @AfterEach

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

java 复制代码
    @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里面的语句");
    }

4. @ParameterizedTest参数化

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

  1. 单参数

    java 复制代码
        @ParameterizedTest
        @ValueSource(ints = {1, 2, 3})
        void Test04(int num) {
            System.out.print(num);
        }
    java 复制代码
        @ParameterizedTest
        @ValueSource(strings = {"1", "2", "3"," "})
        void Test05(String number) {
            System.out.println(number);
            System.out.println("=============");
        }

    如果想要打印空格可以用空字符串

  2. CSV获取参数

    java 复制代码
        @ParameterizedTest
        @CsvFileSource(resources = "test01.csv")
        void Test06(String name) {
            System.out.println(name);
        }

    resource:test01.csv:

    java 复制代码
    张三1,李四1,王五1
    张三2,李四2,王五2
    张三3,李四3,1
  3. 方法获取参数

    java 复制代码
        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);
        }

5. @Disabled

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

java 复制代码
@Disabled
    void Test03() {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("https://www.baidu.com");
        webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(6)"));
    }

执行所有测试用例发现:

Test03未被执行.

6. @Order

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

java 复制代码
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("被忽略的测试用例");
    }

}

可以看到,执行顺序使我们所手动指定的顺序.

上述例子中,@TestMethodOrder(MethodOrderer.OrderAnnotation.class) 注解指定了使用 OrderAnnotation 来排序测试方法。然后,每个测试方法都使用 @Order 注解指定了它们应该执行的顺序。

需要注意的是:测试方法的默认执行顺序是不确定的 .因此使用 @Order 注解可以提供一致和可预测的执行顺序。

三. 测试套件

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

1. 通过class运行测试用例

java 复制代码
	@Suite
	//通过class测试用例运行
	@SelectClasses({JunitTest03.class, JunitTest.class, JunitTest01.class})
	public class RunSuite {
	}

2. 通过包运行测试用例

java 复制代码
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 {
}
java 复制代码
package Test08;

import org.junit.jupiter.api.Test;

public class Test07 {
    @Test
    void Test007() {
        System.out.println("Test08 pacage Test007");
    }
}
java 复制代码
package Test09;

import org.junit.jupiter.api.Test;

public class Test09 {
    @Test
    void Test01() {
        System.out.println("package test09 test01");
    }
}

四. 断言

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) 验证代码块是否在指定的时间内执行完成,超过指定时间则测试失败。
java 复制代码
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);
    }
}

上述例子中.assertFalse(condition);即测试中验证预期结果与实际结果不相符.

相关推荐
期待のcode7 分钟前
Java虚拟机的运行模式
java·开发语言·jvm
程序员老徐10 分钟前
Tomcat源码分析三(Tomcat请求源码分析)
java·tomcat
a程序小傲19 分钟前
京东Java面试被问:动态规划的状态压缩和优化技巧
java·开发语言·mysql·算法·adb·postgresql·深度优先
仙俊红20 分钟前
spring的IoC(控制反转)面试题
java·后端·spring
阿湯哥21 分钟前
AgentScope Java 集成 Spring AI Alibaba Workflow 完整指南
java·人工智能·spring
小楼v32 分钟前
说说常见的限流算法及如何使用Redisson实现多机限流
java·后端·redisson·限流算法
与遨游于天地44 分钟前
NIO的三个组件解决三个问题
java·后端·nio
czlczl200209251 小时前
Guava Cache 原理与实战
java·后端·spring
yangminlei1 小时前
Spring 事务探秘:核心机制与应用场景解析
java·spring boot
记得开心一点嘛2 小时前
Redis封装类
java·redis