Windowsアプリケーションのテスト
そうか、Windowsアプリのウインドウとかコンポーネントも単なるクラスだから、大抵の内容なら普通にテストができるんだ…。Webアプリ脳なので何かSeleniumみたいなものが必要なのかと漠然と思い込んでた。
こんな適当なWindowsアプリケーションがあったら
using System; using System.ComponentModel; using System.Data; using System.Drawing; using System.Windows.Forms; namespace WindowsApplication1 { // デザイナは省略 public partial class Form1 : Form { public Form1() { InitializeComponent(); } // "button1" という Button が押されたときのイベント private void button1_Click(object sender, EventArgs e) { // "textBox1" という TextBox に値を設定 textBox1.Text = "ボタンが押されました"; } // "textBox1" のテキストが変化したときのイベント private void textBox1_TextChanged(object sender, EventArgs e) { // "checkBox1" という CheckBox をトグル checkBox1.Checked = !checkBox1.Checked; } } }
強引に内部を蹂躙。
using System; using System.Reflection; using System.Windows.Forms; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { WindowsApplication1.Form1 f = new WindowsApplication1.Form1(); // コンポーネントを取得 TextBox textBox1 = GetField(f, "textBox1") as TextBox; CheckBox checkBox1 = GetField(f, "checkBox1") as CheckBox; Console.WriteLine("最初の状態: TextBox={0}, CheckBox={1}", textBox1.Text, checkBox1.Checked); // ボタン押したときのイベントを起こす Button button1 = GetField(f, "button1") as Button; CallMethod(f, "button1_Click", button1, null); Console.WriteLine("ボタン押下後: TextBox={0}, CheckBox={1}", textBox1.Text, checkBox1.Checked); } static object CallMethod(object o, String name, params object[] args) { MethodInfo mi = o.GetType().GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance); return mi.Invoke(o, args); } static object GetField(object o, String name) { FieldInfo fi = o.GetType().GetField(name, BindingFlags.NonPublic | BindingFlags.Instance); return fi.GetValue(o); } } }
こういうのをNUnitなりと組み合わせればテストできそうだけど、本当にこれでいいんだろうか。普通どうやるんだろう?