よく、ユニットテスト書くときに忘れるのでメモメモ。
Visual Studio 2008からProfessional版に搭載された単体テスト機能ですが
普通にユニットテストを作ると以下のようになります。
テスト対象メソッド
public int Sum(int x, int y){ return (x + y); }
自動作成されたテストメソッド
/// <summary> ///Sum のテスト ///</summary> [TestMethod()] public void SumTest() { Program target = new Program(); // TODO: 適切な値に初期化してください int x = 0; // TODO: 適切な値に初期化してください int y = 0; // TODO: 適切な値に初期化してください int expected = 0; // TODO: 適切な値に初期化してください int actual; actual = target.Sum(x, y); Assert.AreEqual(expected, actual); Assert.Inconclusive("このテストメソッドの正確性を確認します。"); }
後は、テストしたい値を設定して書き換えます。
/// <summary> ///Sum のテスト ///</summary> [TestMethod()] public void SumTest() { Program target = new Program(); int x = 1; int y = 2; int expected = 3; int actual; actual = target.Sum(x, y); Assert.AreEqual(expected, actual); }
んで、テストしてめでたく成功したら次のテストへって感じですが、
いちいちいろんなデータのパターンをその都度テストメソッド作って
書いてたら大変です。
そういう時に、外部ファイルとしてテストデータを作成して
それをテストデータとして利用する方法があります。
やり方は以下の3通りあります。
データベースを利用する方法は割愛します。
まずは、CSVから。
エディタやExcelなどを使ってCSVファイルを作成します。
x,y,answer 0,0,0 1,1,2 1,2,3 2,1,3 10,10,20
一行目に列名を付けておきます。これが後でテストの際に
データを取得する為の列名になります。
後は、これを以下の手順で設定します。
すると、テストメソッドが以下の状態に変更されます。
/// <summary> ///Sum のテスト ///</summary> [DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "|DataDirectory|\\TestData.csv", "TestData#csv", DataAccessMethod.Sequential), DeploymentItem("TestProject1.Tests2\\TestData.csv"), TestMethod()] public void SumTest() { Program target = new Program(); int x = 1; int y = 2; int expected = 3; int actual; actual = target.Sum(x, y); Assert.AreEqual(expected, actual); }
属性が付加されました。
で、ここままでは、設定する前と同じですので、指定したテストデータからデータを取得できるように
する必要があります。
データを取得するには、以下のプロパティにアクセスします。
TestContext
TestContextはテストクラス上で以下のようにプロパティ設定されています。
/// <summary> ///現在のテストの実行についての情報および機能を ///提供するテスト コンテキストを取得または設定します。 ///</summary> public TestContext TestContext { get { return testContextInstance; } set { testContextInstance = value; } }
このオブジェクトのDataRowよりデータが取得できます。
テストメソッドをTestContext用に書き換えた版が以下です。
/// <summary> ///Sum のテスト ///</summary> [DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "|DataDirectory|\\TestData.csv", "TestData#csv", DataAccessMethod.Sequential), DeploymentItem("TestProject1.Tests2\\TestData.csv"), TestMethod()] public void SumTest() { Program target = new Program(); int x = int.Parse(TestContext.DataRow["x"].ToString()); int y = int.Parse(TestContext.DataRow["y"].ToString()); int expected = int.Parse(TestContext.DataRow["answer"].ToString()); int actual; actual = target.Sum(x, y); Assert.AreEqual(expected, actual); }
これで、テストを実行するとテストデータファイルからデータが読み込まれ
テストが行われます。
後、XMLでの設定も出来ます。
以下のようにしてXMLファイルを記述します。
<?xml version="1.0" encoindg="utf-8"?> <TestData> <Data> <x>1</x> <y>2</y> <answer>3</answer> </Data> <Data> <x>2</x> <y>3</y> <answer>5</answer> </Data> </TestData>
要素の書き方は自由みたいです。見たまんまですが
今度は要素名が列名となります。
設定方法はCSVの場合と同じです。
データの取得方法も同じです。
TestContextには、他にも時間を計るメソッドがあったりしますので
込み入ったテストを作成する際には、便利です。
補足:
DataRowクラスには、Field拡張メソッドがあるので
System.Data.DataSetExtensions.dll
を参照設定して、
using System.Data;
しておくと、テストメソッドが以下のように書けます。
/// <summary> ///Sum のテスト ///</summary> [DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "|DataDirectory|\\TestData.csv", "TestData#csv", DataAccessMethod.Sequential), DeploymentItem("TestProject1.Tests2\\TestData.csv"), TestMethod()] public void SumTest() { Program target = new Program(); int x = TestContext.DataRow.Field<int>("x"); int y = TestContext.DataRow.Field<int>("y"); int expected = TestContext.DataRow.Field<int>("answer"); int actual; actual = target.Sum(x, y); Assert.AreEqual(expected, actual); }
こっちの方がToStringもint.Parseもしなくて個人的には好きです。
================================
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場