SBT/Scala 按分组顺序执行测试及解决测试报告覆盖的配置
解决方案
两个可落地的实现方向,全部基于SBT原生能力,无需引入第三方插件:
方案1:build.sbt配置分组顺序执行,同组保留并行能力
通过SBT原生的测试分组机制实现,完全对齐当前的测试筛选规则,同组继承原有并行配置,无额外性能损耗,测试报告自动统一写入默认路径,不会出现覆盖问题。
在根项目的build.sbt中添加如下配置,多项目场景下通过ThisBuild作用域即可自动传递给所有子项目:
ThisBuild / Test / groups := Seq( // 第一执行组:所有带attributeX标签的测试 Tests.Group( name = "attributeX-tagged", runPolicy = Tests.SubProcess(ForkOptions().withRunJVMOptions((Test / javaOptions).value)), // 注入标签过滤规则,和testOnly -n attributeX逻辑一致 tag = Some(Tests.TaggedFilter(includeTags = Set("attributeX"))), filter = Tests.Filter(_ => true) ), // 第二执行组:所有不带attributeX标签的测试 Tests.Group( name = "non-attributeX-tagged", runPolicy = Tests.SubProcess(ForkOptions().withRunJVMOptions((Test / javaOptions).value)), // 注入标签过滤规则,和testOnly -l attributeX逻辑一致 tag = Some(Tests.TaggedFilter(excludeTags = Set("attributeX"))), filter = Tests.Filter(_ => true) ) ) // 强制指定组执行顺序:先跑带标签的组,完成后再跑不带标签的组 ThisBuild / Test / testGroupingOrder := { allGroups => allGroups.sortBy(_.name match { case "attributeX-tagged" => 0 case "non-attributeX-tagged" => 1 }) }
配置完成后直接执行sbt test即可:
- 组间严格串行,第一批次所有测试执行完成后,才会启动第二批次
- 同组内完全沿用原有并行、fork执行配置,和之前单独跑的性能一致
- 两批次的测试结果会自动写入同一套XML报告文件,不会出现覆盖问题
方案2:分批次执行时独立输出报告,最后合并结果
如果不想调整现有分组配置,保留两次手动执行测试命令的流程,可以通过自定义报告输出路径隔离两个批次的结果,最后统一合并:
- 第一批次执行测试时,指定独立的XML报告输出路径,和默认路径隔离,避免被后续执行覆盖
sbt testOnly -- -n attributeX -u target/tagged-test-reports - 第二批次执行测试时,同样指定独立的报告输出路径
sbt testOnly -- -l attributeX -u target/non-tagged-test-reports - 在build.sbt中添加简单的自定义拷贝任务,把两个目录下的报告统一合并到CI默认扫描的路径
val mergeTestReports = taskKey[Unit]("合并两批次测试报告") mergeTestReports := { val finalReportDir = target.value / "test-reports" IO.copyDirectory(target.value / "tagged-test-reports", finalReportDir, overwrite = true) IO.copyDirectory(target.value / "non-tagged-test-reports", finalReportDir, overwrite = true) }
两批次测试跑完后,执行sbt mergeTestReports即可完成合并。由于XML测试报告的文件名以测试类名为核心标识,两个批次的测试类无重名,拷贝后的报告可以被所有支持JUnit XML格式的CI工具正常解析,无需额外转换。
内容的提问来源于stack exchange,提问作者Josjr87
相关产品推荐
相关产品推荐

