🪒
Jetpack Compose UI Test
読んでほしい人
- Jetpack Compose UI Testに興味がある.
- 簡単なテストで良いので書いてみたい。
補足情報
テストに必要なパッケージは最初から入ってます。
こちらの動画を参考にUI Testの練習をしていきましょう!
記事の内容
UI Testをするファイルを動画で解説しているディレクトリに作成してください。こちらにテストコードを書いていきます。
Hello WorldするUI作りましょう
実行するアプリのコード
package com.junichi.composetest
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.junichi.composetest.ui.theme.ComposeTestTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeTestTheme {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Text(text = "Hello World!")
}
}
}
}
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
ComposeTestTheme {
}
}
UI Testのコードを書く。Hello World!
というテキストがあればテストが通る!
UI Testのコード
package com.junichi.composetest
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import org.junit.Rule
import org.junit.Test
class ComposeUITest {
@get:Rule
val composeRule = createAndroidComposeRule<MainActivity>()
@Test
fun testIfHelloWorldIsDisplayed() {
// Hello Worldというテキストが表示されているかどうかを確認する
composeRule.onNodeWithText("Hello World!").assertIsDisplayed()
}
}
tagを追加してみる。もしtagのテキストが違ったらエラーが出る!
tagを追加したUI
package com.junichi.composetest
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.junichi.composetest.ui.theme.ComposeTestTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeTestTheme {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Text(text = "Hello World!", modifier = Modifier.testTag("helloText").semantics {
contentDescription = "Hello world button"
})
}
}
}
}
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
ComposeTestTheme {
}
}
tagがあるかテストする
package com.junichi.composetest
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithText
import org.junit.Rule
import org.junit.Test
class ComposeUITest {
@get:Rule
val composeRule = createAndroidComposeRule<MainActivity>()
@Test
fun testIfHelloWorldIsDisplayed() {
// hello world buttonというcontentDescriptionがついたノードが表示されているかどうかを確認する
composeRule.onNodeWithContentDescription("Hello world button").assertIsDisplayed()
}
}
カウンターのテストをする
ボタンを押すと、カウントがされるUIを作成します。これをUI Testのファイルでimportしてカウントがされたかテストします。
カウンターのUI
package com.junichi.composetest
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.tooling.preview.Preview
import com.junichi.composetest.ui.theme.ComposeTestTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeTestTheme {
Counter()
}
}
}
}
@Composable
fun Counter() {
var counter by remember { mutableStateOf(0) }
Column (modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally) {
Button(onClick = { counter++ }, modifier = Modifier.testTag("incrementButton")) {
Text(text = "Increment")
}
Text(text = "The current count is $counter", Modifier.testTag("text"))
}
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
ComposeTestTheme {
}
}
3回ボタンをカウントして期待する値が3だったらテストが通るテストコードです。
カウンターのテストコード
package com.junichi.composetest
import androidx.compose.ui.test.assert
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performClick
import org.junit.Rule
import org.junit.Test
class ComposeUITest {
@get:Rule
// createComposeRuleに修正してください
val composeRule = createComposeRule()
@Test
fun testIfCounterIsFine() {
// setContentを呼び出す
composeRule.setContent {
// CounterのComposableを呼び出す
Counter()
}
// カウンターは最初は0なので、0であることを確認。0でなければテストは失敗します。
composeRule.onNodeWithTag("text").assert(hasText("The current count is 0"))
// カウンターを3回インクリメントさせるので、composeRule.onNodeWithTagを3回呼び出す
composeRule.onNodeWithTag("incrementButton").performClick()
composeRule.onNodeWithTag("incrementButton").performClick()
composeRule.onNodeWithTag("incrementButton").performClick()
// カウンターは3になるので、3であることを確認。3でなければテストは失敗します。
composeRule.onNodeWithTag("text").assert(hasText("The current count is 3"))
}
}
期待する値が3ではなければ失敗する!
期待する値が3であればテストが通る!
最後に
今回は、Jetpack ComposeでUI Testをやってみました。知識がないものでしたから最初は分からなかったですね。最近テストコードを書くのを意識してるので書いていきたいですね。
公式でも紹介はされている:
Discussion