Now in AndroidでRoborazziはどのように使われているか
はじめに
最近、Android のテストについて興味が高まっており色々調べています sanao と申します。
Roborazziとは、@takahirom氏によって開発されているスクリーンショットテストライブラリです(私も地味に Contribute してるぜ)。
その有用性から、now in android にも 2023 年夏ごろに採用されました[1]。
本記事では now in android 内で Roborazzi がどのように使われているのかざっくりと説明します。
なお、まだまだ now in android では Roborazzi の導入が進むことが予想されますので、執筆時点(2024/2/6)での情報だということにご注意ください。
本記事では説明しないこと
- Roborazzi を採用するメリット
- Roborazzi の使い方
使用箇所
現在、Roborazzi が配置されているモジュールは
- core/testing
- core/designsystem
- app
- feature/foryou
になります。
core/testing
core/testing では、スクリーンショットをシュッと撮るためのヘルパー関数などが実装されています。
もっともよく使用されている関数がcaptureMultiTheme
です。
captureMultiTheme
は
- 出力するスクリーンショットのファイル名
- ダークモードか
- ダイナミックカラーを使うか
- Android テーマを使うか
を引数を変えるだけで柔軟にスクリーンショットを撮影することができます。
また、現状の使用頻度は少ないですが、デバイスごとにスクリーンショットを取得する関数もあります。
まず、ただひとつのデバイスでスクリーンショットを撮影するためのcaptureForDevice
関数が実装されています。
これも同様に引数から
- 出力するスクリーンショットのファイル名
- 撮影に使用するデバイスのスペック
- ダークモードか
を設定できます。
captureForDevice
の引数deviceSpec: String
は次のように使われています。
composeTestRule.captureForDevice(
deviceName = "phone_dark",
deviceSpec = DefaultTestDevices.PHONE.spec,
...
DefaultTestDevices
列挙型はあらかじめ定義してあるスマホ、折りたたみデバイス、タブレットの高さや幅などのスペックです。
以下のように定義されています。
また、DefaultTestDevices
列挙型を用いてスマホ、折りたたみデバイス、タブレットの全てのスクリーンショットを一括で撮影する関数 captureMultiDevice
も実装されています。
core/designsystem
以上の 6 ファイルにて使用されています。
ほとんどがcaptureMultiTheme
でただ撮影しているだけなのですが、LoadingWheel
だけ注目すべき実装があったので共有します。
LoadingWheel
LoadingWheel
では唯一アニメーションのスクリーンショットが撮影されています。実装は以下になります。
Compose テストはデフォルトで UI と同期される仕様があります。[2]
つまり UI がアイドル状態(アニメーションが完了している状態)となるまでスクリーンショットのキャプチャを行うことはできません。
これを解決するために 67 行目でまず同期を解除しています。
composeTestRule.mainClock.autoAdvance = false
同期を解除したので、次は自分で時間を進める処理が必要となります。
これは 75 行目のadvanceTimeBy
で行われています。
listOf(20L, 115L, 724L, 1000L).forEach { deltaTime ->
composeTestRule.mainClock.advanceTimeBy(deltaTime)
...
これらの処理によってアニメーションが進行している間の任意のフレームずつcaptureRoboImage
を使ってスクリーンショットの撮影を行うことが可能となっているわけです。
now in android で実践されている Roborazzi でアニメーションのスクリーンショットを撮影するテクニックは Android Test Night#9[3] で @sumio さんが発表されていた内容[4]の一つでもあり、コードを読んでいた際にテンションが上がりました。
app
NiaAppScreenSizesScreenshotTests.kt にて使用されています。
テーマは関係なく、ひたすら色んな幅や高さのスクリーンショットを撮っています。
ここでcaptureMultiDevice
を使わなかった理由としては3つのデバイスのスペックだけでなくいろいろな高さや幅のスクリーンショットを撮影するためだと考えられます。
feature/foryou
ForYouScreenScreenshotTests.kt にて使用されています。
前述した captureForDevice
やcaptureMultiDevice
によってデバイスごとに丁寧にスクリーンショットが撮影されています。
おわりに
now in android は最新知識の宝庫なので読んでいると楽しいし知識も仕入れられるしで一石二鳥ですね!
効率良くスクリーンショットテストを撮影するために適切な拡張関数を作成するのは大事だと感じました。
現状、/feature
ではforyou
モジュールしか Roborazzi によるスクリーンショットテストが実装されていないので今後も増えることが予想されます。なので随時記事をアップデートしていけたらなと思っています。
ヘルパー関数のあたりは詳しい実装を説明していないので気になった方はぜひリポジトリのソースを読みに行ってみてください。
記事内で解釈違いの部分やここも注目するべきなどの箇所があればお手柔らかに教えていただけると幸いです。
お読みいただきありがとうございました。
Discussion