• JUnit 5简明教程


    概述

    写测试用例对于开发来说有2点好处,一是开发阶段写完的功能可以快速验证,第二就是在后期需求变动或修改BUG后可以快速测试当前改动是否带来其它问题。下面就了解一下Junit5写测试用例。

    准备

    创建一个maven项目

    mkdir junit5-tutorial
    cd junit5-tutorial
    
    mkdir -p src/main/java
    mkdir -p src/test/java
    
    mkdir -p src/main/resources
    mkdir -p src/test/resources
    
    # 编写pom.xml
    vi pom.xml
    

    添加依赖

    • 引入第三方断言库assertj
    • 支持json测试
    • 支持xml测试

    pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.example.xxx</groupId>
        <artifactId>junit5-tutorial</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <name>junit5-tutorial</name>
    
        <url>https://www.xxx.com</url>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>17</maven.compiler.source>
            <maven.compiler.target>17</maven.compiler.target>
        </properties>
    
        <build>
            <pluginManagement>
                <plugins>
                    <!-- 在这里声明的目的是使用指定的版本 -->
                    <!-- 执行测试用例任务的插件,默认绑定test生命周期的test阶段 -->
                    <plugin>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <version>3.0.0-M6</version>
                    </plugin>
                    <!-- 用来执行编译任务的插件,默认绑定default生命周期compile阶段 -->
                    <plugin>
                        <artifactId>maven-compiler-plugin</artifactId>
                        <version>3.10.1</version>
                    </plugin>
                </plugins>
            </pluginManagement>
    
        </build>
    
        <dependencyManagement>
            <dependencies>
                <!-- XML Unit - Dependency Management -->
                <dependency>
                    <groupId>net.bytebuddy</groupId>
                    <artifactId>byte-buddy</artifactId>
                    <version>1.12.10</version>
                </dependency>
                <dependency>
                    <groupId>net.bytebuddy</groupId>
                    <artifactId>byte-buddy-agent</artifactId>
                    <version>1.12.10</version>
                    <scope>test</scope>
                </dependency>
    
                <!-- Mockito Dependency -->
                <dependency>
                    <groupId>org.mockito</groupId>
                    <artifactId>mockito-junit-jupiter</artifactId>
                    <version>4.5.1</version>
                    <scope>test</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <dependencies>
    
            <dependency>
                <groupId>org.assertj</groupId>
                <artifactId>assertj-core</artifactId>
                <version>3.22.0</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>io.github.classgraph</groupId>
                <artifactId>classgraph</artifactId>
                <version>4.8.146</version>
            </dependency>
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter</artifactId>
                <version>5.8.2</version>
            </dependency>
    
            <!-- JSON Unit - Dependencies -->
            <dependency>
                <groupId>net.javacrumbs.json-unit</groupId>
                <artifactId>json-unit-assertj</artifactId>
                <version>2.33.0</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.13.2.2</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.datatype</groupId>
                <artifactId>jackson-datatype-jsr310</artifactId>
                <version>2.13.2</version>
            </dependency>
    
            <!-- XML Unit - Dependencies -->
            <dependency>
                <groupId>org.xmlunit</groupId>
                <artifactId>xmlunit-assertj</artifactId>
                <version>2.9.0</version>
                <scope>test</scope>
            </dependency>
    
        </dependencies>
    </project>
    
    

    创建一个User

    public record User(String name, Integer age, Boolean blocked, LocalDate birthDate) {
    }
    

    测试

    测试用例命名最佳实践

    首先测试类名应该以Test结尾,测试用例名称最好遵从以下规则

    1. 测试名称应表达特定要求
    2. 测试名称应包含预期的输入或预期的结果
    3. 测试名称应以陈述的形式

    具体参考:https://osherove.com/blog/2005/4/3/naming-standards-for-unit-tests.html

    断言

    @Test
    @DisplayName("User should be at least 18")
    void user_should_be_at_least_18() {
        // junit5 的断言
        assertTrue(user.age() >= 18);
        // assertj 的断言
        assertThat(user.age()).isGreaterThanOrEqualTo(18);
    }
    

    显示名称

    测试类和测试方法可以声明自定义显示名称,可以使用空格、特殊字符、甚至emojis表情符号,这些名称会在runner和测试报告中显示。

    参数化测试

    参数化测试可以用不同的参数多次运行测试。它们和普通的@Test方法一样声明,但是使用@ParameterizedTest注解。还必须声明至少一个将为每次调用提供参数的来

    使用@ValueSource来指定参数来源

    它可以指定一个原生类型的数组,并且只能为每次调用提供一个参数

    @ParameterizedTest
    @ValueSource(ints = {20, 50, 80})
    void test_value_source(int age) {
        assertThat(age).isGreaterThanOrEqualTo(18);
    }
    
    
    

    读取CSV文件内容作为参数来源

    它可以让你使用classpath中的csv文件。csv文件中的每一行都会导致参数测试的一次调用

    src/test/resources/friends.csv

    name,age
    lisa,20
    hans,30
    hanna,40
    
    @ParameterizedTest
    @CsvFileSource(resources = "/friends.csv", numLinesToSkip = 1)
    void test_value_source_by_csv_file_source(String name, int age) {
        assertThat(age).isGreaterThanOrEqualTo(18);
    }
    

    标签

    我们可以给测试类或测试用例上面通过@Tag加标签,执行测试的时候可以指定标签,从而达到为测试用例分组的目的。
    下面就给测试类打上一个integration的标签

    @Tag("integration")
    class User01Test {
        // ...
    }
    

    可以使用如下命令来指定要执行的测试用例:

    mvn test -Dgroups="integration"
    

    左侧只执行了Running com.example.xxx.User01Test一个测试类,右侧则执行了3个

    总结

    本文介绍了如何使用Junit5写测试用例。

    参考

    1. Unit test naming best practices Unit test naming best practices - Stack Overflow
    2. https://osherove.com/blog/2005/4/3/naming-standards-for-unit-tests.html
    3. AssertJ Homepage https://assertj.github.io/doc/
    4. Gradle: https://stackoverflow.com/a/64986861
    5. https://junit.org/junit5/docs/current/user-guide/#running-tests-tag-expressions
    6. further reading
    7. JUnit 5 User Guide
    8. JUnit 5 中文文档 https://doczhcn.gitbook.io/junit5/
    9. AssertJ - fluent assertions java library
    10. Jupiter / JUnit 5 - Testcontainers
    11. awaitility/awaitility: Awaitility is a small Java DSL for synchronizing asynchronous operations (github.com)
  • 相关阅读:
    C# WinForm开发系列 Socket/WCF/Rometing/Web Services
    .net(c#) 简单的软件注册功能的实现:
    来自xici网友的Ubuntu和windows xp的Super PI性能测试
    最新的Linpack测试指南-基于woodcrest机器
    CFX x86_64 version issues 无法找到可执行文件
    如何检查一个mvapich的版本?
    Intel Tools Training Notes Intel Compiler, MKLs
    Infiniband IPoIB Debug FAQ
    让CFX的license server在开机的时候就自动启动
    FFTW 3.1.2 和 2.1.5编译
  • 原文地址:https://www.cnblogs.com/okokabcd/p/16475909.html
Copyright © 2020-2023  润新知