DBのユニットテスト④ .NET

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

UserDaoTest.cs

Javaで作ったテストクラスと同じ感じになりました。


アノテーションは、こんな感じです。
 [Test]があるのがテストメソッドです。
 [SetUp]は各テストメソッドの実行前に呼ばれます。
 [TearDown]は各テストメソッドの実行後に呼ばれます。


テストの流れはJavaの時と同じで、こんな感じです。
 1.SetUpメソッドでuserテーブルを初期化
 2.テストメソッド実行
  UserDaoのメソッドを実行
  抽出結果比較 or 更新結果比較(userテーブル)
 3.TearDownメソッドで後始末


DbTesterの引数には、INDbUnitTestインタフェースを指定します。
データベースに応じて実装クラスを指定する必要があります。
今回はSQLServerなので、SqlDbUnitTestクラスを設定します。


NDbUnitは以下のDBに対応しているみたいです。(公式より)


 ・Microsoft SQL Server 2005 and 2008 (Express thru Enterprise)
 ・Microsoft SQL Server CE 2005 and 2008
 ・Microsoft OleDB-supported databases
 ・SQLLite
 ・MySQL
 ・Oracle (XE thru Enterprise, 9i and later)

using System;
using System.Data;

using NDbUnitSample;
using NUnit.Framework;
using NDbUnit.Core.SqlClient;

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

        private IDbConnection con;
        private UserDao dao;
        private DbTester tester = new DbTester(new SqlDbUnitTest(Dbcp.GetInstance().ConnectionString));

        [SetUp]
	public void SetUp()
        {
            this.con = Dbcp.GetInstance().CreateConnection();
            this.dao = new UserDao(this.con);
            this.tester.InitDb(XSD_PATH, "testdata/NDbUnitSampleTest/init.xml");
 	}

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

	[Test]
	public void SelectAll()
        {
            DataSet actual = this.dao.SelectAll();

            // テストデータの作成
            //actual.WriteXmlSchema("userInfo.xsd");
            //actual.WriteXml("userInfo.xml");

            DataSet expected = this.tester.CreateDataSet(XSD_PATH, "testdata/NDbUnitSampleTest/selectAll.xml");
            DataSetAssert.AreEqual(expected, actual);
        }

	[Test]
	public void Select()
        {
            DataSet actual = this.dao.Select(1);

            DataSet expected = this.tester.CreateDataSet(XSD_PATH, "testdata/NDbUnitSampleTest/select.xml");
            DataSetAssert.AreEqual(expected, actual);
	}

	[Test]
	public void Insert()
        {
            this.dao.Insert(4, "userD");

            this.tester.AssertDb(XSD_PATH, "testdata/NDbUnitSampleTest/insert.xml");
	}

	[Test]
	public void Update()
        {
            this.dao.Update(2, "userE");

            this.tester.AssertDb(XSD_PATH, "testdata/NDbUnitSampleTest/update.xml");
	}

	[Test]
    	public void Delete()
        {
            this.dao.Delete(2);

            this.tester.AssertDb(XSD_PATH, "testdata/NDbUnitSampleTest/delete.xml");
	}

    }
}


テストデータはXMLで作ります。
テーブル定義情報を記述したXSDファイルと
テーブルデータ情報を記述した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>


■select.xml(Selectメソッド実行後)
[id=1、name=userA]のレコードが抽出されるはず。

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


■insert.xml(Insertメソッド実行後)
[id=4、name=userD]のレコードが追加されているはず。

<?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>
  <userInfo>
    <id>4</id>
    <name>userD</name>
  </userInfo>
</NewDataSet>


■update.xml(Updateメソッド実行後)
[id=2、name=userB]が[id=2、name=userE]に変更されているはず。

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


■delete.xml(Deleteメソッド実行後)
[id=2、name=userB]のレコードが削除されているはず。

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


Excelと違って、XMLデータを手作業で作るのは面倒なので・・・
テーブルにデータを投入して、SelectAll()メソッドのコメント行を有効にして、
XSDファイルとXMLファイルを作りました。
XSDファイルは一度作っておけばいいので、この方法が楽かもですね。

[Test]
public void SelectAll()
{
    DataSet actual = this.dao.SelectAll();

    // テストデータの作成
    //actual.WriteXmlSchema("userInfo.xsd");
    //actual.WriteXml("userInfo.xml");

    DataSet expected = this.tester.CreateDataSet(XSD_PATH, "testdata/NDbUnitSampleTest/selectAll.xml");
    DataSetAssert.AreEqual(expected, actual);
}

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


テスト実行を簡単にする為に、TestDriven.NETをインストールします。
ココから無料のPersonal Versionをダウンロードします。
インストールは適当にクリックしていくだけです。


インストールするとEclipseからJUnitを実行するような感じで、
VisualStudioからNUnitを実行できます。


テストクラス名を選択して、
右クリック→「Run Test(s)」で全テストが実行されます。


どれか一つのテストを実行したい場合は、
テストメソッド名を選択して、右クリック→「Run Test(s)」で実行できます。


デバッグ実行したい場合は、右クリック→「Test With」→「Debugger」で実行できます。





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




ではでは、わざとエラーにしてみます。
Insertメソッドの引数を変更して実行すると・・・

[Test]
public void Insert()
{
    //this.dao.Insert(4, "userD");
    this.dao.Insert(4, "HOGEHOGE");

    this.tester.AssertDb(XSD_PATH, "testdata/NDbUnitSampleTest/insert.xml");
}


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