升级JUnit5与Pitest1.6.0后POJO校验测试失败解决方案咨询
问题根因
Pitest从1.4.0升级到1.6.0后修改了字节码插桩实现,会在被变异的目标类中注入private static transient int $$pitCoverageProbeSize字段,用于存储覆盖率探针计数。当前使用的POJO结构校验逻辑没有过滤这类字节码工具注入的非业务字段,这个原始int类型的插桩字段刚好触发了NoPrimitivesRule禁止原始类型字段的校验规则,最终导致变异测试执行失败。
普通单元测试运行时不会触发Pitest的字节码插桩流程,因此常规测试可以全部通过,只有执行变异测试时才会出现该报错。
解决方案
任选一种方案即可修复:
- 方案1:在POJO扫描阶段过滤Pitest注入字段
修改获取POJO类集合的过滤逻辑,在加载类后直接剔除Pitest生成的探针字段,示例代码:pojoClasses = PojoClassFactory.getPojoClassesRecursively(POJO_PACKAGE, pojoClass -> { // 保留原有仅扫描Dto类的规则 if (!pojoClass.getName().endsWith("Dto")) { return false; } // 移除所有Pitest注入的探针字段,不纳入校验范围 pojoClass.getPojoFields().removeIf(field -> field.getName().startsWith("$$pit")); return true; }); - 方案2:新增全局合成字段过滤规则
Pitest注入的字段属于字节码工具生成的合成(synthetic)字段,本身不属于业务POJO的自有字段,本就不该纳入结构校验。可以在校验器中新增前置规则,统一过滤所有合成字段:// 优先添加合成字段过滤规则 pojoValidator.addRule(pojoClass -> { pojoClass.getPojoFields().removeIf(PojoField::isSynthetic); }); // 后续再添加原有的NoPublicFieldsRule、NoPrimitivesRule等业务校验规则 pojoValidator.addRule(new NoPublicFieldsRule()); pojoValidator.addRule(new NoPrimitivesRule()); // ...其余原有规则和Tester保持不变 - 方案3:关闭Pitest探针插桩(不推荐)
可在Pitest插件配置中添加参数关闭覆盖率探针插桩,但该操作会导致变异覆盖率统计失效,仅适合临时排查问题使用,不建议作为长期方案。
内容的提问来源于stack exchange,提问作者Rain03
相关产品推荐
相关产品推荐

