Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Jetpack Composeの テストに入門しよう / Getting started with Jetpack Compose Testing

tkmnzm
September 29, 2020

Jetpack Composeの テストに入門しよう / Getting started with Jetpack Compose Testing

Android 11 Meetups (UI・デザイン)の発表資料です。
https://developersonair.withgoogle.com/events/a11meetups-jp

tkmnzm

September 29, 2020
Tweet

More Decks by tkmnzm

Other Decks in Programming

Transcript

  1. Jetpack Composeの
    テストに入門しよう
    Nozomi Takuma
    SWET
    DeNA Co., Ltd.

    View Slide

  2. Composable Functionの動作確認をしたい
    ● アプリをビルドする
    ● Preview機能
    ● 自動テスト

    View Slide

  3. Composable Functionの動作確認をしたい
    ● アプリをビルドする
    ● Preview機能
    ● 自動テスト

    View Slide

  4. Jetpack Composeの
    Preview機能

    View Slide

  5. Jetpack ComposeのPreview機能
    ● @Previewアノテーションをつけたプレビュー用の
    Composable Functionを作成する
    ● 画面幅・デバイスなどを指定してプレビューを作成
    できる
    ● サンプルデータを用いたプレビューを作成できる

    View Slide

  6. Jetpack ComposeのPreview機能
    @Composable
    fun Greeting(name: String) {
    Text (text = "Hello $name!")
    }
    @Preview
    @Composable
    fun PreviewGreeting() {
    Greeting("Android")
    }

    View Slide

  7. @Previewで設定できる項目
    annotation class Preview(
    val name: String = "",
    val group: String = "",
    @IntRange(from = 1) val apiLevel: Int = -1,
    val widthDp: Int = -1,
    val heightDp: Int = -1,
    val locale: String = "",
    @FloatRange(from = 0.01) val fontScale: Float = 1f,
    val showDecoration: Boolean = false,
    val showBackground: Boolean = false,
    val backgroundColor: Long = 0,
    @UiMode val uiMode: Int = 0,
    @Device val device: String = Devices.DEFAULT)

    View Slide

  8. サンプルデータでPreview作成
    @Composable
    fun ProfileScreen(
    userData: ProfileScreenState,
    onFabClicked: () -> Unit = { }
    )
    @Preview
    @Composable
    fun Preview() {
    ProfileScreen(SampleData.myProfile)
    }

    View Slide

  9. サンプルデータでPreview作成
    @Composable
    fun ProfileScreen(
    userData: ProfileScreenState,
    onFabClicked: () -> Unit = { }
    )
    @Preview
    @Composable
    fun Preview() {
    ProfileScreen(SampleData.myProfile)
    }
    プロフィールデータを受け取る
    Composable Function
    サンプルデータを用意しておき
    それを使ってプレビューを作成

    View Slide

  10. 表示パターンが複数あるとき
    ● PreviewParameterProviderを使うことで、
    プレビューしたいデータをパラメータ化することが
    できる

    View Slide

  11. PreviewParameterProvider
    interface PreviewParameterProvider {
    val values: Sequence
    val count get() = values.count()
    }

    View Slide

  12. PreviewParameterProvider
    interface PreviewParameterProvider {
    val values: Sequence
    val count get() = values.count()
    }
    Composable Functionにわたす
    データの型

    View Slide

  13. PreviewParameterProvider
    interface PreviewParameterProvider {
    val values: Sequence
    val count get() = values.count()
    }
    overrideして複数のサンプル
    データを返すようにする

    View Slide

  14. PreviewParameterProvider
    @Preview
    @Composable
    fun Preview() {
    ProfileScreen(SampleData.myProfile)
    }
    @Preview
    @Composable
    fun Preview(state: ProfileScreenState) {
    ProfileScreen(state)
    }
    引数にProfileScreenStateを
    うけとるように修正

    View Slide

  15. @Preview
    @Composable
    fun Preview(state: ProfileScreenState) {
    ProfileScreen(state)
    }
    class ProfileStateProvider : PreviewParameterProvider {
    override val values: Sequence
    get() = sequenceOf(SampleData.meProfile, SampleData.friend)
    }
    PreviewParameterProvider
    プロフィールデータを返すカスタムの
    PreviewParameterProviderを作成

    View Slide

  16. PreviewParameterProvider
    @Preview
    @Composable
    fun Preview(@PreviewParameter(ProfileStateProvider::class) state: ProfileScreenState) {
    ProfileScreen(state)
    }
    class ProfileStateProvider : PreviewParameterProvider {
    override val values: Sequence
    get() = sequenceOf(SampleData.meProfile, SampleData.friend)
    }
    @PreviewParameterをプレビューの
    引数に指定する

    View Slide

  17. PreviewParameterProvider
    @Preview
    @Composable
    fun Preview(@PreviewParameter(ProfileStateProvider::class) state: ProfileScreenState) {
    ProfileScreen(state)
    }
    class ProfileStateProvider : PreviewParameterProvider {
    override val values: Sequence
    get() = sequenceOf(SampleData.meProfile, SampleData.friend)
    }

    View Slide

  18. その他便利なPreview機能
    ● Interactive previews mode
    ○ Previewに対してUIの操作をすることができる
    ● Animation Inspector
    ○ アニメーションのプレビューをタイムラインでみる
    ことができる

    View Slide

  19. Preview機能
    デモ

    View Slide

  20. Animation Inspector(Coming soon)

    View Slide

  21. Jetpack ComposeのPreview機能
    ● 素早く動作確認ができる
    ● サンプルデータを用意することで表示パターンの
    確認ができる
    ● Previewの作りやすさを意識したIFや、サンプルデー
    タの管理をどうするかを考える必要がありそう

    View Slide

  22. Jetpack Composeの
    自動テスト

    View Slide

  23. Jetpack Composeの自動テスト
    ● Jetpack Compose用のTest Rule
    ● Jetpack Compose用のテストAPI
    ○ Semanticsを使ってテストをする

    View Slide

  24. ComposeTestRule
    ● createComposeRule
    ○ 空のActivityにsetContentをした上でテストをする
    ○ 実Activityとは切り離して、Composable Function単
    体のテストをすることができる
    ● createAndroidComposeRule
    ○ 任意のActivityを指定できる
    ○ 実Activity上でテストをすることが可能

    View Slide

  25. createComposeRule
    ● 空のComponentActivityを起動できるように
    AndroidManifestに登録しておく
    ○ app/src/debug/AndroidManifest.xmlなど





    View Slide

  26. createComposeRule
    class ProfileTest {
    @get:Rule
    val rule = createComposeRule()
    @Test
    fun test() {
    rule.setContent {
    ProfileScreen(userData = SampleData.meProfile)
    }
    }
    }

    View Slide

  27. createAndroidComposeRule
    class ProfileTest {
    @get:Rule
    val rule = createAndroidComposeRule()
    @Test
    fun test() {
    // MainActivityが起動した状態
    // rule.setContentで表示中のComposable Functionを上書きすることも可
    }
    }

    View Slide

  28. Semantics
    ● Jetpack Composeでは既存のViewのテストとは異な
    り、IDではなくセマンティクスでUIの操作をする
    ● セマンティクスはアクセシビリティのために使用さ
    れる

    View Slide

  29. Semanticsの指定
    ● Modifier.semanticsで指定する
    ● 指定できる要素
    ○ text
    ○ accessibilityLabel
    ○ accessibilityValue etc…

    View Slide

  30. セマンティクスツリー
    Display Name
    Nozomi Takuma

    View Slide

  31. セマンティクスツリー
    Display Name
    Nozomi Takuma
    Root
    Node #1 Node #4
    Node #2
    text = Display Name
    Node #3
    text = Nozomi Takuma

    View Slide

  32. Semanticsのデフォルト値
    ● デフォルトでプロパティの値をセマンティクスツ
    リーに公開しているComposable Functionもある
    ● TextのComposable Functionは、textプロパティの値
    がセマンティクスのtextの値としても使用される
    ○ 自身で別の値を指定したいときはModifierで変更する

    View Slide

  33. Test用API
    ● Jetpack ComposeのUIテスト用API
    ● Espressoと似た構造
    ● Finder/Semantics Matcher/Action/Assertion

    View Slide

  34. Finder
    ● onNode(SemanticsMatcher)
    ○ 単一のノードを選択
    ● onAllNodes(SemanticsMatcher)
    ○ 複数のノードを選択

    View Slide

  35. Semantics Matcher
    ● hasText(String)
    ● hasLabel(String)
    ● hasParent(SemanticsMatcher)
    ● hasAnyChild(SemanticsMatcher) etc...

    View Slide

  36. Action
    ● performClick
    ● performTextReplacement
    ● performKeypress
    ● performScrollTo etc...

    View Slide

  37. Assertion
    ● assert(SemanticsMatcher)
    ● assertIsDisplayed etc...

    View Slide

  38. その他便利なTest用API
    ● captureBitmap
    ○ ノードをBitmap化できる
    ○ Visual Regression Test等の用途で使用できる
    ● printLog
    ○ 現在のセマンティクスツリーをLogに出力する

    View Slide

  39. 自動テスト
    デモ

    View Slide

  40. Jetpack Composeの自動テスト
    ● Jetpack Composeではセマンティクスを使用して
    UIテストを行い、Jetpack Composeのテスト用APIが
    提供されている
    ● 空のActivityを利用することで、Jetpack Compose単
    体のUIテストをすることが可能

    View Slide

  41. Jetpack Composeのテストまとめ
    ● Jetpack ComposeではUIの作り方だけではなく、
    動作確認時も既存のViewとは違う仕組みを使う
    ● Jetpack Composeははじめから動作確認・テストの
    やりやすさを意識して実装されていると感じる
    ● Preview機能もテストAPIも進化中だと思うので今後
    のアップデートにも期待

    View Slide

  42. View Slide

  43. ご静聴ありがとうご
    ざいました!

    View Slide