我目前正在xUnit中编写一些单元测试。到目前为止,我使用MSTest for UT,所以每个测试用例都是文件中的单个测试。通过xUnit,我可以使用参数化测试。我不确定使用它们是什么,更常见的还是我应该使用更多。
我正在测试的方法很简单-它使用十进制数字并将其转换为具有某些属性的字符串。测试始终具有相同的代码,只是输入和输出有所不同。下面的示例是简化版本,但我认为它仍然可以说明这一点。
[Fact]
public void valueIsZero()
{
var formattedValue = Formatter.Format(0m);
Assert.Equal("0", formattedValue);
}
[Fact]
public void valueIsOne()
{
var formattedValue = Formatter.Format(1m);
Assert.Equal("1", formattedValue);
}
这是我在MSTest中编写测试的方式,但是在xUnit中,我可以使用如下理论编写这些测试:
public static IEnumerable<object[]> Data =>
new List<object[]>
{
new object[] { 0m, "0" },
new object[] { 1m, "1" }
};
[Theory]
[MemberData(nameof(Data))]
public void multipleValue(decimal value, string expectedResult)
{
var formattedValue = Formatter.Format(value, true, false, true);
Assert.Equal(expectedResult, formattedValue);
}
第一种或第二种方法有什么优点或缺点?还是更常见的方法?
答案 0 :(得分:2)
测试代码应像生产代码一样对待。因此,也适用SOLID,DRY等一般性原则。
xUnit中的Theory
构造有助于避免重复测试代码。这使将来的维护变得更加容易(只有一个地方可以更改逻辑)。考虑您的程序逻辑是否会由于需求的变化而改变。然后,您还要调整程序逻辑和测试。更改一个Theory
-测试要比进行多个Fact
-测试少。
对于您的示例,我建议像这样使用InlineData:
[Theory]
[InlineData("0", "0")]
[InlineData("1", "1")]
public void multipleValue(string value, string expectedResult)
{
var formattedValue = Formatter.Format(Convert.ToDecimal(value), true, false, true);
Assert.Equal(expectedResult, formattedValue);
}
由于分析器将每个InlineData识别为一个单元测试并将其显示为一个组,因此在VisualStudio的Testrunner中显示效果很好。