Roborazziを試してみる
気になってはいるものの長い間手を出せずにいたので、先日たまたま流れてきたこちらの記事を参考にいいかげん手元で動かしてみようと思います
なるほど?Showkaseというのを使うとPreview関数のComposableをスクリーンショットテストに使えるのか
Showkase を採用した理由としては、Preview 関数で生成した Composable をスクリーンショットテストにそのまま使用でき、コード削減できると考えたためです。
とりあえず記事を参考に手元のサンプルコードに導入してみる
KSPのバージョンがAGPとあってなかったので更新
UnitTestってどこに追加するんだっけ...(毎回忘れる)
任意のモジュール > src > new > Directoryでtest/java(kotlin)にすればいいのか

robolectricの依存関係も足りてなかったので追加
testImplementation("junit:junit:4.13.2")
testImplementation("org.robolectric:robolectric:4.12")
Showkase.getMetadataが参照エラーになる、と思ったらビルドしたら解決された。autogeneratedされるやつっぽい
なるほど、モジュールの定義はこのために必要なのか
This is relevant because we generate the Showkase related classes in the package of the root module and we need to be able to access the UI elements across all the sub modules. This is only possible from the root module as it typically has a dependency on all the sub-modules.
デフォだと以下の場所に生成してくれるっぽい?
const val DEFAULT_ROBORAZZI_OUTPUT_DIR_PATH: String = "build/outputs/roborazzi"
なんかテストが失敗する...
java.lang.NoSuchMethodError: 'float android.text.TextPaint.getLetterSpacing()'
これを追加し忘れてたっぽい
testOptions {
unitTests {
this.isIncludeAndroidResources = true
}
}
いけたっぽい。
追加したUnitTestを実行したらちゃんと所定の位置にPreview 関数分のpngファイルが作成されてる

普通のPreview関数って多分Screen単位とかでしか作らないと思うので、AppBarとかも含めたスクショが撮りたかったらまた別の方法を使うって感じになるのかな?
明日他のサンプルも見てみよう。DroidKaigiのConferenceAppとNiaも使ってた気がする
今日は参考文献も見てみる
なるほどーーーー、差分を比較するとかはRoborazzi側のgradle taskとして用意してくれてるのか
./gradlew recordRoborazziDebug
スクリーンショットを保存して、 build/outputs/roborazzi 以下のディレクトリに保存
./gradlew compareRoborazziDebug
build/outputs/roborazzi 以下のディレクトリに保存されているスクリーンショットをと、テストから生成されるスクリーンショットを比較する。差分があった場合は ***_compare.png の名前で差分の画像を生成
./gradlew verifyRoborazziDebug
保存されているスクリーンショットと、テストから生成されるスクリーンショットを比較して、差分があった場合はテスト失敗とする
./gradlew verifyAndRecordRoborazziDebug
保存されているスクリーンショットをと、テストから生成されるスクリーンショットを比較する。差分があった場合は生成されたスクリーンショットを新しい比較元のスクリーンショットとする
見方があんまよくわからんけど何かしらDiffっぽいものは生成された

なるほど?AppBarがScreenの外にある場合の全体画面のスクショとかもこの感じでやればいいのかな
スクリーンショットの保存は captureRoboImage() を呼び出すことで行えます。Theme の適用などの共通の処理を checkComposeScreen という名前で切り出し、Composeの画面毎に checkSettingsScreen などのテストから呼び出すようにしています。
NiaのNiaAppScreenSizesScreenshotTestsらへんを参考にすると良さそう?
似た書き方しているな。明日これ試してみよう。
private fun testNiaAppScreenshotWithSize(width: Dp, height: Dp, screenshotName: String) {
composeTestRule.setContent {
CompositionLocalProvider(
LocalInspectionMode provides true,
) {
TestHarness(size = DpSize(width, height)) {
BoxWithConstraints {
NiaTheme {
val fakeAppState = rememberNiaAppState(
windowSizeClass = WindowSizeClass.calculateFromSize(
DpSize(maxWidth, maxHeight),
),
networkMonitor = networkMonitor,
userNewsResourceRepository = userNewsResourceRepository,
timeZoneMonitor = timeZoneMonitor,
)
NiaApp(fakeAppState)
}
}
}
}
}
composeTestRule.onRoot()
.captureRoboImage(
"src/testDemo/screenshots/$screenshotName.png",
roborazziOptions = DefaultRoborazziOptions,
)
}
あんまよくわかってないのが、ComposeがViewModelとかに依存してる状態でPreviewしようとするとエラーになるだった気がするんだけど、このcaptureRoboImageだとエラーにならない?composeTestRuleでActivityをセットしているとViewModelなどに依存していても問題なくキャプチャできる???
問題なくキャプチャできたっぽい
最後にCI/CDに組み込むステップを試し中 GithubActionsなんもわからん
今日もとりあえずこれを参考に手元で試してみる
↑で紹介されてる以下を手元のymlに組み込んで試し中
on:
push:
jobs:
unit_test_android:
steps:
...
- uses: actions/upload-artifact@v3
if: ${{ always() }}
with:
name: golden-screenshot
path: |
**/build/outputs/roborazzi
retention-days: 14
...```AGPに対してJDKが古いと言われた。しばらくメンテしてなかった自分が悪い
Failed to apply plugin 'com.android.internal.application'.
Android Gradle plugin requires Java 17 to run. You are currently using Java 11.
Your current JDK is located in /opt/hostedtoolcache/Java_Adopt_jdk/11.0.22-7/x64
記述を修正してリトライ
- name: Set up JDK
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '11'
