GUIのユニットテスト② .NET

前回の続きです。
SampleFrameをテストするクラスを作ってみます。

NUnitFormsのインストール

.NETでは、NUnitFormsを使ってGUIアプリケーションのユニットテストを行ってみます。
ココからダウンロードしてきます。
適当にクリックしてインストールした後に、プロジェクトの参照設定にNUnitFormsを追加しておきます。



NUnitFormsSampleTest.cs

以前に作った、Dbcp.cs、DbTester.cs、DataSetAssert.csを使って実装しています。


SetUpメソッドで以下を行っています。
 1.データベースの初期化
 2.テスト対象画面の表示


ClickSearchButtonメソッドで検索ボタンを押して、
検索結果テーブルに設定された値が正しいかを確認しています。



using System;
using System.Data;
using System.Windows.Forms;

using NUnit.Framework;
using NUnit.Extensions.Forms;
using NDbUnit.Core;
using NDbUnit.Core.SqlClient;

using NUnitFormsSample;
using NDbUnitSample;
using NDbUnitSampleTest;

namespace NUnitFormsSampleTest
{
    [TestFixture]
    public class NUnitFormsSampleTest
    {
        private const string XSD_PATH = "testdata/NUnitFormsSampleTest/userInfo.xsd";

        private SampleForm form;
        private DbTester tester = new DbTester(new SqlDbUnitTest(Dbcp.GetInstance().ConnectionString));

        [SetUp]
        public void SetUp()
        {
            // データベースの初期化
            this.tester.InitDb(XSD_PATH, "testdata/NUnitFormsSampleTest/init.xml");

            // テスト対象画面の表示
            this.form = new SampleForm();
            this.form.Show();
        }

        [TearDown]
        public void TearDown()
        {
            this.form.Close();
        }

        [Test]
        public void ClickSearchButton()
        {
            // 検索ボタンを押下
            ButtonTester buttonTester = new ButtonTester("searchButton");
            buttonTester.Click();

            // 検索結果テーブルを取得
            ControlFinder finder = new ControlFinder("userTable");
            DataGridView dataGridView = (DataGridView)finder.Find();

            // 検索結果を確認
            DataTable expected = this.tester.CreateDataSet(XSD_PATH, "testdata/NUnitFormsSampleTest/selectAll.xml").Tables[0];
            Assert.AreEqual(expected.Rows.Count, dataGridView.Rows.Count);
            for (int i = 0; i < dataGridView.Rows.Count; i++)
            {
                DataRowView actual = (DataRowView)dataGridView.Rows[i].DataBoundItem;
                DataSetAssert.AreEqual(expected.Rows[i], actual.Row, i);
            }
        }
    }
}


NUnitFormsのAPIドキュメントを見ると必要最低限の実装みたいですね。
FEST-Swingほど充実していない感じがします。


ControlFinderでコンポーネントインスタンスが取得できるので、
自前で実装すればカバー出来そうです。

ControlFinder finder = new ControlFinder("userTable");
DataGridView dataGridView = (DataGridView)finder.Find();

テストデータXML

以前に作ったものをそのまま使います。


■userInfo.xsd(テーブル定義)

<?xml version="1.0" standalone="yes"?>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="userInfo">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="id" type="xs:int" minOccurs="0" />
              <xs:element name="name" type="xs:string" minOccurs="0" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>


■init.xml(テスト実行前の初期状態)

<?xml version="1.0" standalone="yes"?>
<NewDataSet>
  <userInfo>
    <id>1</id>
    <name>userA</name>
  </userInfo>
  <userInfo>
    <id>2</id>
    <name>userB</name>
  </userInfo>
  <userInfo>
    <id>3</id>
    <name>userC</name>
  </userInfo>
</NewDataSet>


■selectAll.xml(SelectAllメソッド実行後)
全てのレコードが抽出されるはず。

<?xml version="1.0" standalone="yes"?>
<NewDataSet>
  <userInfo>
    <id>1</id>
    <name>userA</name>
  </userInfo>
  <userInfo>
    <id>2</id>
    <name>userB</name>
  </userInfo>
  <userInfo>
    <id>3</id>
    <name>userC</name>
  </userInfo>
</NewDataSet>

テストをVisualStudio上から実行してみる

以前と同様にTestDriven.NETから実行します。
テストを実行すると、SampleFormが表示されて勝手に検索ボタンが押されます。





実行結果は出力ウィンドウに表示されます。




ではでは、わざとエラーにしてみます。
selectAll.xmlの期待値を変更して実行すると・・・

<?xml version="1.0" standalone="yes"?>
<NewDataSet>
  <userInfo>
    <id>1</id>
    <name>HOGEHOGE</name>
  </userInfo>
  <userInfo>
    <id>2</id>
    <name>userB</name>
  </userInfo>
  <userInfo>
    <id>3</id>
    <name>userC</name>
  </userInfo>
</NewDataSet>


ちゃんとエラーになりますね!





.NET3.0からMicrosoft UIオートメーションというのが、Windows Presentation Foundation(WPF)に含まれているそうです。
UIオートメーションを使うとNUnitFormsと同じ事ができます。
時間の空いた時に調べてみようと思います。

 // UIオートメーションでsearchButtonボタンを押してみる
 AutomationElement searchButton = FindElement(form, "searchButton"); 
 searchButton.Invoke();