🌊

Visual Regression Testingツール選定 ~①aShot編~

2023/12/22に公開

最近、Visual Regression Testingの重要性が高まっていることを感じています。しかし、このテストが具体的に何を意味するのか、初めは私自身もよく理解していませんでした。そこで、Visual Regression Testingに関連する幾つかのツールを実際に検証してみることにしました。

このプロセスを通じて私が気づいたのは、各ツールにはそれぞれ独自のメリットとデメリットがあるということ。これらをしっかり理解し、自分のプロジェクトに合わせて適切に選ぶことが、Visual Regression Testingを効果的に行うための鍵だということです。

Visual Regression Testingに使えるツールには、オープンソースソフトウェア(OSS)もあれば、有償サービスもあります。それぞれに特徴があり、機能やサポートのレベルも異なります。特に、最近はVisual AI技術を用いたツールが注目されており、その高度な画像分析能力が魅力的です。

今後の記事で、私が検証したVisual Regression Testingツールの結果を3部に分けてご紹介します。各ツールのメリットとデメリットを共有し、これらの情報がVisual Regression Testingの効果的な実施に少しでもお役に立てればと思います。

想定する読者

  • Visual Regression Testingに興味がある方
  • Visual Regression Testingの導入を検討している方

Visual Regression Testingとは?

①目的
Visual Regression Testingは、ソフトウェアテストの一種で、アプリケーションの画面表示が意図した通りになっているかを確認する手法です。このテストは、ウェブアプリケーションやモバイルアプリケーションの開発において特に重要であり、新たなコード変更が既存の機能に悪影響を与えていないかをチェックします。主な目的は、UIの外観や使い勝手に重点を置き、視覚的なバグを検出することです。

②重要性
Visual Regression Testingの重要性は、開発プロセスの初期段階で視覚的な問題を特定し、修正にかかる時間とコストを削減することにあります。特に、機能バグはテストで摘出できる一方で、UIバグは一目瞭然なものもあれば、ブランディングに重要な色合い(例えば「Honda Red」のようなブランドガイドラインに沿った色使い)の微細な差異を識別することが困難な場合もあるため、Visual Regression Testingが非常に重要です。

③プロセス
Visual Regression Testingのプロセスは以下です。:

  1. 基準画像の作成:テスト対象の画面の「正しい」状態を示すスクリーンショットを作成します。
  2. テスト実行:アプリケーションに変更を加えた後、新しいスクリーンショットを取得します。
  3. 画像比較:基準画像と新しいスクリーンショットを比較し、ピクセルレベルでの違いを検出します。
  4. 結果分析:違いが見つかった場合、それが意図的な変更かバグによるものかを分析します。

④利点
Visual Regression Testingの利点は、視覚的な変更がプログラムコードの変更によって意図せずに発生した場合でも、それを迅速に検出できることです。このテストは、特にUI/UXの変更が頻繁に行われるアジャイル開発や継続的インテグレーションの環境で有用です。また、人間の目では見逃してしまう微細な違いも検出することができます。Seleniumなどの自動テストライブラリと組み合わせて利用されることにより、視覚的な要素も効率的に検証され、テストプロセス全体が強化されます。これにより、質の高いアプリケーションの提供に貢献します。

⑤Visual Regression Testingの具体的な使用例

  1. UIの一貫性の担保:プロジェクト全体を通じてUIの一貫性を確保し、全てのユーザーに最適な体験を提供します。
  2. 意図しないUI変更の検出と対応:開発中に意図せずに発生したUIの変更やエラーを迅速に特定し、修正します。
  3. 自動化による効率化:手動での目視検査に比べて、自動化によるVisual Regression Testingは膨大な時間と労力を節約し、迅速なフィードバックを提供します。
  4. クロスブラウザ・クロスデバイスのUIの一貫性:異なるブラウザやデバイス間でのUIの一貫性を保証し、ユーザーにどの環境でも同様の体験を提供します。
  5. プラグインとコアソフトウェアの更新:アプリケーションのコアソフトウェアやプラグインが更新された際に、UIにどのような影響を与えるかを確認します。
  6. 外部ソフトウェアとAPIの問題:外部ソフトウェアやAPIの変更がアプリケーションのUIに影響を与えていないかをチェックします。

これらの使用例を通じて、Visual Regression Testingは開発プロセス全体の効率化と品質向上に寄与します。

Visual Regression Testing用ツールの紹介

Visual Regression Testingを実施するためのツールについて、3部に分けてご紹介します。
今回は、オープンソースソフトウェア (OSS)のaShotについてご説明いたします。
※将来的にはこのリストに他のツールが加わる可能性もあります。

# ツール タイプ 説明
1 aShot オープンソースソフトウェア (OSS) スクリーンショットのキャプチャと画像比較機能を提供し、視覚的なバグの検出に有効な無料で利用できるオープンソースのライブラリ。
2 Percy 有償サービス Visual testを自動化し、UIの変更を容易に検出できるライブラリ。
3 Applitools 有償サービス Visual AI技術を活用し、高度なビジュアル比較と分析を実行できるライブラリ。

1.aShotとは?

aShotは、スクリーンショットの取得から比較までを行うことができる無償のライブラリです。
本章では、スクリーンショット比較の機能について紹介いたします。

aShotのスクリーンショット比較の機能は、以下のソースコードに示されるように、二つの画像が完全に一致しているかを判断します。画像の高さや幅、カラーモデルが完全に一致していない場合、それらは差分として検出されます。目視では同じに見える画像でも、微妙なずれがあれば検出可能です。

public static boolean areImagesEqual(BufferedImage expected, BufferedImage actual) {
        return  expected.getHeight() == actual.getHeight() &&
                expected.getWidth() == actual.getWidth() &&
                actual.getColorModel().equals(expected.getColorModel()) &&
                areImagesBuffersEqual(expected.getRaster().getDataBuffer(), actual.getRaster().getDataBuffer());
}

差分が存在する場合、以下の処理を通じて二つのスクリーンショット間の差分をピクセル単位で検出します。無視すべき領域を考慮しつつ、差異のあるポイントを特定し、新しい画像に差分をマークします。

   protected void markDiffPoints(Screenshot expected, Screenshot actual, ImageDiff diff) {
        Coords expectedImageCoords = Coords.ofImage(expected.getImage());
        Coords actualImageCoords = Coords.ofImage(actual.getImage());

        CoordsSet compareCoordsSet = new CoordsSet(CoordsSet.union(actual.getCoordsToCompare(), expected.getCoordsToCompare()));
        CoordsSet ignoreCoordsSet = new CoordsSet(CoordsSet.intersection(actual.getIgnoredAreas(), expected.getIgnoredAreas()));

        int width = Math.max(expected.getImage().getWidth(), actual.getImage().getWidth());
        int height = Math.max(expected.getImage().getHeight(), actual.getImage().getHeight());
        diff.setDiffImage(createDiffImage(expected.getImage(), actual.getImage(), width, height));

        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {
                if (ignoreCoordsSet.contains(i, j)) {
                    continue;
                }
                if (!isInsideBothImages(i, j, expectedImageCoords, actualImageCoords)
                        || compareCoordsSet.contains(i, j) && hasDiffInChannel(expected, actual, i, j)) {
                    diff.addDiffPoint(i, j);
                }
            }
        }
    }

参考情報:https://github.com/pazone/ashot

2.aShotを使用したVisual Regression Testingの実践

本記事で前提とする技術スタック

  • Java 8 以降
  • Maven

依存関係追加

まずはMavenの依存関係を追加します。

<dependency>
    <groupId>ru.yandex.qatools.ashot</groupId>
    <artifactId>ashot</artifactId>
    <version>1.5.4</version>
</dependency>

スクリーンショット比較のソースコード

期待するスクリーンショットと実際のスクリーンショットを比較し、もし差分が存在する場合は、その差分を視覚的に示すスクリーンショットを生成する方法を紹介します。

//比較対象のスクリーンショットが保存されているパス
String actualPath = "capture\\actualImages\\";
//期待するスクリーンショットが保存されているパス
String expectedPath = "capture\\expectedImages\\";
//差分が検出された場合のスクリーンショットを保存するパス
String markedImages = "capture\\markedImages\\";

//比較対象のスクリーンショットを読み込む
Screenshot actual = new Screenshot(ImageIO.read(new File(actualPath + "screenshot.png")));
//期待するスクリーンショットを読み込む
Screenshot expect = new Screenshot(ImageIO.read(new File(expectedPath + "screenshot.png")));
//比較対象のスクリーンショットと期待されるスクリーンショットの比較
ImageDiff diff = new ImageDiffer().makeDiff(actual, expect);

int size = diff.getDiffSize();

if (size != 0) {
    //差分が検出された場合、スクリーンショット取得
    File diffFile = new File(markedImages + "comparisonResult.png");
    ImageIO.write(diff.getMarkedImage(), "png", diffFile);
 }	     

このコードは、最初に比較対象のスクリーンショットと期待されるスクリーンショットを読み込み、次に ImageDiffer クラスを使用して両者を比較します。差分のサイズ(diffSize)が0でない場合(差分が存在する場合)、差分がマークされた新しい画像を生成し、指定されたパスに保存します。このプロセスにより、Visual Regression Testingの精度を高め、UIの変更点を容易に特定することが可能になります。

差分が存在する場合、スクリーンショットが作成される

先ほど紹介したソースコードを実行すると、差分が存在する場合、自動的に特定のスクリーンショットが生成されます。
このスクリーンショットは、差分を視覚的に示すために作成され、分析やレビューに役立ちます。差分が含まれるスクリーンショットの詳細については、後ほど詳しく説明します。

実際の比較

①幅が変更された場合の比較結果

ウェブページの要素の幅を変更した際のaShotによる比較結果を示します。具体的には、ログインボタンの幅を1ピクセル狭くすることで、その影響を視覚的に確認します。

1 期待するスクリーンショット
これは変更前のウェブページのスクリーンショットで、期待されるデザインを示しています。

  1. 幅を1ピクセル狭くしたスクリーンショット
    この画像は、ログインボタンの幅を1ピクセルだけ狭く変更した後のウェブページのスクリーンショットです。

  2. 1ピクセル幅を狭くした場合の比較結果
    以下の画像は、期待するスクリーンショットと幅を変更したスクリーンショットとの比較結果し、差分が発生している部分には赤色が付けられています。この比較から、細かな変更点も明確に確認することができます。

②色が変更された場合の比較結果

ウェブページの要素の色を変更した際のaShotによる比較結果を示します。具体的には、ログインボタンの色を変更することで、その影響を視覚的に確認します。

  1. 期待値のスクリーンショット
    これは変更前のウェブページのスクリーンショットで、期待されるデザインを示しています。

  2. 色を変更したスクリーンショット
    こちらはログインボタンの色を白に変更した後のウェブページのスクリーンショットです。

  3. 色を変更した場合の比較結果
    下の画像では、元のスクリーンショットと色を変更したスクリーンショットを比較し、差分が発生している部分には赤色が付けられています。これにより、色の変更による影響が一目でわかります。

③類似色が変更された場合の比較結果

ウェブページの要素の類似色を変更した際のaShotによる比較結果を示します。具体的には、ログインボタンの文字の色を微妙に変更することで、その影響を視覚的に確認します。

  1. 期待値のスクリーンショット
    これは変更前のウェブページのスクリーンショットで、期待されるデザインを示しています。
    (色コード: #ff00ff)

  2. 類似色で変更したスクリーンショット
    次に、ログインボタンの文字色を類似色(#ff00ea)に変更し、その後のウェブページのスクリーンショットを取得します。

  3. 色を変更した場合の比較結果
    下の画像では、元のスクリーンショットと色を変更したスクリーンショットを比較し、差分が発生している部分には赤色が付けられています。これにより、細やかな色の変更も明確に確認することができます。

3.aShotライブラリのメリットとデメリット

実際にaShotを使用してみた経験をもとに、メリットとデメリットを以下にまとめました。ここでは私なりの考察と適応シナリオも含めて、参考として提供します。

aShotライブラリのメリット

  • 無料かつオープンソース
     aShotは無料で利用可能なオープンソースライブラリであるため、コストをかけずに導入できます。予算が限られているプロジェクトにとって、コストを抑えながらVisual Regression Testingの導入が可能になります。

  • 統合の容易さ
     aShotは、WebDriverをベースにした自動化フレームワークだけでなく、Microsoft Playwrightのような他の自動テストツールとも容易に統合できます。私の経験では、Microsoft Playwrightを使用してaShotを組み込み、既存の自動テストプロセスにVisual Regression Testingを導入できました。既存の自動テストフレームワークをそのまま活用しつつ、Visual Regression Testingの導入が可能になります。

  • 細かい比較が可能
     色や幅の比較を1ピクセル単位で行うことができ、非常に細かい変更も検出可能です。これにより、目視では見落としがちな細かな差分も検知することができます。

aShotライブラリのデメリット

  • 過敏な差分検出
     aShotは微細な差分を検出できますが、これが誤検出を引き起こす原因となることがありました。実際には問題のない差異も「差分あり」と判断されることがあり、その結果、本来無視すべき差分を誤って検出することがあります。
  • 安定性に課題
     導入は容易でしたが、特に複数の画面を持つウェブサイトのテストでは安定性の問題に直面しました。スクリーンショットのサイズを合わせたものの、私が検証した5つの画面遷移を伴うウェブサイトでは、変化がないにもかかわらず、どこかで差分ありと判定されるFlakyな状況が発生しました。これはネットワークの遅延やページのロード時間の違いによるもので、ピクセルレベルの差異が原因だと推測しております。
  • Ignoreの設定が条件付き
     Visual Regression Testingでは、タイムスタンプやカレンダー情報など可変フィールドを含む画面要素は事前にIgnore(無視)する設定を行う必要があります。これにより、不要なUI差分摘出を回避します。aShotを使用する際には、スクリーンショットの取得時にこのIgnore設定を行う必要があり、設定がない場合、比較時に特定の要素を無視できません。この設定は導入時の手間となり、特にクイックな導入を目指す場合には課題となる可能性があります。

aShotの適用シナリオ

aShotは特に、Javaの自動化フレームワークが既にある小規模なウェブプロジェクトや、目視では分からない微細な差分が重要なケースに適しています。しかし、画面数が多く、複雑なウェブサイトのテストにaShotを使用する場合、Flakyなテスト結果が生じる可能性が高いです。そのため、このような環境での導入はあまりお勧めしません。導入を検討する際は、プロジェクトの規模や複雑性を考慮して、aShotが本当に適したツールかどうかを慎重に判断することが重要です。

4.まとめ

Visual Regression TestingとしてaShotライブラリを試してみた結果、1ピクセル単位で細かな差分を検出できる点は大きなメリットでした。しかし、ウェブサイトの画面数が多い場合、安定性の確保が難しいという課題も明らかになりました。スクリーンショットを取得した時点で微細な差分が発生すると、本来差分のない画面も差分ありと判定されることがありました。また、差分の閾値を設定する際には、閾値が大きすぎれば重要な差分を見逃し、小さすぎれば無視すべき差分まで検出してしまう可能性がありました。

aShotはオープンソースで導入が容易な点が魅力ですが、高い精度が求められる場合やクイックなVisual Regression Testingを行う場合には、導入に際して慎重な検討が必要です。

以下は、差分の閾値を設定した例です。

int size = diff.getDiffSize();

       //スクリーンショットを比較し差分があるか判定
            if (size != 500) {
                //差分があった場合、スクリーンショットを作成
                File diffFile = new File(markedImages + "comparisonResult.png");
                ImageIO.write(diff.getMarkedImage(), "png", diffFile);
             }

今後も引き続き、より効果的なVisual Regression Testingが実施できるよう、さまざまなツールの検証を進めていきたいと思います。
次は有償サービスである「Percy」について、ご説明させていただこうと思います。楽しみにしていただけると嬉しいです。

それでは、皆様にとって充実したテストの時間を。Happy Testing!

仲間募集

Accenture Japan QE&Aでは、テスト自動化を通じてお客様の変革を支援しています。
同じビジョンを共有する仲間を募集しています!

https://www.accenture.com/jp-ja/careers/jobdetails?id=R00091947_ja

Accenture Japan SDET (Voluntary)

Discussion