- 単体テストでは、引数と結果だけが違って、処理の同じテストを行いたいケースが多い。
- テストを関数として準備してやり、そこに引数を順次入れてテストを実行するための便利な機能が
xUnit.net
には準備されている。
InlineData 属性
- テスト用の関数に属性としてつける。
- 属性の引数に書いたものがテストとして実行する際の引数になる。
- 1つの関数に何回でもつけることができる。
- 対象となる関数には
Theory
属性をつけないとテストは実行されない。(逆に[Fact]
は必要ない) -
InlineData
の引数はすべてobject
型になるため実行するまで型があってるかの情報は得られない。
[Theory,
InlineData(0, 0, 0),
InlineData(1, 0, 1),
InlineData(1, 1, 0),
InlineData(2, 1, 1)]
public void AddTest(int expected, int x, int y)
{
Assert.Equal(expected, Add(x, y));
}
MemberData 属性
- テスト用の関数に属性としてつける
- 第1引数に指定した名前の、プロパティー、フィールド、メソッドが実行時の引数として利用される
- 1つの関数に何回でもつけることができる
- 対象となる関数には
Theory
属性をつけないとテストは実行されない
メソッド版
- 第1引数で指定した名前の
static
メンバー関数が実行されその結果がテストに渡される - 関数の戻り値は、イテレータブルなものである必要があり、その中身が順次テストの引数として渡される
- 第2引数以降の引数は、ソースの生成用関数に渡される
- 以下の様に、
IEnumerable<T>
とyield
を利用すればきれいに書ける
public static IEnumerable<object[]> GetSource()
{
yield return new object[] { 0, 0, 0 };
yield return new object[] { 1, 0, 1 };
yield return new object[] { 1, 1, 0 };
yield return new object[] { 2, 1, 1 };
}
[Theory,
MemberData(nameof(GetSource))]
public void AddTest(int expected, int x, int y)
{
Assert.Equal(expected, Add(x, y));
}
プロパティー版
- 第1引数で指定した名前の
static
プロパティーの値がテストに渡される - 関数の戻り値は、イテレータブルなものである必要があり、その中身が順次テストの引数として渡される
public static object[][] Source
{
get
{
return new object[][]
{
new object[] { 0, 0, 0 },
new object[] { 1, 0, 1 },
new object[] { 1, 1, 0 },
new object[] { 2, 1, 1 },
};
}
}
[Theory,
MemberData(nameof(Source))]
public void AddTest(int expected, int x, int y)
{
Assert.Equal(expected, Add(x, y));
}
フィールド版
- 第1引数で指定した名前の
static
フィールドの値がテストに渡される - 関数の戻り値は、イテレータブルなものである必要があり、その中身が順次テストの引数として渡される
public static object[][] Source = new object[][]
{
new object[] { 0, 0, 0 },
new object[] { 1, 0, 1 },
new object[] { 1, 1, 0 },
new object[] { 2, 1, 1 },
}
[Theory,
MemberData(nameof(Source))]
public void AddTest(int expected, int x, int y)
{
Assert.Equal(expected, Add(x, y));
}