a2 Tech blog

試したこと・調べたこと・感じたことを発信するITエンジニアの日記です。仕事とは直接関係ないけど興味あることを模索していきます。

Coded UI Testで画面キャプチャを独自に撮る方法

f:id:ninna2:20170411015358j:plain:w360

Coded UI Test において Visual Studio の機能を使って画面キャプチャを自動取得する方法は「前回の投稿」で書きました。ただ、どうしても任意のタイミングで取得したいと言う要望は上がると思います。今回はテスト実行時の自分の好きなタイミングで画面キャプチャを取る実装方法について記載しておこうと思います。

ninna2.hatenablog.com

はじめに

前提として、①Visual Studio のインストール、②コード化されたUIテストのプロジェクト作成、③テストオペレーションの記録、テスト実施までできていることとします。まだの方は是非、「UIテストコード化はじめの一歩」を参照して準備してみてください。

ninna2.hatenablog.com

UIMapクラスについて

UIMapクラスは partial クラスで、UIMap.Designer.cs ファイルと UIMap.cs ファイルの2ファイルから成り立ちます。この2つの関係性について理解しておく必要があります。Coded UI Test では、UI テストビルダーを用いてテストオペレーションの記録を行います。UI テストビルダーによる自動生成コードは、UIMap.Designer.cs ファイルにコードが生成されます。そして、Coded UI Test のベストプラクティスには、UIMap.Designer.cs ファイルは変更しないように記述されています。

UIMap.designer.cs ファイルは直接変更しないでください。 このファイルを直接変更すると、その変更内容が上書きされます。 引用 : コード化された UI テストのベスト プラクティス

では、生成したコードに対してなにか処理を加えるなどのカスタマイズをしたい場合はどうするのか?と言うと疑問が生まれると思います。その場合は、UIMap.designer.csファイルの内容を、UIMap.csファイルに移してからカスタマイズします。もちろん、わざわざ自分で移すわけではなく、Visual Studio の機能として提供されています。

UIMap.Designer.cs ファイルと UIMap.cs ファイルをまとめている UIMap.uitest を開き、移動させたいメソッドを選択し、Uimapへ移動としてください。そうすると必要なものが全て移動されます。これで、カスタマイズしても、自動生成で上書きされることはないわけですね。ただし、移動すると、以降の変更はUIテストビルダーは使用できないので、全てコードから変更しないといけないので注意してください。

画面全体をキャプチャする実装

ここまでできたら、あとはカスタマイズを個別のメソッドに対して入れていきます。まず、初めに行いたいことは、TestContextに含まれる情報を利用したいので、移動したメソッドに引数を増やします。TestContextを引数に指定して渡すように変更してください。もちろん呼び出し側がコンパイルエラーになるので、呼び出し側も変更してくださいね。

public partial class UIMap
{
    /// <summary>
    /// RecordedMethod - このメソッドにパラメーターを渡すには 'RecordedMethodParams' を使用します。
    /// </summary>
    public void RecordedMethod(TestContext testContextInstance)
    {
        // 省略
    }
}

そのうえで、下記のコードを画面キャプチャを撮りたい箇所に入れてください(今回特に共通化とか全く考えてないのですが本来は共通メソッドにしておくべきです)。このサンプルコードでは、出力先は、TestDeploymentDirにしています。ファイル名も「テストメソッド名 + 任意の文字列」とかにしているので、それぞれで適当にカスタマイズしてください。

int display_h = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;
int display_w = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;

using (Bitmap bm = new Bitmap(display_w, display_h))
{
    using (Graphics gr = Graphics.FromImage(bm))
    {
        gr.CopyFromScreen(new Point(0, 0), new Point(0, 0), bm.Size);
        String testDir = testContextInstance.TestDeploymentDir;
        String testMethodName = testContextInstance.TestName;
        String imageFileName = testMethodName + "任意文字列" + ".png";
        bm.Save(imageFileName, System.Drawing.Imaging.ImageFormat.Png);
    }
}

これでテストを実行すると、実行時に画面キャプチャが保存されているはずです。 最後に、全体のソースコードの様子を載せておきます。

public partial class UIMap
{
    /// <summary>
    /// RecordedMethod - このメソッドにパラメーターを渡すには 'RecordedMethodParams' を使用します。
    /// </summary>
    public void RecordedMethod(TestContext testContextInstance)
    {
        // テストオペレーション(自動生成コード)
        // 省略

        int display_h = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;
        int display_w = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
        using (Bitmap bm = new Bitmap(display_w, display_h))
        {
            using (Graphics gr = Graphics.FromImage(bm))
            {
                gr.CopyFromScreen(new Point(0, 0), new Point(0, 0), bm.Size);
                String testDir = testContextInstance.TestDeploymentDir;
                String testMethodName = testContextInstance.TestName;
                String imageFileName = testMethodName + "任意文字列_all" + ".png";
                bm.Save(imageFileName, System.Drawing.Imaging.ImageFormat.Png);
            }
        }

        // 自動生成コード
        // 省略
    }
}

今回は簡単ですが、参考になればと思います。