如何为ArchUnit规则设置违规数量阈值(无需Freeze-Store)
在老项目中给ArchUnit规则设置违规阈值(无需Freeze-Store)
ArchUnit原生没有直接的failThresholdAPI,但完全可以通过自定义逻辑实现你要的需求——允许历史遗留的N个违规存在,一旦新增违规导致总数超过阈值就触发测试失败,不用一次性整改所有旧问题。
两种实用实现方式
方式1:直接在测试里统计违规数
适合快速给单个规则加阈值控制:
// 先跑一次测试,把当前实际违规数设成阈值 private static final int MAX_ALLOWED_VIOLATIONS = 10; @ArchTest public void limit_something() { // 定义你的规则 ArchRule myRule = classes().should(/* 你的规则条件,比如accessClassesThat().resideInAPackage("..legacy..") */); // 执行规则并拿到结果 EvaluationResult result = myRule.evaluate(importedClasses); long actualViolations = result.getFailureReport().getNumberOfViolations(); // 只有超过阈值才失败 if (actualViolations > MAX_ALLOWED_VIOLATIONS) { Assertions.fail(String.format("违规数超标!当前:%d,最多允许:%d", actualViolations, MAX_ALLOWED_VIOLATIONS)); } }
方式2:封装通用工具方法(复用性强)
如果多个规则都要加阈值,封装个工具方法更方便:
// 通用阈值包装方法 private static <T extends ArchRule> T withThreshold(T rule, int maxAllowed) { return (T) ArchRuleDefinition.custom(description -> { EvaluationResult result = rule.evaluate(importedClasses); long violations = result.getFailureReport().getNumberOfViolations(); if (violations > maxAllowed) { return EvaluationResult.failed(result.getFailureReport()); } else { return EvaluationResult.passed(); } }).as(rule.getDescription()); } // 使用示例 @ArchTest public void limit_something = withThreshold( classes().should(/* 你的规则条件 */), 10 // 允许的最大违规数 );
关键注意点
- 第一次运行时,先看测试报告里的实际违规数,把阈值设成这个数,这样后续新增违规才会触发失败
- 测试仍会输出所有违规记录,方便你慢慢整改历史问题
- 每次整改完一批旧违规,记得同步降低阈值,保持对新代码的约束
内容的提问来源于stack exchange,提问作者René Jahn
相关产品推荐
相关产品推荐

