一、定位未覆盖的代码
-  
利用 IDEA 的覆盖率工具:
- 右键测试类 → Run with Coverage,或使用 
Alt+Shift+F10(Windows)打开运行菜单选择覆盖率。 - 查看高亮标记: 
- 绿色:已覆盖代码行。
 - 红色:未覆盖代码行。
 - 黄色:部分覆盖(如条件分支未完全覆盖)。
 
 
https://via.placeholder.com/600x400?text=IDEA+Coverage+Highlight
 - 右键测试类 → Run with Coverage,或使用 
 -  
分析 JaCoCo 报告:
- 打开 
target/site/jacoco/index.html,查看:- 行覆盖率(Line):哪些行未执行?
 - 分支覆盖率(Branch):哪些条件分支(如 
if/else)未覆盖? - 方法覆盖率:是否有未调用的方法?
 
 
 - 打开 
 
二、针对性提升覆盖率的策略
策略 1:覆盖边界条件
- 示例场景:一个计算器类的方法 
divide(int a, int b)。public int divide(int a, int b) {if (b == 0) throw new IllegalArgumentException("除数不能为0");return a / b; } - 问题:常规测试可能只覆盖 
b≠0的情况,遗漏了异常分支。 - 解决方案: 
@Test void testDivideByZero() {Calculator calculator = new Calculator();assertThrows(IllegalArgumentException.class, () -> calculator.divide(5, 0)); } 
策略 2:覆盖所有代码分支
- 示例场景:带有 
if-else的逻辑。public String getGrade(int score) {if (score >= 90) return "A";else if (score >= 60) return "B";else return "C"; } - 问题:若仅测试 
score=80,则未覆盖score≥90和score<60的分支。 - 解决方案:使用参数化测试覆盖所有分支: 
@ParameterizedTest @CsvSource({"95, A", "75, B", "50, C"}) void testGetGrade(int score, String expected) {assertEquals(expected, grader.getGrade(score)); } 
策略 3:覆盖异常和错误处理
- 示例场景:数据库操作失败时的回滚逻辑。 
public void saveData(Data data) {try {database.insert(data);} catch (SQLException e) {logger.error("保存失败", e);rollback();} } - 问题:正常流程测试不会触发 
catch块。 - 解决方案:使用 Mockito 模拟异常: 
@Test void testSaveDataFailure() {Database mockDb = mock(Database.class);when(mockDb.insert(any())).thenThrow(new SQLException());DataService service = new DataService(mockDb);service.saveData(new Data());verify(mockDb).rollback(); // 验证是否执行了回滚 } 
策略 4:覆盖工具生成的代码
- 常见问题:Lombok 生成的 
getter/setter、equals/hashCode或 IDE 自动生成的代码未覆盖。 - 解决方案: 
- 显式测试生成的代码(如验证 
equals方法)。 - 配置 JaCoCo 忽略 Lombok 生成的代码(在 
pom.xml中):<configuration><excludes><exclude>**/*$Lombok*/**</exclude></excludes> </configuration> 
 - 显式测试生成的代码(如验证 
 
三、高级技巧
技巧 1:强制覆盖难以触发的代码
- 场景:测试 
private方法或静态代码块。public class ConfigLoader {static {loadConfig(); // 静态代码块}private static void loadConfig() { /* 加载配置 */ } } - 解决方案:通过反射调用私有方法或触发静态初始化: 
@Test void testStaticBlock() throws Exception {Class.forName("com.example.ConfigLoader"); // 触发静态代码块 } 
技巧 2:优化测试数据
- 使用随机测试工具:如 
QuickTheories或jqwik,生成大量随机输入覆盖边缘情况。@Property void testRandomInput(@ForAll int a, @ForAll int b) {assumeTrue(b != 0); // 忽略 b=0 的情况assertEquals(a / b, calculator.divide(a, b)); } 
技巧 3:忽略无需覆盖的代码
- 配置 JaCoCo 排除(在 
pom.xml中):<excludes><exclude>**/model/*.java</exclude> // 忽略 POJO 类<exclude>**/Main.java</exclude> // 忽略启动类 </excludes> 
四、避免常见误区
-  
盲目追求 100% 覆盖率:
- 某些代码(如自动生成的代码、简单 Getter)无需强制覆盖。
 - 更关注核心逻辑和复杂分支的覆盖。
 
 -  
编写无效测试:
@Test void testAdd() {calculator.add(2, 3); // 没有断言!看似覆盖,实则无效 } -  
忽略测试代码质量:
- 避免重复代码:用 
@BeforeEach初始化公共对象。 - 遵循命名规范:测试方法名应明确表达场景(如 
testDivide_WhenDivisorIsZero_ThrowException)。 
 - 避免重复代码:用 
 
五、总结
通过以下步骤系统提升覆盖率:
- 定位未覆盖代码:使用 IDEA 高亮和 JaCoCo 报告。
 - 设计针对性用例:覆盖边界条件、异常分支、复杂逻辑。
 - 利用工具和技巧:参数化测试、Mock 异常、反射调用。
 - 平衡覆盖率和成本:优先覆盖关键代码,忽略无关部分。