这次迁移的特殊性
75000个测试类,不是小数目。Uber的处理方案有几个技术亮点:
1. OpenRewrite的自动化覆盖率
OpenRewrite自动处理了约85%的迁移工作:
# OpenRewrite JUnit4→JUnit5 转换规则
rewrite_coverage = {
"注解映射": {
"@Test (org.junit)": "@Test (org.junit.jupiter.api)",
"@Before": "@BeforeEach",
"@After": "@AfterEach",
"@BeforeClass": "@BeforeAll",
"@AfterClass": "@AfterAll",
"@Ignore": "@Disabled"
},
"断言转换": {
"assertThat(x).isEqualTo(y)": "assertEquals(y, x)",
"assertThat(x).isTrue()": "assertTrue(x)",
"assertThat(x).isFalse()": "assertFalse(x)"
},
"自动覆盖": 0.85 # 85%
}
2. Bazel双执行模式
# BUILD文件配置(简化)
load("@rules_junit5//junit5:defs.bzl", "junit5_test")
# JUnit 5测试
junit5_test(
name = "all_tests_j5",
srcs = glob(["**/*.java"]),
runtime = "@maven//:junit_jupiter",
deps = ["//src/main:myapp"]
)
# 原有JUnit 4测试保持
java_test(
name = "all_tests_j4",
srcs = glob(["**/*.java"]),
target = "//src/main:myapp"
)
# CI并行执行
# bazel test //tests:all_tests_j4 && bazel test //tests:all_tests_j5
3. 迁移效果数据
| 指标 | 迁移前 (JUnit4) | 迁移后 (JUnit5) |
|---|---|---|
| 测试并行度 | 60% | 95% |
| CI执行时间 | ~45min | ~22min |
| 断言风格 | Hamcrest | 内置断言 |
| 参数化测试 | @ParametersRunner | @ParameterizedTest |
开源复用的价值
Uber把OpenRewrite规则集开源了。任何使用Bazel的团队可以直接复用:
# 导入Uber的JUnit迁移规则(示例)
# 实际路径参考Uber开源项目
git clone https://github.com/uber/junit5-migration-rules
cd junit5-migration-rules
# 应用到自己的项目
rewrite openrewrite.yaml --source your-java-project/
给其他团队的参考
- 先做工具链:大版本迁移前,先投入时间做自动化
- 双版本并行:不要一次性切换,用并行验证降低风险
- 开源复用:先搜有没有现成工具,别重复造轮子
- 度量收益:把CI时间、并行度作为迁移效果的评估指标