JaCoCo案例

wen java案例 1

本文目录导读:

JaCoCo案例

  1. 案例一:基础分支覆盖(Branch Coverage)—— 最经典的“坑”
  2. 案例二:条件覆盖(Conditional Coverage)—— 短路运算的陷阱
  3. 案例三:Maven集成与构建门槛(CI/CD实战)
  4. 实战技巧(针对上述案例)
  5. 如果你想看真实项目截图效果

关于JaCoCo(Java Code Coverage)的案例,我无法提供真实的公司内部项目代码,但我可以为你构建几个经典的、具有代表性的模拟案例场景,这些场景涵盖了JaCoCo最常见的应用方式,你可以直接运行这些代码来观察覆盖率的变化。

以下是三个核心场景的实战案例:


基础分支覆盖(Branch Coverage)—— 最经典的“坑”

场景描述checkAge 方法用于校验年龄,开发者认为写了一个完整的测试,但实际上漏掉了隐藏的分支。

代码准备

public class AgeValidator {
    public static String checkAge(int age) {
        if (age < 0) {
            throw new IllegalArgumentException("Age cannot be negative");
        } else if (age < 18) {
            return "Minor";
        } else if (age < 65) {
            return "Adult";
        } else {
            return "Senior";
        }
    }
}

测试代码(故意不全面):

import org.junit.Test;
import static org.junit.Assert.*;
public class AgeValidatorTest {
    @Test
    public void testAdult() {
        assertEquals("Adult", AgeValidator.checkAge(30));
    }
    @Test
    public void testMinor() {
        assertEquals("Minor", AgeValidator.checkAge(10));
    }
}

JaCoCo分析结果

  • 行覆盖率(Line Coverage):可能达到 75%(4个return语句执行了3个)。
  • 分支覆盖率(Branch Coverage):可能只有 50%age < 0 的 True 分支和 age < 65 的 False 分支没走)。
  • 如果CI配置了 <rule><element>BRANCH</element><limits><limit counter="BRANCH" value="COVEREDRATIO" minimum="0.80"/></limits></rule>,这个构建会失败

改进建议:增加测试用例 AgeValidator.checkAge(-1)(抛异常)和 AgeValidator.checkAge(70)(Senior),覆盖率才会达标。


条件覆盖(Conditional Coverage)—— 短路运算的陷阱

场景描述isValidUser 方法使用了 && 短路逻辑,测试只测了“正常通过”和“完全不通过”,忽略了中间的短路情况。

代码准备

public class UserValidator {
    public boolean isValidUser(String username, String password) {
        return username != null && !username.isEmpty()
                && password != null && password.length() >= 8;
    }
}

测试代码

import org.junit.Test;
import static org.junit.Assert.*;
public class UserValidatorTest {
    @Test
    public void testValid() {
        UserValidator validator = new UserValidator();
        assertTrue(validator.isValidUser("john", "password123"));
    }
    @Test
    public void testNullUsername() {
        UserValidator validator = new UserValidator();
        assertFalse(validator.isValidUser(null, "password123"));
    }
}

JaCoCo分析结果

  • 行覆盖率100%(单行代码全执行了)。
  • 条件覆盖率(分支覆盖)50%,因为对于第一个条件 username != null,测试只覆盖了 False(null)和 True(非null);但对于第二个条件 !username.isEmpty(),由于短路,null 场景没走到那一步,导致该条件的 TrueFalse 分支只覆盖了其中一个。
  • 教训:行率100%不代表逻辑测试完善,JaCoCo红色菱形(分支/条件)会明确提示这里有问题。

Maven集成与构建门槛(CI/CD实战)

场景描述:在pom.xml中配置JaCoCo插件,并设定覆盖率红线(行覆盖率低于80%则构建失败)。

核心配置pom.xml 片段):

<build>
    <plugins>
        <!-- JaCoCo Maven Plugin -->
        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>0.8.11</version>
            <executions>
                <execution>
                    <goals>
                        <goal>prepare-agent</goal> <!-- 生成覆盖率数据文件 -->
                    </goals>
                </execution>
                <execution>
                    <id>report</id>
                    <phase>test</phase>
                    <goals>
                        <goal>report</goal> <!-- 生成HTML报告 -->
                    </goals>
                </execution>
                <execution>
                    <id>check</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>check</goal> <!-- 执行覆盖率检查 -->
                    </goals>
                    <configuration>
                        <rules>
                            <rule>
                                <element>BUNDLE</element>
                                <limits>
                                    <limit>
                                        <counter>LINE</counter>
                                        <value>COVEREDRATIO</value>
                                        <minimum>0.80</minimum> <!-- 行覆盖不低于80% -->
                                    </limit>
                                    <limit>
                                        <counter>BRANCH</counter>
                                        <value>COVEREDRATIO</value>
                                        <minimum>0.70</minimum> <!-- 分支覆盖不低于70% -->
                                    </limit>
                                </limits>
                            </rule>
                        </rules>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

执行命令

mvn clean verify

案例效果

  • 运行测试后,在 target/site/jacoco/index.html 生成报告(红色/绿色/黄色的类)。
  • 如果测试覆盖率不达标,verify 阶段直接 BUILD FAILURE,阻止CI发布。

实战技巧(针对上述案例)

  1. 查看报告:打开 target/site/jacoco/index.html,点击具体的类。
    • 绿色:已覆盖。
    • 红色:未覆盖的行。
    • 黄色/菱形:部分覆盖的分支(需要双击查看具体是哪个条件没测到)。
  2. 故意漏测:尝试注释掉某个测试方法,再跑一次 mvn test,观察覆盖率数值变化,理解测试对覆盖率的贡献。

如果你想看真实项目截图效果

你可以快速在本地跑一个 Spring Boot 项目,添加 spring-boot-starter-test(自带JaCoCo),然后故意不写某个Service的测试,生成报告后你会看到:

  • DAO/Mapper 层(接口)通常覆盖率为0%。
  • Controller 层如果没有集成测试,覆盖率为0%。
  • Service 层如果只测了主流程,分支覆盖率会亮红灯。

如果你需要,我可以为你生成一份具体的HTML报告截图样张(模拟数据),或者帮你写一个多模块项目的集成配置,你想深入哪个部分?

抱歉,评论功能暂时关闭!