« [IE8] Ajax Navigation | トップページ | Microsoft SharedView Ver.1 正式版リリース »

2008年5月12日 (月)

[VS2008] 手動テストのカバレッジ

MSDN フォーラム 「UTによるカバレッジの取得について」 で話題に出たことなんですが、  Visual Studio Team System 2008 (Dev. E) で、 WindowsForms や WPF の画面を手動でテストしたときのコードカバレッジを計測できるでしょうか?
結論を言ってしまえば、 フォーラムに書いたように、 「できます」。

サンプルコードを作ってみたので、 VSTS2008 を使える方はどうぞ。 → UITestCoverage.zip (20,426バイト) をダウンロード
※ VS2008 Pro. でも、 テスト部分は動きます。

20080512uitest_01 このソリューションの中の、 WindowsFormsApplication1 プロジェクトがテストターゲットです。 WindowsForms で作った、 シンプルな割り算を実行するだけの画面です。 ( WPF でも、 同じようにテストできます。 )

UITest1 プロジェクトは、 通常のユニットテストです。

TDD で開発するときの原則は、 出来る限りユニットテストしやすい構造にしましょう、 です。 それによって、 テストカバレッジが上がるだけでなく、 保守性にも良い影響を与えるはずです。
そのために、
・ 画面のイベントハンドラに書くコードは、 最小限にする。
・ ロジックはソースファイルが分かれている方が良いが、 Form と一緒になっていてもユニットテストは可能。 テストしやすいロジックにする。
…といったことに気を使ってあげましょう。
# 画面とロジックのつなげ方がだいたい決まったら、 あとはロジックを TDD で攻めていけば、 そんな形になるもんです f(^^;

UITest1 プロジェクトは、 画面を表示しない普通のユニットテストですが、 ロジック部分は 100% カバーできています。 Form1 クラスの手で書いた部分 ( 自動生成されなかった部分 ) も、 100% カバーできています。
20080512uitest_02

まぁ、 これはシンプルな画面だから出来たことで、 実際にはどうしても手動テストに頼らざるを得ないところが出てくるでしょう。

UITest2ByManual プロジェクトが、 手動テスト用です。
テストはひとつだけ。

[TestMethod()]
ublic void ManualTest()
{
    // 対象アプリを起動する
    Process proc = Process.Start("WindowsFormsApplication1.exe");

    // 終了するまで待機 … この間に、 手動で UI をテストする。
    while (!proc.HasExited)
    {
        Thread.Sleep(1000);
    }
    proc.Close();
    proc.Dispose();
}

この while ループ中で画面に対して行った操作は、 すべてユニットテストフレームワークの内部で処理されます。 テスト終了後に、 ちゃんとテストカバレッジを表示させられます。
20080512uitest_03

※ この画像は、 手動で 1 ÷ 0 だけを実行した結果です。 40行の 「return "ERR: 0除算";」 が実行された ( 青くなっている ) ことが分かります。

※ この手法、 VSTS2005 では試していません。 2005 でも出来たよ~、 って方は教えていただけると嬉しいです。

# これとは別の方法として、 UIAutomation を使ってテストコードから画面を操作するやりかたもありますが… それはまた、 機会があれば。

…って、 その UIAutomation を使う方法も、 5月15日に MSDN フォーラムに書きました。 こちらにも載せておきます。

 

UI Automation を直接使うのは面倒ですが、 John Robbins 氏が MSDN マガジン 2007年 3月号に発表してくれたラッパークラスを使うと楽になります。 → http://msdn.microsoft.com/ja-jp/magazine/cc163465.aspx

詳細は MSDN マガジンの記事を読んでいただきたいのですが、 テストコードのイメージはこんなふうになります。

using System.Windows.Automation;
using System.Windows.Automation.Peers;

using Bugslayer.TestTools.GuiAutomation;

// ...略...

  [TestMethod()]
  public void UITest()
  {
    // 対象アプリを起動する
    Process proc = Process.Start("foo.exe");

    Thread.Sleep(5000); // 本当はループを回して、win1 が取れるようになるのを一定時間まで待つべき。

    // AutomationElement クラスをラップした UIWindow を得る ( Bugslayer.TestTools.GuiAutomation )
    UIWindow win1 = new UIWindow(proc);

    // 結果を見たいテキストボックス
    UIEditControl resultText = ((UIEditControl)win1.FindChild("textBoxResult"));

    // 実行ボタンクリック
    ((UIButton)win1.FindChild("buttonDoExec")).Click();

    Thread.Sleep(1000); // 本当はループを回して、resultText.Value が変わるのを一定時間まで待つべき。

    // 結果を判定
    Assert.AreEqual("bar", resultText.Value);

    // ウィンドウを閉じる
    win1.SendKeys("%{F4}");

    proc.Close();
    proc.Dispose();
  }

 

( 2008/06/04 追記 ) Bugslayer.TestTools.GuiAutomation を利用せずに直接 UI Automation を使うやり方が、  @IT に掲載されています。 → UI オートメーションによる自動 UI テストの実践 ( 2008/06/03 )
読んでいただくと分かりますが、 かなり面倒です。

|

« [IE8] Ajax Navigation | トップページ | Microsoft SharedView Ver.1 正式版リリース »

プログラミング」カテゴリの記事

* プログラミング ( WPF )」カテゴリの記事

コメント

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: [VS2008] 手動テストのカバレッジ:

» [VS2008] どんなテストでもカバレッジ [biac の それさえもおそらくは幸せな日々@nifty]
以前に、 手動テストのカバレッジを取るのための TestMethod を作る方法を書いたけど。 そんな必要も無かったらしい。 Scrabble.NET » Blog Archive » NUnitとVSTSのCode Coverageを連携させる つまり、 vsinstr.exe で対象の dll / exe を指定し... [続きを読む]

受信: 2008年6月24日 (火) 18時30分

« [IE8] Ajax Navigation | トップページ | Microsoft SharedView Ver.1 正式版リリース »