Plaid测试金字塔:单元测试、Robolectric集成测试与Espresso实战详解

发布时间:2026/9/19 13:47:45
Plaid测试金字塔:单元测试、Robolectric集成测试与Espresso实战详解 Plaid测试金字塔单元测试、Robolectric集成测试与Espresso实战详解【免费下载链接】plaidAn Android app which provides design news inspiration as well as being an example of implementing material design.项目地址: https://gitcode.com/gh_mirrors/pl/plaidPlaid 是一款开源的 Android 设计资讯应用聚合 DesignerNews、Dribbble 与 ProductHunt 的设计新闻同时是 Google 官方的 Material Design 实战范例。本文带你拆解 Plaid 的测试金字塔如何用JUnit 单元测试测试 ViewModel、如何搭建集成测试含 Robolectric 思路对比、以及如何用Espresso做 UI 自动化测试。新手跟着看就能在自己项目里复刻一套完整的 Android 测试体系。 一、先看全局Plaid 的测试金字塔长什么样测试金字塔的核心思想单元测试最多最快UI 测试最少最慢。Plaid 作为 MVVM 架构ViewModel LiveData 协程 Room Dagger的典范把三层测试清晰映射到了 Gradle 的目录约定中测试层源码目录核心工具运行位置单元测试src/test/JUnit 4、Mockito、kotlinx-coroutines-testJVM秒级反馈集成测试src/androidTest/AndroidJUnit4、Room 内存数据库真机 / 模拟器UI 测试src/androidTest/Espresso、UiAutomator真机 / 模拟器全部测试依赖集中在根目录的 test_dependencies.gradle 中统一管理版本一览依赖版本用途junit4.12测试框架mockito / mockito-kotlin2.23.0 / 2.0.0-RC3依赖打桩espresso-core / espresso-contrib3.1.0-beta02UI 自动化androidx.test (runner / rules / ext-junit)1.1.0 / 1.1.0-beta02仪器化测试基础设施kotlinx-coroutines-test1.3.0协程调度控制 值得学习的工程细节每个功能模块app、core、designernews、dribbble、search、about都各自带test与androidTest目录测试随代码走而不是堆在某个集中目录。⚡ 二、单元测试Mockito 协程 Rule 测试 ViewModel单元测试是金字塔的底座。以 HomeViewModelTest.kt 为例Plaid 有一套非常可复用的“三件套”// 1) 替换主线程协程调度器让协程在测试中同步可控 get:Rule var coroutinesRule MainCoroutineRule() // 2) 让 Architecture Components 的任务在当前线程执行 get:Rule var instantTaskExecutorRule InstantTaskExecutorRule() // 3) 用 mock() 打桩所有外部依赖 private val dataManager: DataManager mock() private val loginRepository: LoginRepository mock()对应源码见 HomeViewModelTest.kt#L66-L76。测试用例本身遵循Given-When-Then注释范式例如验证退出登录逻辑HomeViewModelTest.kt#L92-L101Given构造一个 ViewModelWhen调用logoutFromDesignerNews()Thenverify(loginRepository).logout()验证仓库被正确调用配套技巧MockitoKotlinHelpers.kt 里封装了capture()与argumentCaptorT()两个 Kotlin 扩展规避了 Mockito 泛型 API 在 Kotlin 中的繁琐写法而capture的返回值被处理为可空类型避免 Mockito 返回 null 时抛IllegalStateException——这种“为 Kotlin 修 Java API 毛刺”的写法很值得借鉴。新手要点清单✅被测类只 mock 依赖不 mock 被测对象用whenever(...).thenReturn(...)打桩输入用verify(...)断言输出每个测试只验证一件事方法名写成行为描述如isDesignerNewsLoggedIn 三、集成测试Plaid 的真机方案与 Robolectric 思路提到 Android 集成测试很多人第一反应是Robolectric——在 JVM 上模拟 Android API无需设备即可运行。Plaid 的选择略有不同它的集成测试放在src/androidTest/以仪器化测试形式在真机/模拟器上运行用AndroidJUnit4跑数据库、SharedPreferences 等真实组件。典型代表是 Room 数据库测试 LoggedInUserDaoTest.kt套路非常标准// Before建内存数据库不落盘每个用例干净隔离 database Room.inMemoryDatabaseBuilder(context, DesignerNewsDatabase::class.java).build() // After关闭数据库 database.close()它验证 DAO 的setLoggedInUser/getLoggedInUser读写是否一致。由于 Repository 层基于协程测试中用共享工具getOrAwaitValue()把挂起结果“await”出来再断言。两种路线的取舍一张表说清对比项RobolectricJVM 集成Plaid 方案真机仪器化运行速度快无需设备较慢需模拟器/真机保真度模拟 Android API存在偏差真实运行时保真度最高适用场景快速回归、CI 密集执行数据库、文件、系统 API 等强依赖真实环境的逻辑结论如果你的集成点像 Plaid 一样集中在 Room 与本地存储真机仪器化测试是最稳的写法若希望 CI 提速可以参考同样的测试代码引入 Robolectric把RunWith(AndroidJUnit4::class)换成 Robolectric 运行器测试主体几乎不用改动。 四、Espresso 实战三步写一个 UI 测试UI 测试是金字塔塔尖Plaid 只写了 3 个个个精炼。HomeActivityTest.kt 覆盖了主页的三种关键状态初始状态drawerClosedOnStartup—— 应用启动时抽屉应为关闭L42-L50交互行为pressFilterButtonOpensDrawer—— 点击过滤按钮后抽屉打开L52-L62配置变更drawerStaysOpenAfterRotation—— 旋转屏幕后抽屉应保持打开L64-L75结构上就三个要素Rule ActivityTestRule负责拉起被测 ActivityonView(withId(...)).perform(click())驱动点击check(matches(isOpen(isClosed)))做状态断言几个细节值得抄作业抽屉开合断言来自espresso-contrib的DrawerMatchers这正是 test_dependencies.gradle 中同时引入 core 与 contrib 的原因而屏幕旋转这种 Espresso 覆盖不到的设备级操作Plaid 用UiAutomator补位UiDevice.getInstance(...).setOrientationLeft()见 HomeActivityTest.kt#L71。Espresso 管 View 交互UiAutomator 管设备级操作分工明确。 五、跨层共享的测试资产Plaid 用一个独立的 test_shared 模块沉淀跨层复用的工具各模块通过testImplementation project(:test_shared)引入见 test_dependencies.gradle#L17。其中被反复引用的核心成员MainCoroutineRule统一的主线程协程调度器替换规则getOrAwaitValue()等待并取出挂起结果的通用断言助手provideFakeCoroutinesDispatcherProvider()/runBlocking配合项目自定义的 CoroutinesDispatcherProvider 注入假调度器每个功能模块还各自维护一份 TestData.kt提供story、shot、post、designerNewsSource等测试数据工厂——测试数据不依赖网络全部本地构造这是集成测试稳定不抖动的关键。 六、怎么跑起来单元测试执行./gradlew test全部在 JVM 上秒级反馈集成测试 Espresso连接设备后执行./gradlew connectedAndroidTest仓库的 scripts/ftl_run_tests.sh 提供了 CI 场景下的完整测试执行脚本可参考其组织方式结语Plaid 的测试体系没有炫技却把“该测什么、放哪层、用什么工具”示范得清清楚楚——ViewModel 交给 Mockito 快速打桩数据库交给内存库真机验证UI 只挑最高价值的三条路径交给 Espresso。照着这套金字塔组织自己的测试你就拥有了可维护、可回归的 Android 测试基线。【免费下载链接】plaidAn Android app which provides design news inspiration as well as being an example of implementing material design.项目地址: https://gitcode.com/gh_mirrors/pl/plaid创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考