Jorgen's blog Jorgen's blog
首页
  • 平台架构
  • 混合式开发记录
  • 推送服务
  • 数据分析
  • 实时调度
  • 架构思想

    • 分布式
  • 编程框架工具

    • 编程语言
    • 框架
    • 开发工具
  • 数据存储与处理

    • 数据库
    • 大数据
  • 消息、缓存与搜索

    • 消息队列
    • 搜索与日志分析
  • 前端与跨端开发

    • 前端技术
    • Android
  • 系统与运维

    • 操作系统
    • 容器化与 DevOps
  • 物联网与安全

    • 通信协议
    • 安全
    • 云平台
newland
  • 关于我
  • 终身学习
  • 关于时间的感悟
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

jorgen

Love it, make mistakes, learn, keep grinding.
首页
  • 平台架构
  • 混合式开发记录
  • 推送服务
  • 数据分析
  • 实时调度
  • 架构思想

    • 分布式
  • 编程框架工具

    • 编程语言
    • 框架
    • 开发工具
  • 数据存储与处理

    • 数据库
    • 大数据
  • 消息、缓存与搜索

    • 消息队列
    • 搜索与日志分析
  • 前端与跨端开发

    • 前端技术
    • Android
  • 系统与运维

    • 操作系统
    • 容器化与 DevOps
  • 物联网与安全

    • 通信协议
    • 安全
    • 云平台
newland
  • 关于我
  • 终身学习
  • 关于时间的感悟
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Capacitor浅析
  • ADB调试
  • mlkit
  • face detection
  • Android中的Kotlin协程:告别回调地狱
  • Android性能优化实践与技巧
  • Android Jetpack Compose入门:构建现代UI的全新方式
  • Android Jetpack Compose入门与实践 - 构建现代Android UI
  • Android Jetpack Compose入门指南 - 构建现代UI的全新方式
  • Android Jetpack与架构组件-构建现代化应用
  • Android Jetpack架构组件:ViewModel与LiveData实战指南
  • Android Jetpack组件:构建现代Android应用的核心利器
  • Android Jetpack组件详解:构建现代化应用的核心
  • Android数据绑定与MVVM架构-构建现代化应用
  • Android架构组件:构建现代化应用的基石
  • Android架构组件与Jetpack-构建现代化应用的基石
  • Android架构组件与Jetpack-构建现代化应用的基础
  • Android架构设计之MVVM模式实战指南
  • 拥抱未来:Android Jetpack Compose入门指南
  • Android权限管理完全指南-从基础到实践
  • Android测试指南-从单元测试到UI测试的实践之路
    • 前言
    • Android测试体系概览
      • 1. 本地测试(Local Tests)
      • 2. 仪器化测试(Instrumented Tests)
    • 单元测试:打好基础
      • 测试框架选择
      • 实战示例:测试ViewModel
    • 集成测试:组件协作
      • 测试用例场景
      • 实战示例:测试数据流
    • UI测试:真实用户视角
      • Espresso核心组件
      • 实战示例:登录流程测试
    • 测试最佳实践
      • 1. 测试金字塔
      • 2. 测试命名规范
      • 3. 测试覆盖率目标
    • 结语
    • 个人建议
  • Android依赖注入实战:从Dagger到Hilt的进化之路
  • Android网络编程完全指南-从HTTP到Retrofit的实践之路
  • Android数据持久化完全指南-从SharedPreferences到Room数据库
  • Android多线程与并发处理完全指南-从Thread到协程的进阶之路
  • Android应用打包与发布全流程指南-从签名到上架的实战之路
  • Android安全完全指南-从基础防护到高级加密的实战之路
  • android
Jorgen
2023-10-15
目录

Android测试指南-从单元测试到UI测试的实践之路

# 前言

在Android开发的世界里,我们总是忙着实现酷炫的UI和复杂的功能逻辑,却常常忽略了一个至关重要的环节——测试。测试?那是产品经理该关心的事吧? 😅

实际上,完善的测试体系不仅能保证代码质量,还能大幅减少线上bug,让我们的应用在用户手中更稳定可靠。今天,我们就来聊聊Android测试的那些事儿,从单元测试到UI测试,带你构建全方位的测试防护网!

提示

"测试是代码质量的守护者,而不是开发流程的绊脚石。" —— 来自一个被测试救过无数次的程序员

# Android测试体系概览

Android测试主要分为两大阵营:

# 1. 本地测试(Local Tests)

  • 单元测试:测试独立组件(如ViewModel、Repository)
  • 集成测试:测试组件间的交互

# 2. 仪器化测试(Instrumented Tests)

  • UI测试:测试用户界面交互(使用Espresso)
  • 端到端测试:模拟真实用户操作流程

# 单元测试:打好基础

单元测试是测试金字塔的基石,专注于验证代码中最小可测试单元的正确性。

# 测试框架选择

  • JUnit:Java/Kotlin标准测试框架
  • Mockito:创建模拟对象,隔离依赖
  • Kotlin Coroutines Test:协程测试支持

# 实战示例:测试ViewModel

// 测试文件:UserProfileViewModelTest.kt
class UserProfileViewModelTest {
    private lateinit var viewModel: UserProfileViewModel
    private val repository: UserRepository = mock()

    @Before
    fun setup() {
        viewModel = UserProfileViewModel(repository)
    }

    @Test
    fun `loadUser should update user profile`() = runTest {
        // 准备
        val userId = "123"
        val expectedUser = User(id = userId, name = "Jorgen")
        whenever(repository.getUser(userId)).thenReturn(expectedUser)

        // 执行
        viewModel.loadUser(userId)

        // 验证
        assertEquals(expectedUser, viewModel.userProfile.value)
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

THEOREM

单元测试的黄金法则:测试应该快速、独立、可重复,且不依赖外部资源。

# 集成测试:组件协作

当多个组件需要协同工作时,集成测试就派上用场了。

# 测试用例场景

  • Repository与Room数据库交互
  • ViewModel与Repository的数据流
  • 多个ViewModel之间的通信

# 实战示例:测试数据流

// 测试文件:UserRepositoryIntegrationTest.kt
class UserRepositoryIntegrationTest {
    private lateinit var database: AppDatabase
    private lateinit var repository: UserRepository

    @Before
    fun setup() {
        database = Room.inMemoryDatabaseBuilder(
            ApplicationProvider.getApplicationContext(),
            AppDatabase::class.java
        ).allowMainThreadQueries().build()
        
        repository = UserRepository(database.userDao())
    }

    @After
    fun tearDown() {
        database.close()
    }

    @Test
    fun `insertUser should persist user`() = runTest {
        // 准备
        val user = User(name = "Test User")
        
        // 执行
        repository.insertUser(user)
        
        // 验证
        val savedUser = repository.getUser(user.id)
        assertEquals(user.name, savedUser?.name)
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# UI测试:真实用户视角

UI测试使用Espresso框架模拟用户操作,验证界面行为是否符合预期。

# Espresso核心组件

  • ViewMatchers:查找UI元素
  • ViewActions:执行用户操作
  • ViewAssertions:验证UI状态

# 实战示例:登录流程测试

// 测试文件:LoginActivityTest.kt
@RunWith(AndroidJUnit4::class)
class LoginActivityTest {
    @Rule
    @JvmField
    val activityRule = ActivityTestRule(LoginActivity::class.java)

    @Test
    fun loginSuccess() {
        // 输入用户名和密码
        onView(withId(R.id.et_username)).perform(typeText("validUser"))
        onView(withId(R.id.et_password)).perform(typeText("password123"))
        
        // 点击登录按钮
        onView(withId(R.id.btn_login)).perform(click())
        
        // 验证跳转到主界面
        onView(withId(R.id.main_activity)).check(matches(isDisplayed()))
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

提示

UI测试的秘诀:保持测试简单,只测试关键用户流程,避免过度实现细节。

# 测试最佳实践

# 1. 测试金字塔

        /\
       /  \
      /____\
     /      \
    /________\
  E2E   集成   单元
1
2
3
4
5
6
  • 底层:大量单元测试(70%)
  • 中层:适量集成测试(20%)
  • 顶层:少量端到端测试(10%)

# 2. 测试命名规范

使用BDD风格命名:"given when then"格式

@Test
fun `when user enters invalid credentials then show error message`() {
    // given
    // when
    // then
}
1
2
3
4
5
6

# 3. 测试覆盖率目标

  • 核心业务逻辑:≥80%
  • 工具类:≥70%
  • UI交互:关键流程≥60%

# 结语

在Android开发的征途上,测试不是负担,而是我们的安全带和导航仪。通过单元测试确保代码质量,通过集成测试验证组件协作,通过UI测试保障用户体验,我们才能构建出真正可靠的应用。

"优秀的测试不是开发流程的终点,而是代码质量的起点。" —— 某位不愿透露姓名的测试工程师

从今天开始,给你的项目添加测试吧!哪怕从简单的单元测试开始,也是迈向高质量代码的重要一步。毕竟,谁不想成为那个写出零bug代码的传奇开发者呢?🚀

# 个人建议

  1. 循序渐进:先为核心业务逻辑添加单元测试,再逐步扩展
  2. 测试驱动:尝试TDD开发模式,先写测试再实现功能
  3. 持续集成:在CI/CD流程中加入测试检查,确保代码质量
  4. 定期重构:利用测试安全地重构代码,保持架构健康

记住:测试不是开发者的敌人,而是质量的守护者! 🛡️

#Android测试#单元测试#Espresso#Mockito
上次更新: 2026/01/28, 15:36:58
Android权限管理完全指南-从基础到实践
Android依赖注入实战:从Dagger到Hilt的进化之路

← Android权限管理完全指南-从基础到实践 Android依赖注入实战:从Dagger到Hilt的进化之路→

最近更新
01
LLM
01-30
02
intro
01-30
03
intro
01-30
更多文章>
Theme by Vdoing | Copyright © 2019-2026 Jorgen | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式