Kotlin回归测试概述
回归测试,说白了就是「改完代码再跑一遍所有测试,确保没把老功能搞坏」。我刚开始接触Android项目时,总觉得回归测试浪费时间,心想「我就改了一行日志,不至于炸吧?」结果那次把支付模块的签名校验给误删了,提测后整个交易流程挂掉……嗯,从那以后我再也不敢忽视回归测试了。
回归测试的意义——为什么我们离不开它
你的项目迭代越快,改动面越大,回归测试的价值就越明显。它解决的核心问题只有一个:在持续集成和持续交付中,快速验证旧功能没有被新代码破坏。
- 避免回归缺陷:你改A模块,B模块被间接影响了——这种情况几乎每天都在发生。
- 降低修改成本:越早发现回归问题,修复成本越低。上线后再回滚,成本至少翻10倍。
- 给重构底气:没有回归测试支撑的重构,跟裸奔没什么区别。
- 提升团队信心:每次提交都能一键跑过回归用例,大家才敢放心合代码。
我个人的经验:以前做金融SDK,每次对接新的加密算法,我都会写一套回归测试套件,覆盖所有历史业务场景。哪怕新算法性能再好,回归没过我绝不合并。有一次正是因为回归测试发现了旧签名长度限制被改小,才避免了一次线上事故。
回归测试的常见类型
| 类型 | 范围 | 执行频率 | 适用场景 |
|---|---|---|---|
| 全量回归 | 整个项目测试用例 | 发布前 / 大重构后 | 版本大迭代、底层架构变更 |
| 增量回归 | 改动模块及关联模块 | 每次提交 | 日常开发、紧急热修复 |
| 冒烟回归 | 核心业务流程(20%) | 每日构建 | 快速验证可用性,确认主干未断 |
你想想看,如果每次改几行都要跑全量测试,开发效率肯定受不了。所以大多数团队会采用「增量回归为主 + 冒烟回归保底 + 全量回归兜底」的组合策略。
kotlin.test 库概览——Kotlin原生测试框架
提到Kotlin回归测试,你可能会先想到JUnit或TestNG。但Kotlin官方还提供了一个轻量但功能完备的测试库——kotlin.test。它直接集成在标准库中,无需额外依赖,语法更接近Kotlin惯用写法。
kotlin.test 的核心能力包括:
- 断言函数:
assertEquals、assertTrue、assertNotNull等,比Java的JUnit断言更简化。 - 注解支持:
@Test、@BeforeTest、@AfterTest,与JUnit 5风格类似但更原生。 - 期望异常:
assertFailsWith直观捕获特定异常。 - 忽略测试:
@Ignore标注暂时不跑的用例。 - 测试分组:通过
@Tag注解对用例分类,方便只跑特定子集。
小提示:kotlin.test 底层实际上是包装了JUnit平台。所以你可以在同一个项目里同时使用JUnit 5的高级特性和kotlin.test的简洁语法,两者互补。
看一个简单的回归测试例子
假设我们有一个计算折扣的函数,我们需要写一个回归测试来确保后续改动不会破坏原有逻辑。
// 目标函数:根据原价和会员等级计算折后价
fun calculateDiscount(price: Double, level: String): Double {
return when (level) {
"vip" -> price * 0.8
"svip" -> price * 0.65
else -> price
}
}
对应的回归测试用例:
import kotlin.test.*
class DiscountTest {
@Test
fun `普通用户无折扣`() {
val result = calculateDiscount(100.0, "normal")
assertEquals(100.0, result)
}
@Test
fun `VIP用户打8折`() {
val result = calculateDiscount(100.0, "vip")
assertEquals(80.0, result)
}
@Test
fun `SVIP用户打65折`() {
val result = calculateDiscount(100.0, "svip")
assertEquals(65.0, result)
}
}
这三个测试覆盖了所有分支。如果有人把折扣逻辑改成了「SVIP打6折」而忘记同步,第二个用例就会立刻失败——这就是回归测试的价值。
我曾经踩过的坑:一开始我习惯把所有断言写在一个@Test方法里,一旦前面的断言失败整个方法就跳出了,后面的回归场景根本测不到。后来我改成每个场景一个独立的@Test方法,这样即使某个场景失败,其他场景依然可以运行——排错效率高很多。
知识体系:Kotlin回归测试核心框架
下面这张图梳理了回归测试和kotlin.test库的关系。你可以把它作为章节地图,后面所有的技巧都会围绕着几个核心节点展开。
什么时候该把回归测试纳入流程?
我认为有一条比较实用的判断标准:当你的项目有了3个以上开发者,或者迭代周期短于1周时,手动回归就已经不可靠了。这时候需要开始建立自动化的回归测试体系,而kotlin.test就是零成本起步的选择。
另外,如果你的项目使用了Gradle多模块构建,可以在每个模块下都建一个src/test/kotlin目录,按模块粒度组织回归测试。跑的时候用./gradlew test --tests "*.DiscountTest"就能只跑指定用例,非常方便。
总结一下本章核心要点:
- 回归测试的价值在于「快速发现改坏的老功能」。
- 三种策略(全量/增量/冒烟)各有适用场景,实际项目中混合使用。
- kotlin.test 是 Kotlin 官方原生测试库,语法简洁,可直接用于回归测试。
- 在 CI/CD 中接入 kotlin.test,每次提交自动运行回归用例,是防止退化的最佳实践。