D27 / 怎麽测试? - Testing Compose

今天大概会聊到的范围

  • Testing

Compose 的 Test 属於 UI Test ,在执行时需要启动模拟器或是 run 在实机上。在使用上,就像其他的 UI Test 工具( ex. Espresso, Selenium) 很像:先在画面上找到目标、对目标进行操作、检查操作结果

环境配置

在开始 Compose Test 之前,别忘了引入相关的 library

androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"

ui-test-junit4 是主要的测试 library。另外当 Compose test 执行时,会将要测试的 Composable 放入 "ComponentActivity" 并用 Intent 将其启动。所以我们要在 Manifest 中加上 ComponentActivity 的定义,因此我们加上 ui-test-manifest 来帮忙完成这个任务。

/androidTest 中,我们建立一个测试 class

class SimpleCompTest {
    
    // 1    
    @get:Rule
    val composeTestRule = createComposeRule()
    
    @Test
    fun test_when_SimpleComp_click_should_display() {
        // 2
        composeTestRule.setContent {
            SimpleComp()
        }
        
        composeTestRule.onNodeWithText("Click Me", ignoreCase = true).performClick()
        composeTestRule.onNodeWithText("Perfect").assertIsDisplayed()
    }
    
    
}
  1. Compose Test 使用 createComposeRule() 来建立一个 TestRule
  2. 在测试开始前,先用 composeTestRule.setContent 定义要测试的内容。setContent 做的事情就和 Activity.setContent 一样,将画面摆进 Activity 中。这边使用的 Activity 就是前面提到的 ComponentActivity。若希望使用自己的 Activity,则改用 createAndroidComposeRule 并定义要使用的 Activity:
@get:Rule
val composeTestRule = createAndroidComposeRule<MyActivity>()

找到目标

compose test 提供一系列的工具,方便我们在画面上找寻我们要互动的元件。主要分成 Finder 和 Matcher 两个角色:

  • Finder:负责找到元件的,可以定义要找的是一个 or N 个元件
  • Matcher:查找的条件
@Composable
fun TestComp() {
    Text("One", color = Color.Red)
    Text("Two", color = Color.Blue)
    Text("Three", color = Color.Green)
    Text("Four", color = Color.Cyan)
}

@Test
fun test_TestComp() {
    composeTestRule.setContent {
        TestComp()
    }
    
    composeTestRule.onNodeWithText("One")     // 1. 
    
    composeTestRule.onNode(hasText("One"))    // 2.
    
}
  1. onNodeWithText 就是一个常用的 Finder,他可以找到 Text or TextField 包含对应的字样
  2. onNode 是泛用的 Finder,他可以吃一个 Matcher。hasText 就是一个负责找到包含对应文字的元件的 Matcher

对目标进行操作

找到目标後,我们可以对他进行操作:

onNode(...).performClick()        // 对找到的 Node 进行点击
onNode(...).perforTextInput(...)    // 输入文字

除了进行一些常见的操作外,还可以对 Node 进行一个 or N 个手势操作

onNode(...).performGesture { 
    click()
    swipeUp()
    ...
}

检查操作结果

最後要提到的 assertion,最基本的检查是检查元件是否存在

onNode(...).assertIsDisplayed()

当然,还有很多 assertion 可以使用。例外还有通用的 assert() function

onNode(...).assert( <matcher> ) 

Cheat Sheet

有这麽多的 Finder、Matcher、Action 和 Assertion ,谁记得了那麽多啊?好加在 Google 很贴心的将这个 Compose Testing framework 的常用功能整理成一张小抄,方便我们在开发的时候对照:


<<:  Day 19:AWS 是什麽?30天从动漫/影视作品看AWS服务应用 -《尼尔:自动人形》

>>:  【Day 26】Go 与 Redis

DAY 20 Big Data 5Vs – Variety(速度) EMR (2)

EMR的分散式运算与分散式储存适用是批量处理的应用场景,它也和Glue一样有提供互动式分析介面:EM...

JavaScript Day30 - 完结与铁人赛 JS 系列主题

铁人赛系列 在本次的铁人赛也看到不少 JS 的相关主题,提供给大家参考也方便自己查询,有不少都很清楚...

Raspberry pi 与云端的连结

前面都在讲电控 对Raspberry pi似乎大材小用了 既然他有网路, 那就可以将感测器所计算出来...

[Day 18]所以我说那个酱汁呢(前端篇)

挑战目标: MockNative Camp 这次的挑战应该就止步於此了,在前端上我太弱小LA,没有事...

Day 25 Redux 介绍

第 25 天 ! 我们知道 redux 结构 flux-like , 那麽他的每个阶段是在处理什麽?...