我是UnitTesting的新手,并且有以下代码
public class PowerOf
{
public int CalcPowerOf(int @base, int exponent) {
if (@base == 0) { return 0; }
if (exponent == 0) { return 1; }
return @base * CalcPowerOf(@base, exponent - 1);
}
}
我首先为它编写的单元测试(使用xUnit)就是这个,但是我不太确定它是否是正确的方法,或者我是否应该使用其他模式?
我想知道的是,这是否正确用于将多组数据传递到“单元测试” – 因为我没有在xUnit的文档上看到任何文档或参考示例?
[Fact]
public void PowerOfTest() {
foreach(var td in PowerOfTestData()) {
Assert.Equal(expected, CalcPowerOf(@base, exponent));
}
}
public class TestData {
int Base {get;set;}
int Exponent {get;set;}
int ExpectedResult {get;set;}
}
public List<TestData> PowerOfTestData() {
yield return new TestData { Base = 0, Exponent = 0, TestData = 0 };
yield return new TestData { Base = 0, Exponent = 1, TestData = 0 };
yield return new TestData { Base = 2, Exponent = 0, TestData = 1 };
yield return new TestData { Base = 2, Exponent = 1, TestData = 2 };
yield return new TestData { Base = 5, Exponent = 2, TestData = 25 };
}
解决方法:
你最好在xUnit中使用一个名为Theory的专用构造来处理所谓的“数据驱动测试”.
使用Theory属性装饰你的testmethod,然后确保返回一个带有输入参数的静态“成员”和你已经对TestData类做的预期结果.请参阅下面的示例,并参考xUnit文档:“Writing your first theory”.
因此我会像下面那样重构你的代码.首先使用Theory和MemberData属性修改测试,并将参数添加到测试“@base”,“exponent”和“expectedResult” – 就像在TestData类中一样. xUnit不允许您使用TestData类,它只接受IEnumerable< object>并且要求它是静态的,但foreach循环结构的好处是所有的测试都单独运行.对于具有特定数据集的每次运行,您将获得绿色或红色标记!
public class PowerOfTests
{
[Theory]
[MemberData(nameof(PowerOfTestData))]
public void PowerOfTest(int @base, int exponent, int expected) {
Assert.Equal(expected, CalcPowerOf(@base, exponent));
}
public static IEnumerable<object[]> PowerOfTestData() {
yield return new object[] { 0, 0, 0 };
yield return new object[] { 0, 1, 0 };
yield return new object[] { 2, 0, 1 };
yield return new object[] { 2, 1, 2 };
yield return new object[] { 2, 2, 4 };
yield return new object[] { 5, 2, 25 };
yield return new object[] { 5, 3, 125 };
yield return new object[] { 5, 4, 625 };
}
}