ユーザー コード リファレンス:フルスクリーンショットのイメージ比較

Ranorexでは、バリデーションアクションのイメージ比較をおこなう条件として、比較対象のイメージがデスクトップ上に表示されている必要があります。そのためWebアプリケーションなどのスクロールが必要なWebブラウザーの画面全体に対してイメージ比較をおこなうことは、隠れた部分のイメージが比較対象にならないことから難しいものとなります。

このような場合、テスト実行時に取得したフルスクリーンショット(※1)を使用して、次のようなイメージ比較の方法があります。

  • 目検で確認をおこなう。
  • 他ツール(WinMergeなど)を使用してイメージ比較をおこなう。
  • 画面に表示される程度のオブジェクト(画面全体ではなく、divブロック要素単位など)単位で、バリデーションアクションでイメージ比較をおこなう。
  • Ranorex APIのImaging.Compareメソッドを使用してイメージ比較をおこなう。

今回は、この方法の中からユーザーコードを使用する方法として、Ranorex APIのImaging.Compareメソッドを使用したイメージ比較について紹介します。

※1.Webアプリケーションのテストでは、RanorexのオートメーションヘルパーにあるWebLibraryライブラリのReportFullPageScreenshotメソッド、またはRanorex APIにあるWebDocument.CaptureFullPageScreenshotメソッドを使用することでスクロールによるスクリーンショットを取得することがでます。

※本記事で紹介しているRanorex APIは、Ranorex v9.3.2にて確認をおこなっています。

※ユーザー コードの機能概要については、こちらの記事をご参照ください。

※本記事で紹介しているRanorex APIについては、API ドキュメントをご参照ください。

Imaging.Compareメソッド

Imaging.Compare(Bitmap imgA, Bitmap imgB)

このメソッドは、第1、2パラメーター(Bitmap型)として渡された2つのイメージ情報を比較します。メソッドの戻り値として、比較した結果を類似度として返します。なお比較するイメージサイズが異なる場合は”“を返します。

public static double Compare(
	Bitmap imgA,
	Bitmap imgB
)

Imaging.Compare(Bitmap imgA, Bitmap imgB, double similarity)

このメソッドは、第1、2パラメーター(Bitmap型)として渡された2つのイメージ情報を比較します。また比較した際の類似度(similarity)を第3パラメーターとして指定することができます。
メソッドの戻り値として、比較したイメージの結果がパラメーターで指定した類似度以上である場合は”真”true)を返し、類似度未満もしくは比較するイメージサイズが異なる場合は”“(false)を返します。

public static bool Compare(
	Bitmap imgA,
	Bitmap imgB,
	double similarity
)

Imaging.Compare(Bitmap imgA, Bitmap imgB, Imaging. FindOptions options)

このメソッドは、第1、2パラメーター(Bitmap型)として渡された2つのイメージ情報を比較します。またイメージ比較のオプションを第3パラメーターとして指定することができます。
メソッドの戻り値として、比較したイメージの結果がパラメーターで指定した類似度以上である場合は”真”true)を返し、類似度未満もしくは比較するイメージサイズが異なる場合は”“(false)を返します。

public static bool Compare(
	Bitmap imgA,
	Bitmap imgB,
	Imaging.FindOptions options
)

イメージ比較の方法

事前に比較するための2つのフルスクリーンショットを取得した後、Imaging.Compareメソッドにてイメージ比較をおこなうテストを作成します。

ユーザーコードにおいて、以下のようなイメージ比較をおこなうためのメソッドを作成します。

サンプルコード:

Imaging.Compare(Bitmap imgA, Bitmap imgB)メソッドを使用した場合

/// <summary>
/// 第1パラメーター:比較イメージの画像ファイル名を含むパス(絶対パス)
/// 第2パラメーター:比較イメージの画像ファイル名を含むパス(絶対パス)
/// </summary>
public void diffImg(string imgA, string imgB)
{
	// 比較するイメージファイルを取得
	Bitmap bitmapA = Ranorex.Imaging.Load(imgA);
	Bitmap bitmapB = Ranorex.Imaging.Load(imgB);

	// 合格とする類似度を指定
	double similarity = 1.0;
			
	// イメージ比較
	double result = Ranorex.Imaging.Compare(bitmapA, bitmapB);
	if( similarity <= result )
	{
		// イメージ比較の結果、差分無し
		Report.Log( ReportLevel.Success, "similarity(1.0)", result.ToString() );
		Report.LogData( ReportLevel.Success, imgA, bitmapA );
		Report.LogData( ReportLevel.Success, imgB, bitmapB );
	} else {
		// イメージ比較の結果、差分有り
		Report.Log( ReportLevel.Failure, "similarity(1.0), result.ToString() );				
		Report.LogData( ReportLevel.Failure, imgA, bitmapA );
		Report.LogData( ReportLevel.Failure, imgB, bitmapB );
	}
}

Imaging.Compare(Bitmap imgA, Bitmap imgB, double similarity)メソッドを使用した場合

/// <summary>
/// 第1パラメーター:比較イメージの画像ファイル名を含むパス(絶対パス)
/// 第2パラメーター:比較イメージの画像ファイル名を含むパス(絶対パス)
/// 第3パラメーター:類似度
/// </summary>
public void diffImg(string imgA, string imgB, double similarity)
{
    	// 比較するイメージファイルを取得
       	Bitmap bitmapA = Ranorex.Imaging.Load(imgA);
       	Bitmap bitmapB = Ranorex.Imaging.Load(imgB);
            
       	// イメージ比較
       	if(Ranorex.Imaging.Compare(bitmapA, bitmapB, similarity))
       	{
       		// イメージ比較の結果、差分無し
		Report.Log( ReportLevel.Success, "similarity", similarity.ToString() );
       		Report.LogData( ReportLevel.Success, imgA, bitmapA );
       		Report.LogData( ReportLevel.Success, imgB, bitmapB );
       	} else {
       		// イメージ比較の結果、差分有り
		Report.Log( ReportLevel.Failure, "similarity", similarity.ToString() );
      		Report.LogData( ReportLevel.Failure, imgA, bitmapA );
       		Report.LogData( ReportLevel.Failure, imgB, bitmapB );
       	}
}

Imaging.Compare(Bitmap imgA, Bitmap imgB, Imaging. FindOptions options)を使用した場合

/// <summary>
/// 第1パラメーター:比較イメージの画像ファイル名を含むパス(絶対パス)
/// 第2パラメーター:比較イメージの画像ファイル名を含むパス(絶対パス)
/// 第3パラメーター:類似度
/// </summary>
public void diffImg(string imgA, string imgB, double similarity)
{
	// 比較するイメージファイルを取得
	Bitmap bitmapA = Ranorex.Imaging.Load(imgA);
	Bitmap bitmapB = Ranorex.Imaging.Load(imgB);

	// イメージ比較のオプション 			
	Ranorex.Imaging.FindOptions options = new Ranorex.Imaging.FindOptions();
	options.Similarity = similarity;
		
      	// イメージ比較
       	if(Ranorex.Imaging.Compare(bitmapA, bitmapB, options))
       	{
       		// イメージ比較の結果、差分無し
		Report.Log( ReportLevel.Success, "similarity", similarity.ToString() );
       		Report.LogData( ReportLevel.Success, imgA, bitmapA );
       		Report.LogData( ReportLevel.Success, imgB, bitmapB );
       	} else {
       		// イメージ比較の結果、差分有り
		Report.Log( ReportLevel.Failure, "similarity", similarity.ToString() );
       		Report.LogData( ReportLevel.Failure, imgA, bitmapA );
       		Report.LogData( ReportLevel.Failure, imgB, bitmapB );
       	}
}

また、取得したフルスクリーンショットを出力するためのユーザーコードを用意します。
※オートメーションヘルパーでもフルスクリーンショットを出力することができますが、出力するイメージファイルの名前などを指定できないため、ユーザーコードにてRanorex APIを使用します。

サンプルコード:

/// <summary>
/// 第1パラメーター:フルスクリーンショットを取得したいリポジトリ(アプリフォルダー)
/// 第2パラメーター:フルスクリーンショットの出力先(例:C:\tmp\imgA.png)
/// </summary>
public void fullScreenshot(RepoItemInfo itemInfo, string outputImgFile)
{
	// フルスクリーンショットの取得
	Bitmap screenShot = itemInfo.FindAdapter<WebDocument>().CaptureFullPageScreenshot();

	// フルスクリーンショットの出力
	screenShot.Save(outputImgFile);
		
	// レポート出力
	Report.LogData( ReportLevel.Info, "スクリーンショット", screenShot );
}

フルスクリーンショットを出力するメソッドと、イメージ比較をおこなうメソッドのパラメーターに渡すイメージファイルの出力先の情報を、レコーディングモジュールの変数で持たせることでレコーディングモジュール内においてメソッド間でデータの受け渡しがおこなえます。
また、メソッドがレコーディングモジュールをまたぐ場合は、パラメーターを使用することでデータの受け渡しがおこなえます。

まとめ

今回、紹介した方法は、バリデーションアクションのイメージ比較(ContainsImageCompareImage)のように細かい設定(マスク機能など)やイメージ比較の結果として差分があった場合に差分個所がレポートされないなどの制限事項があります。
テストケースの内容によっては、今回、紹介した方法を使用することで、逆にメンテナンスなどでコストがかかることも考えられます。そのため、どのような方法でバリデーションをおこなうかは、テスト内容に合わせて選択されることをお勧めします。