.NETテストプログラミング入門7
前回例として提示したGUIプログラミングのサンプルをテストするには次のようにします。
using System;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
class WpfTest
{
[STAThread]
static void Main()
{
//型を取得(※AssemblyQualifiedNameを使用する)
Type piyoType = Type.GetType( "PiyoWindow, WpfTest_Target, " +
"Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" );
//テストの準備
Window target = ( Window ) Activator.CreateInstance( piyoType );
StackPanel panel = ( StackPanel ) target.Content;
TextBox box = ( TextBox ) panel.Children[ 0 ];
Button btn = ( Button ) panel.Children[ 1 ];
Label label = ( Label ) panel.Children[ 2 ];
//値を設定してからクリックイベントを呼び出す
string inputValue = "テスト";
box.Text = inputValue;
MethodInfo method = typeof( Button ).GetMethod( "OnClick",
BindingFlags.NonPublic | BindingFlags.InvokeMethod |
BindingFlags.Instance );
method.Invoke( btn, null );
//値をチェック
string right = inputValue + "ピヨ♪";
bool result = right.Equals( label.Content );
Console.WriteLine(
result == true ? "テスト成功" : "テスト失敗" );
}
}
このコードを見れば、GUIのテストが意外と簡単である事が分かると思います。GUIのテストは通常のプログラミング以外のなにものでもありません。リフレクションとWPFを知っていれば自然に思いつく方法です。これはテスト対象が簡単である事も影響していますが、テスト対象がサンプルよりも複雑であっても、テストコードの行数が増えるだけで考えそのものは変わりません。GUIテストに於いて重要なポイントは3つしかありません。
1つめのポイントは、非公開のクラスを呼び出す方法です。大概のアプリケーションは、そのアプリケーションしか使わない独自ウィンドウを公開したくありません。公開していないクラスを呼び出す方法は、.NETやJavaの場合はリフレクションです。他の言語の場合、違う方法でハックすれば同様の事が出来ます。アクセス修飾子の問題はテストに於いてよくある事なので、プログラマは非公開のクラスのインスタンスを生成する方法を習得するべきだと言えます。
2つめのポイントは、イベントを発生させる方法です。GUIもただのプログラムです。人間がクリックせねば絶対に動かないわけではありません。それどころかコンピュータはOSの働きもあり、イベントを呼び出す相手が人間の操作なのかプログラムなのかを気にしません。どのようなGUIフレームワークにも、コードでイベントを呼び出す方法があるはずです。今回はリフレクションが簡単なのでそうしましたが、他のリフレクションがない言語でも同様の事が出来るでしょう。
3つめのポイントは、仕様をはっきりさせる事です。どのコントロールが、どのようにして値を付け取り、どのような値を出力するのかを明確にせねばなりません。仕様が明確に定められていないとテストが出来ません。これはあくまでも私個人の感覚ですが、現場ではこの点を見過ごして、「GUIテストは難しいから人がチェックする」と言っている人が多いと感じています。確かにGUIの美的感覚をプログラムをチェックできません。ですが、全てのGUIプログラムの動作はチェックできます。テストできる部分は絶対にするべきです。GUIプログラムはテスト出来ないからバグがあるという言い訳はクライアントに通用しません。
どうやら、GUIプログラミングはどう見えるのかばかりが意識され、プログラム的にどういう動きなのかを見過ごす傾向があるようです。該当しないチームも多々存在するでしょうが、そうでないプロジェクトチームはそもそもGUIプログラムのテストを実施しているはずです。
駆け足でテストプログラミングについて書きました。この連載でテストプログラミングが通常のプログラミングである事が分かったと思います。この連載がテストは難しいと忌避する考えを変え、信頼性が高いシステムがつくられる一助になれば幸いです。