スクリーンショットのテスト

スクリーンショット テストは、アプリの UI を確認するのに非常に効果的な方法です。スクリーンショット テストは、コンポーネント テスト、機能テスト、アプリケーション テストに存在できます。

サードパーティ製ツールを使用して、インストルメンテーション スクリーンショット テストとローカル スクリーンショット テストの両方を作成できます。Compose を使用している場合は、公式の Compose プレビュー スクリーンショット テストツールを使用できます。

定義

スクリーンショット テストでは、UI のスクリーンショットを取得し、以前に承認された「参照」または「ゴールデン」と呼ばれる画像と比較します。

スクリーンショット テストでは、2 つの画像(新しいスクリーンショット 1 つと参照画像 1 つ)を比較します。
図 1. スクリーンショット テストでは 2 つの画像を比較します

画像が同じ場合、テストは合格です。差異がある場合は、ツールによってレポートが作成されます。

スクリーンショットのテストレポート。左右に参照と新しいスクリーンショット、中央に違いが表示されています。
図 2. スクリーンショット テスト レポート。左右に参照スクリーンショットおよび新しいスクリーンショットが表示され、中央に差異が表示されています。

報告に対する対応は 2 つあります。

  • 新しいコードにエラーがあることに気づき、修正する。
  • 新しいスクリーンショットを承認し、参照画像を新しい画像に置き換えます。

スクリーンショット テストのワークフローは、通常のテストとは異なります。テストが失敗してもエラーがあるとは限らないからです。

メリット

スクリーンショット テストの利点は次のとおりです。

  • スクリーンショット テストでは、テストごとに複数のアサーションが行われます。たとえば、1 件のテストのみで、色、余白、サイズ、フォントをチェックできます。
  • スクリーンショット テストは、同等の動作テストよりも作成、理解、メンテナンスがはるかに簡単です。
  • 特に、さまざまな画面サイズで回帰を確認して検出する場合に便利です。

デメリット

ただし、スクリーンショット テストには次のような欠点もあります。

  • 大規模なプロジェクトでは数千もの PNG が作成される可能性があるため、参照画像の処理は煩雑になる可能性があります。
  • プラットフォーム(Linux、Max、Windows)によって、生成されるスクリーンショットが若干異なります。
  • 同等の動作テストよりも時間がかかります。
  • スクリーンショット テストの数が多すぎると、1 回の変更で数千のスクリーンショットに影響するなど、問題が発生する可能性があります。

以降のセクションでは、これらの問題に対処するための推奨事項について説明します。

スクリーンショット テストは最小限に抑える

スクリーンショット テストの数は最小限に抑え、一方で回帰に関するフィードバックとカバレッジは最大化する必要があります。

さまざまな UI 状態を組み合わせると、テスト数が急増する可能性があります。アプリの UI の一部を確認する方法は次のとおりです。

  • さまざまなテーマ
  • 異なるフォントサイズを使用する
  • さまざまな画面サイズや境界内

アプリのすべてのコンポーネント、レイアウト、画面でこれを行うと、数千ものスクリーンショット ファイルが作成されますが、そのほとんどは追加のフィードバックを提供しません。

たとえば、明るいテーマと暗いテーマ、3 つのフォントサイズでカスタム ボタンをテストする場合は、それらをすべて組み合わせて作成する必要はありません。代わりに、テーマを 1 つだけ選択できます。これは、長い単語に対するボタンの反応がテーマに影響しないためです。

UI プロパティの組み合わせによっては、省略できます。
図 3. UI プロパティの一部の組み合わせは省略できます。

参照画像を保存する

参照(またはゴールデン)画像は通常、ソース管理にチェックインできる PNG ファイルです。ただし、Git とほとんどのソース コントロール マネージャーは、大きなバイナリ ファイルではなくテキスト ファイル用に最適化されています。

これらのファイルを管理するには、次の 3 つの方法があります。

  • git を引き続き使用しますが、ストレージ使用量を最小限に抑えるようにしてください。
  • Git LFS を使用します。
  • クラウド サービスを使用してスクリーンショットを管理する。

プラットフォームの違い

スクリーンショット テストでは、低レベルのプラットフォーム API を使用してテキストやシャドウなどの特定の機能を描画します。プラットフォームでは、さまざまな方法でそれらを実装できます。Mac で開発し、ローカルで撮影した新しいスクリーンショットを保存すると、Linux CI マシンでテストが破損することがあります。

この問題を回避するには、次の 2 つの方法があります。

  • 小さな変更を許容する
  • サーバーでスクリーンショットを撮る

小さな変更を許容する

ほとんどのスクリーンショット テスト ライブラリは、2 つのスクリーンショットを比較するときに小さな違いを許容するように構成できます。

これには 2 つの方法があります。

  • 変更されたピクセルの割合またはピクセル値の合計差の割合に基づいて許容範囲を構成します。
  • スマート ディファレンス(スクリーンショットを比較するアルゴリズム)を使用して、ピクセルではなく構造的およびセマンティックな類似性を検証します。

この方法のデメリットは、偽陽性が発生する可能性があり、しきい値を下回るエラーや、誤って類似していると見なされるエラーを検出できないことです。

サーバーでスクリーンショットを撮る

ピクセル単位のスクリーンショット比較ツールを使用するには、テストで同じ条件でスクリーンショットを撮影する必要があります。これを行うには、継続的インテグレーション(CI)システムを使用するか、クラウド サービスを使用します。

たとえば、CI ワークフローで次の処理を行うステップを作成できます。

  1. スクリーンショット テストを実行します(ピクセル単位の一致を使用しない場合にのみ必要)。
  2. 前のステップが失敗した場合は、新しいスクリーンショットを記録します。
  3. 新しいファイルをブランチに commit します。
代替テキスト: CI でスクリーンショットを撮る方法を示す図
図 4. CI でスクリーンショットを撮影する方法を示した図

この方法を使用すると、CI でスクリーンショット テストが失敗することはありませんが、変更が変更されます。これにより、お客様と変更審査担当者は、変更をマージすることで新しいスクリーンショットを受け入れることができます。

スクリーンショット テストツール

スクリーンショットのテストに使用できるツールとライブラリの主な違いは次のとおりです。

  • 環境: ホストで実行されるローカルテスト、またはエミュレータまたはデバイスで実行されるインストルメンテーション テスト。
  • レンダリング エンジン: ホスト側のスクリーンショット ソリューションでは、Layoutlib(プレビュー用 Android Studio のレンダリング エンジン)または Robolectric Native Graphics(RNG)を使用できます。
    • Layoutlib ベースのフレームワークは、静的コンポーネントのレンダリングに重点を置き、さまざまな状態を使用してさまざまな動作を示します。通常は使いやすいため
    • RNG と統合されたフレームワークは、Robolectric のすべての機能を使用できるため、より広範なスコープでテストできます。