先日開催されたDroidKaigi2026に参加しました。
その中で、個人的に気になったセッションの一つが、
UI仕様を「見えるもの」にする
〜 Compose Screenshot Testing とギャラリーで支える、AIエージェント時代のAndroid UI開発 〜
というセッションでした。
セッションページ
ComposeScreenshotTestingを使って、UIの変更をスクリーンショットの差分として確認したり、CI上でレビューできるようにしたり、さらにスクリーンショットをUI仕様として活用したりするという内容でした。
話を聞いていて、
「実際に自分で触ってみたい」
と思ったので、今回は簡単なComposeアプリを作って、ComposePreviewScreenshotTestingを実際に試してみました。
この記事では、「実際に触ってみると、どんな感じだったのか」を中心に書いていきます。
ComposePreviewScreenshotTestingとは?
ざっくり言うと、ComposeのPreviewを使ってUIのスクリーンショットを生成し、それを基準画像として保存しておき、後からUIに変更が入ったときに画像の差分を検知する仕組みです。
公式ドキュメントでも、@PreviewTestを使ってComposable PreviewをScreenshot Testの対象にし、Reference画像を生成して、その後の変更を比較する流れが紹介されています。
イメージとしては、
Compose Preview
↓
Reference画像を生成
↓
UIを変更
↓
もう一度UIを描画
↓
Referenceと比較
↓
差分があればテスト失敗
という感じです。
名前だけ聞くと少し大掛かりに感じますが、実際に触ってみるとPreviewとの距離がかなり近い機能でした。
実際に試してみる
今回は動作確認用として、簡単な「Task Dashboard」を作りました。
こんな感じの画面です。
- タスクの進捗
- 完了したタスク数
- タスク一覧
- タスクのPriority
- 完了 / 未完了
などを表示するシンプルな画面にしました。
ScreenshotTestingそのものを試すことが目的なので、UIはあえてシンプルにしています。
まずは普通のCompose Preview
最初はいつものCompose Previewを作ります。
@Preview(
name = "Phone",
showBackground = true,
widthDp = 360,
heightDp = 800
)
@Composable
fun PhonePreview() {
TaskDashboardScreen(
tasks = previewTasks
)
}
ここまでは普通のPreviewです。
Android Studio上でUIを確認できます。
PreviewをScreenshotTestにしてみる
ここで@PreviewTestを付けます。
@PreviewTest
@Preview(
name = "Phone",
showBackground = true,
widthDp = 360,
heightDp = 800
)
@Composable
fun PhoneScreenshotTest() {
TaskDashboardScreen(
tasks = previewTasks
)
}
今回、実際に触ってみて面白いと思ったのがここです。
新しく「Screenshot Test専用の画面」を作るというより、
普段使っているCompose Previewを、そのままスクリーンショットテストの対象にできる
という感覚でした。
Reference画像を生成する
次に、現在のUIを基準画像として保存します。
今回生成されたReference画像は、
app/src/screenshotTestDebug/reference/
に保存されました。
この画像が、正しいという基準になります。
つまり、UIの仕様を画像として持っているようなイメージです。
ここで、あえてUIを変更してみる
せっかくなので、わざとUIを変更してみました。
例えばTaskCardのpaddingを、
.padding(16.dp)
から、
.padding(36.dp)
に変更します。
当然、画面の見た目が変わります。
コード上ではほんの少しの変更ですが、実際にレンダリングされるUIは変わっています。
そこでScreenshotTestを実行してみます。
Screenshot Testが失敗した
すると、Reference画像と現在のUIの画像に差分があるため、テストが失敗しました。
ちゃんと見た目の変更を検知してくれている!ということを確認できました。
今回実際に生成されたDiffがこちらです。
画像を見ると、UIを変更した部分が差分として確認できます。
コードだけを見ていると、
.padding(16.dp)
が
.padding(36.dp)
になっただけですが、スクリーンショットとして比較すると、画面上で何が変わったのかが、直感的に分かります。
実際に触ってみて感じたこと
Previewとの相性が良さそう
一番感じたのは、ComposePreviewとの相性の良さです。
普段からPreviewを使ってUIを確認しているので、このPreviewをそのままテスト対象にする
という考え方が分かりやすかったです。
ScreenshotTestのために、まったく別のUIテストを書くという感覚ではありませんでした。
「UIが変わった」を画像で確認できる
今回、あえてpaddingを変更してDiffを出してみました。
コードの変更だけを見ると小さな変更ですが、画像として比較することで、実際の見た目の差が分かります。
UIレビューでは、コードだけではなく実際の見た目を確認したいケースが多いので、こういう仕組みは便利そうだと感じました。
Previewのパターンを増やしたくなる
今回試したのはPhoneの1パターンだけでした。
ただ、Compose Previewには、
- Light / Dark
- Phone / Tablet
- Portrait / Landscape
-
fontScaleによる文字サイズの違い - 空の状態
- データが多い状態
など、いろいろなパターンを作れます。
ScreenshotTestingと組み合わせることで、この画面は、この状態でも崩れていないというものを画像として残しておけそうです。
このあたりは、今回の簡単な検証からもう少し発展させて試してみたいと思いました。
というのも、以前、ダークモードや文字サイズによって画面の表示崩れが起きたことがありました。
ScreenshotTestingを導入しておけばPreviewをさまざまな条件で書くことが当たり前になりそうなので、手戻りも減りそうだと感じました。
逆に、Diffの確認はもう少し見やすくなってほしい
今回、テストが失敗した際にはHTMLレポートからDiffを確認しました。
差分そのものは確認できるのですが、個人的には、
もう少しReference / Actual / Diffを見比べやすいと嬉しいな
という印象もありました。
ただ、現在のCompose Preview Screenshot TestingはExperimentalな機能なので、今後さらに使いやすくなっていくことにも期待したいところです。
※今回の記事を書いている時点でもExperimentalな機能として提供されています。
まとめ
今回は、DroidKaigi2026のセッションをきっかけに、ComposePreviewScreenshotTestingを実際に触ってみました。
やったことはかなりシンプルで、
Compose Previewを作る
↓
@PreviewTestを付ける
↓
Reference画像を生成
↓
UIを意図的に変更
↓
Screenshot Testを実行
↓
Diffを確認
という流れです。
今回試したのはまだ本当に小さなサンプルなので、実際のプロジェクトで使うとなると、考えることはまだありそうです。
今回参加したDroidKaigiのセッションでは、まさにこうした実運用の話や、CIへの差分画像投稿、スクリーンショットギャラリーなど、さらに一歩進んだ活用方法が紹介されていました。
今回はまず「実際に動かしてみる」までだったので、次はもう少し実運用を意識した使い方も試してみたいと思います。
カンファレンスで聞いた内容を、そのまま聞いて終わりにせず、実際に手を動かしてみると理解がかなり深まるなと感じました。
今回はまだ試せてないですが、CIを使用してプルリクエストにスクリーンショットの差分がコメントされる仕組みはすごく便利そうだと感じました。
今後も気になった技術は、できるだけ小さくても実際に触ってみようと思います。
