第七篇:进阶篇 —— 工程化与质量保障 第14章 自动化测试:构筑代码质量的防火墙
2026/6/18 7:07:49 网站建设 项目流程

第七篇:进阶篇 —— 工程化与质量保障

第14章 自动化测试:构筑代码质量的防火墙

在第十三章,我们通过 Profiler 优化了 App 的性能。但如果我们改了一行代码,修复了一个 Bug,却不小心引入了三个新 Bug 怎么办?靠人工点点点测试,在 2026 年是低效且不可靠的。

自动化测试是专业开发者的护城河。它是一张安全网,让你敢于重构代码、升级依赖、添加新功能,而无需担心把 App 搞崩。

本章将带你构建三层测试体系:单元测试(Unit Test)集成测试(Integration Test)UI 测试(UI Test)。我们将使用 2026 年最新的测试栈:JUnit 5 + MockK + Turbine + Compose UI Test。我们将深入测试的哲学、Mock 的底层原理、以及如何测试 Kotlin 协程和 Flow。

14.1 测试金字塔:你应该写哪些测试?(深度解析)

并不是测试越多越好,而是要分层。

测试类型占比速度成本关注点2026年工具栈
UI 测试10%模拟用户操作,验证界面流程(如:点击登录按钮是否跳转到主页)。Compose UI Test
集成测试20%验证模块协作(如:ViewModel 调用 Repository 是否能拿到数据)。Hilt + Robolectric
单元测试70%极快验证最小功能单元(如:一个工具函数、一个 ViewModel 的状态计算)。JUnit 5 + MockK + Turbine

核心原则:测试应该是快速的。如果你跑一次测试需要 5 分钟,没人会跑。

14.1.1 为什么是 70/20/10?
  • 单元测试(70%):最便宜,最快。它们不依赖 Android 框架,直接在 JVM 上运行。你应该为每一个业务逻辑类编写单元测试。
  • 集成测试(20%):验证组件之间的交互。例如,ViewModel 是否正确调用了 Repository,数据库是否正确保存了数据。
  • UI 测试(10%):最昂贵,最慢。它们运行在真机或模拟器上,模拟真实用户操作。只为核心业务流程编写 UI 测试。

14.2 单元测试:JUnit 5 与 MockK(深度解析)

单元测试是针对纯 Kotlin 代码的测试,不依赖 Android 设备,直接在 JVM 上运行。

14.2.1 配置测试环境(深度解析)
// build.gradle.kts (App)dependencies{// JUnit 5 (Jupiter)testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")testRuntimeOnly("org.junit.platform:junit-platform-launcher")// MockK (Kotlin 专用 Mock 框架,替代 Mockito)testImplementation("io.mockk:mockk:1.13.9")// Turbine (测试 Flow 的神器)testImplementation("app.cash.turbine:turbine:1.0.0")// 测试协程testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0")}
14.2.2 JUnit 5 注解详解(深度解析)
注解作用示例
@Test标记一个测试方法@Test fun addition_isCorrect()
@BeforeEach每个测试方法前执行@BeforeEach fun setup()
@AfterEach每个测试方法后执行@AfterEach fun tearDown()
@BeforeAll所有测试方法前执行一次@BeforeAll companion object { ... }
@AfterAll所有测试方法后执行一次@AfterAll companion object { ... }
@DisplayName测试显示名称@DisplayName("加法测试")
@Nested嵌套测试类@Nested inner class AdditionTests
@Timeout超时测试@Timeout(1, unit = TimeUnit.SECONDS)
14.2.3 测试一个简单的工具类(深度实战)

假设我们有一个StringUtils.kt

// utils/StringUtils.ktobjectStringUtils{funisValidEmail(email:String):Boolean{returnemail.contains("@")&&email.contains(".")}funformatPrice(price:Double):String{return${String.format("%.2f",price)}"}}

编写测试:

// test/java/com/example/myfirstapp/utils/StringUtilsTest.ktimportorg.junit.jupiter.api.Assertions.assertFalseimportorg.junit.jupiter.api.Assertions.assertTrueimportorg.junit.jupiter.api.DisplayNameimportorg.junit.jupiter.api.TestclassStringUtilsTest{@Test@DisplayName("Valid email should return true")fun`isValidEmail returns true for valid email`(){// Givenvalemail="test@example.com"// Whenvalresult=StringUtils.isValidEmail(email)// ThenassertTrue(result)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询