コードなしの WPF テスト自動化と WinForms UI テスト (アクセシビリティツリーなしでも)
コードなしの WPF テスト自動化と WinForms UI テスト: アプリがテストツールに公開するもの、隠すもの、そしてビルドのたびにテストを記録し、検証し、実行する方法。
読了 10 分執筆: Ait Nohaila (事業開発担当)
短い答え
WPF アプリケーションの UI テストを自動化するには、GUI Test Studio でワークフローを 1 回記録します: すべてのクリック、キー、アサーションが、各コントロールをアプリのアクセシビリティ情報で、アプリが何も伝えないときは見た目で見つけるテストになります。
このガイドは、WPF や Windows Forms (WinForms) のアプリケーションをテストする QA エンジニアや開発者向けです。そうしたアプリがテストツールに何を伝え何を隠すかを示し、テストを手順を追って記録し、再設計に耐えるアサーションを選び、ビルドのたびにテストを実行し、コード中心のライブラリのほうが今でも良い選択となるのはどんなときかを説明します。
WPF や WinForms のアプリがテストツールに公開するもの、隠すもの
WPF も WinForms も、標準のコントロールを UI Automation を通じて Windows に伝えます: 種類、名前、画面上の位置、そして開発者が設定していれば AutomationId です。スクリーンリーダーはその説明を使い、ロケーターでコントロールを見つけるテストツールもすべてそれを使います。同じアプリには、まったく何も伝えないコントロールもあります。
| コントロールの種類 | UI Automation に見えるもの | テストの見つけ方 |
|---|---|---|
| AutomationId のある標準の WPF コントロール: Button、TextBox、ListView、DataGrid | 種類、名前、位置、開発者が付けた id | アプリが伝える内容で、すぐに |
| 標準の WinForms コントロール: Button、TextBox、DataGridView | 種類、テキスト、そして設定されていれば id としてのコントロールの Name | アプリが伝える内容で |
| コントロールが既定の名前のままの WinForms アプリ | 種類とテキスト、そして button1 のようなほとんど意味のない id | コントロールのテキストと位置で、そして見た目で |
| アプリが自分で描画するコントロール: チャート、ゲージ、リボン、キャンバス | 開発者がアクセシビリティを実装していない限り、四角形だけ | 見た目で |
| オーナー描画のグリッドやリスト | セルのない行、または仮の名前の付いたセル | 見た目で、セルごとに |
| サードパーティのコントロールスイート | ベンダーによります: 完全な説明から、単一のペインだけまで | アプリが伝える場合はその内容で、伝えない場合は見た目で |
| 画像、アイコン、図 | テキストのない画像 | 見た目で |
Microsoft 自身のドキュメントには、UI Automation プロバイダーのないコントロールは UI Automation からほとんど見えず、その位置程度しか報告できないと書かれています。アクセシビリティツリーのない Windows アプリには、これが例外ではなく当たり前になっているアプリケーションの種類が挙げられています。
WPF アプリケーションの自動テスト: 手順を追って記録する
WPF アプリケーションの自動テストは、GUI Test Runner-Recorder での 1 回の記録から始まります。アプリには何も追加しません: テスト用ビルドも、ライブラリも、もともとなかった AutomationId も不要です。以下の例では受注入力アプリを記録しますが、WinForms アプリも同じ方法で記録します。すべてのオプションについてはテストを記録するを参照してください。
- 1
「記録」をクリック
GUI Test Runner-Recorder を開き、記録をクリックしてください。アプリを、テストを始めるべき状態にしてください: ワークフローの最初の画面で、その上にほかには何も開いていない状態です。
- 2
「何をテストしますか?」に「アプリ」で答える
アプリを選び、実行中のプログラムの中から自分のプログラムを選ぶか、まだ開いていなければその .exe を参照してください。テストと一緒にアプリを起動して最後に閉じるチェックボックスをオンにすると、すべての実行がまっさらなアプリから始まります。
画面全体が常に記録されます。「アプリ」を選んで決まるのは、自動アサーションをどこから生成するかだけです。 - 3
テスターと同じようにアプリを使う
顧客の名前を入力し、リストから製品を選び、「保存」をクリックして、確認メッセージを読んでください。すべてのクリックとキーが記録され、クリックした各コントロールの画像が、クリックする直前に切り取られます。ワークフローが終わったら停止キーを押してください。
- 4
「このテストで何を検証しますか?」に答える
3 枚のカードで、テストが何を検証するかを尋ねます: クリックしたビジュアル要素、画面上のテキスト、そしてダイアログや確認メッセージのように作業中に表示されたものです。最初のテストでは既定のままにして保存してください。
アサーションは記録の後、アプリの動きを見たばかりのときに選びます。 - 5
テストが専用のフォルダーに保存され、実行される
Orders という名前のテストは、専用のフォルダーに
Orders\Orders.GTSとして保存され、すべての実行の結果と履歴もその横に保管されます。テストを実行をクリックしてください: テストはクリックとキーを、各コントロールが今ある場所に向けて実際の入力として再生し、何が合格し何が変わったかを伝える信頼度レポートで終わります。
- 次の実行で各コントロールがどう見つかるかは、記録が各コントロールについて残した内容で決まります。保存ボタンについては、アプリは Button、Save、SaveButton と伝え、テストはそれをボタンの画像の横に残します。チャートについては、アプリは残す価値のあることを何も伝えなかったので、画像だけでそれを見つけます。
記録を省き、Claude、ChatGPT、またはローカル AI モデル (当社が提供するモデルか、持ち込んだモデル) にワークフローをプロンプトで説明することもできます: テストは同じ方法で、同じアサーションとともに作成されます。
WinForms の UI テスト: 再設計に耐えるアサーション
WinForms の UI テストの成否は、WPF のテストと同じく、本当の変化を捉えて無害な変化を無視するアサーションにかかっています。GUI Test Studio には 3 種類があり、それぞれがテストのタイムライン上のブロックで、チームの誰でも追加、移動、編集できます。
ビジュアルアサーション
ビジュアルアサーションは、要素が画面上にあり、記録どおりに見えることを検証します: ツールバーのアイコン、ステータスランプ、同じ曲線を示すべきチャートなどです。テキストアサーションは要素が表示する言葉を、まずアプリに問い合わせ、アプリが答えられないときは画面を読んで検証し、動的テキストアサーションは注文番号のように変化する値をその形式で受け入れます。レイアウトアサーションは画面の要素が記録どおりに配置されていることを検証するので、それぞれの要素が正しく見えていても、移動した列や位置がずれたボタンを捉えます。
3 種類とも、どの画面にもあるノイズは無視しつつ、人が変化と呼ぶものは捉えます: 間違った色、欠けたアイコン、大文字と小文字が変わった単語、位置がずれたコントロールなどです。ビジュアルアサーションでは、それぞれの設定を順に説明しています。
検索範囲
すべてのアサーションは、要素が記録された場所の周囲の範囲である検索範囲の中で、その要素を探します。検索範囲はよく似た要素を区別します: ツールバーの保存ボタンとダイアログの保存ボタンは、それぞれの位置で見分けられます。1 秒たっても検索範囲の中で要素が見つからないアサーションは画面全体も探すので、もっと右に開いたウィンドウでテストが不合格になることはなく、信頼度レポートには要素が見つかった場所が示されます。
コントロールの背後にあるコードの再設計
- テストは、WPF や WinForms のアプリが経るさまざまな変更を通して動き続けます。WinForms から WPF に書き直されたコントロールも見つかります: アプリは引き続きその名前を伝え、見た目も同じだからです。別のパネルに移動したコントロールは、今ある場所で見つかります。クラス名の変更や新しいコントロールライブラリは、テストが頼りにしているものを何も変えません。
ダークテーマ、ハイコントラストテーマ、別の言語
アプリのアクセシビリティ情報はテーマによって変わらないので、アプリに問い合わせるアサーションはライトでもダークでも同じように成り立ちます。ビジュアルアサーションが比較する画像は変わりますが、ベースラインプロファイルは環境ごとに期待されるバージョンを 1 個ずつ保持します: 「ダークモード」プロファイルでテストを実行し、信頼度レポートで新しい見た目をそれぞれ 1 回採用すれば、同じテストがライトの見た目とダークの見た目を、それぞれ正しいバージョンと照らして検証します。
ロケーターはコードが変わると壊れます。アプリに問い合わせて画面を見るアサーションが壊れるのは画面が間違っているときだけであり、それこそが望ましい唯一の失敗です。
ビルドのたびに実行する Windows デスクトップのテスト自動化
Windows デスクトップのテスト自動化は、誰かが起動しなくても実行されるときに真価を発揮します。コマンドライン実行ツールの gtr-cli は、「テストを実行」ボタンとまったく同じようにテストを実行し、パイプラインが期待するとおりに応答します: 不合格のテストはビルドを失敗させ、JUnit ファイルがテストタブを埋め、失敗したもののすべての画像が同じフォルダーに保管されます。
gtr-cli run tests --countdown 0 --junit results\junit.xml --artifacts results\artifactsオプションで CI ツールを指定すると、プラグインをインストールしなくても、失敗がそのツール自身のログに注釈やテスト項目として表示されます:
| CI ツール | コマンド | ツールに表示される内容 |
|---|---|---|
| TeamCity | gtr-cli run tests --countdown 0 --format teamcity --artifacts results\artifacts | 「Tests」タブのすべてのテストと、理由付きの失敗 |
| Azure DevOps | gtr-cli run tests --countdown 0 --format azure --junit results\junit.xml --artifacts results\artifacts | 失敗ごとのログコマンドと、「Tests」タブの JUnit ファイル |
| GitHub Actions | gtr-cli run tests --countdown 0 --format github --junit results\junit.xml --artifacts results\artifacts | 実行上の失敗ごとの注釈と、ダウンロードできるアーティファクトフォルダー |
デスクトップのテストは実際の画面で再生されるため、ビルドエージェントにはロックされていない Windows デスクトップセッションが必要です: 画面サイズが固定された仮想マシンが適しています。パイプラインでテストを実行するにはすべてのオプションが、ビルドのたびにエンドツーエンドテストを実行するには TeamCity のビルドを手順を追って設定する方法が、Jenkins、GitHub Actions、GitLab、Azure DevOps 向けの同じコマンドとともに載っています。
FlaUI、pywinauto などの WPF UI テストツール: コードが正しい選択であるとき
それ以外に開発者が手を伸ばすのは、2 個のオープンソースライブラリです。FlaUI は、WPF や WinForms を含む Windows アプリケーションの UI 自動テスト用の .NET ライブラリで、C# で書かれたテストのために Microsoft の UI Automation ライブラリをラップしています。GitHub ページによると、pywinauto は Windows の GUI を自動化するための Python モジュール群で、2 種類のバックエンドを持ちます: 既定の Win32 API と UI Automation です。
どちらも、コントロールがすべてアクセシブルなコード中心のチームには妥当な選択です: テストはアプリ自身のリポジトリに、チームが毎日書く言語で、ユニットテストの横に置かれ、コントロールツリーを知っている開発者は各要素に正確なロケーターを書けます。そのコストは、すべてのロケーターと、それを変えてしまうすべての再設計のために開発者の時間で支払われ、アプリが説明しない要素には別の手段が必要です。
両者は敵同士ではありません。カスタムコントロールだらけの WPF アプリを持つチームは、ユニットテストはコードのまま残し、エンドツーエンドテストは記録することがよくあり、そうすればワークフローを最もよく知る人がそれを保守でき、アプリが説明しないコントロールもテストされます。
要点
- 1WPF と WinForms は標準のコントロールを説明しますが、チャート、ゲージ、オーナー描画のグリッド、多くのサードパーティ製コントロールについては何も伝えません。
- 21 回の記録で両方の種類をテストできます: GTS Engine + AI はまずアプリに問い合わせ、アプリが何も伝えないときはコントロールを見た目で見つけます。
- 3再設計に耐えるアサーションを選んでください: ビジュアルアサーション、テキストアサーション、レイアウトアサーションは画面が間違っているときにだけ不合格になり、ダークテーマはベースラインプロファイルでカバーできます。
- 4gtr-cli を使えば、ビルドのたびに TeamCity、Azure DevOps、GitHub Actions、Jenkins、GitLab で、ロックされていない Windows デスクトップ上でテストを実行できます。
- 5コントロールがすべてアクセシブルなコード中心のチームには、FlaUI と pywinauto も今なお有効ですが、そのコストはロケーターごとにかかる開発者の時間です。
よくある質問
WPF アプリケーションの UI テストはどのように自動化しますか?
GUI Test Studio でワークフローを 1 回記録します: テスターと同じように、アプリを開き、クリックし、入力し、表示される内容を読みます。すべての操作とすべてのアサーションがコードなしのテストになり、gtr-cli がビルドのたびにそれをもう一度実行します。各コントロールは、アプリのアクセシビリティ情報で、アプリがそれについて何も伝えないときは見た目で見つかります。
AutomationId のない WinForms アプリもテストできますか?
はい。標準の WinForms コントロールは種類とテキストを報告し、役に立つことを何も報告しないコントロールは、画面上の画像によって見た目で見つかります。テストが動くために、アプリケーションに何かを追加する必要はありません。
テスト自動化のために、WPF アプリに AutomationId を追加する必要はありますか?
GUI Test Studio なら必要ありません。AutomationId があるとアプリがコントロールを正確に名指しするので役に立ち、ある場合は GUI Test Studio がそれを保持します。なければ、コントロールの名前、種類、位置、そして画像で十分です。
WPF アプリの独自描画のコントロールやサードパーティ製コントロールはどのようにテストしますか?
見た目でテストします。チャート、ゲージ、オーナー描画のグリッド、サードパーティ製コントロールは、Windows には空の四角形しか見せないことがよくあります。GUI Test Studio はそうしたコントロールを検索範囲の中でその画像によって見つけ、実際のマウスとキーボードの入力で操作し、表示される内容も同じ方法で検証します。
コードを必要としない FlaUI の代替は何ですか?
GUI Test Studio です。FlaUI は C# のコードから Windows UI Automation を動かす .NET ライブラリなので、テストプロジェクトのすべての要素にロケーターが必要です。GUI Test Studio は代わりにワークフローを記録し、アプリのアクセシビリティ情報を自動で保持し、アプリが説明しないものは見た目で見つけます。
WPF のテスト自動化はダークテーマでも機能しますか?
はい。アプリのアクセシビリティ情報はテーマによって変わらず、画像を比較するアサーションについては、ベースラインプロファイルがテーマごとに期待されるバージョンを 1 個ずつ保持します。同じテストがライトの見た目とダークの見た目に対して実行され、それぞれを正しいバージョンと比較します。
WPF や WinForms のテストを CI/CD パイプラインで実行できますか?
はい。gtr-cli は、ロックされていないデスクトップセッションのある Windows ビルドエージェントでテストを実行し、テストが不合格ならビルドを失敗させ、JUnit ファイルを書き出し、失敗のすべての画像を保管します。TeamCity、Azure DevOps、GitHub Actions、Jenkins、GitLab で使えます。
アプリケーションの中に何かをインストールする必要はありますか?
いいえ。GUI Test Studio は画面を見て、アプリがすでに自分自身について説明している内容を Windows に問い合わせ、人と同じようにマウスとキーボードを使います。アプリの中にはライブラリも、テスト用ビルドも、エージェントもありません。
Microsoft、Windows、WPF、Windows Forms、FlaUI、pywinauto、TeamCity、Azure DevOps、GitHub、GitLab、Jenkins は、それぞれの所有者の商標またはプロジェクトです。
テスト対象のアプリでご覧になりますか? チームとの 30 分の無料相談を予約してください。