跳至主要內容

UT 覆盖与 Mock

大约 2 分钟

UT 覆盖与 Mock

1 前言

预备知识

  • UT: Unit Test 单元测试
  • TDD: Test-Driven Development 测试驱动开发
  • BDD: Behavior-Driven Development 行为驱动开发
  • ATDD: Acceptance Test Driven Development 验收测试驱动开发

像我们做算法题(codeforces, leetcode, nowcoder 等),都有输入输出用例。实际工程中,我们也需要引入 UT。一般业界使用覆盖率衡量 UT 的质量:

  • 语句覆盖: 程序中每一可执行语句至少执行一次
  • 判定(分支)覆盖: 程序中每个判定的"真"和"假"至少执行一次
  • 条件覆盖: 程序中每个判定的每个条件取得各种可能的结果
  • 判定/条件覆盖: 程序中每个判定的"真"和"假"至少执行一次,并且每个判定的每个条件取得各种可能的结果
  • 条件组合覆盖: 程序中所有判定的条件组合至少执行一次
  • 路径覆盖: 选择足够多的测试用例,使程序中每条路径至少执行一次

等价类:

  • 有效等价类: 是指对于程序的规格说明来说是合理的、有意义的输入数据构成的集合。利用有效等价类可检验程序是否实现了规格说明中所规定的功能和性能。
  • 无效等价类: 与有效等价类的定义恰巧相反。无效等价类指对程序的规格说明是不合理的或无意义的输入数据所构成的集合。对于具体的问题,无效等价类至少应有一个,也可能有多个。

2 maven 坐标

junit 已是事实上 java 的 UT 标准,当前趋势是从 junit4 向 junit5 过渡 。

junit4:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
</dependency>

junit5

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.8.2</version>
    <scope>test</scope>
</dependency>

笔者的一个基于 jdk17 + maven3.8 + junit5 + jacoco 的项目 leetcode-hub-javaopen in new window

3 Mockito, EasyMock, PowerMock

实际工程中,类和类之间会有依赖关系,A 类可能依赖 B、C、D 类的实现,B 类又可能依赖 E、F 类实现。

在测试类 A 的时候,我们可以预先设定 B、C、D 类的表现,这种手段称为 mock。大致可分为 录制-回放-验证 (record-replay-verify) 三个阶段

springboot 2 中(spring-boot-starter-test),选型了 Mockito

笔者的一个基于 Mockito 的项目 OpenYspideropen in new window

4 jacoco 覆盖率

pom.xml

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>${maven-surefire-plugin.version}</version>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>${maven-failsafe-plugin.version}</version>
        </plugin>

        <!-- https://www.baeldung.com/jacoco -->
        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>${jacoco-maven-plugin.version}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>prepare-agent</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

jacoco 聚合报告,pom.xml

<build>
    <plugins>
        <!-- https://www.baeldung.com/jacoco -->
        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>${jacoco-maven-plugin.version}</version>
            <executions>
                <execution>
                    <id>report</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>report-aggregate</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

(全文完)