将单元测试循环运行是不好的做法吗?

时间:2017-03-06 21:42:30

标签: c# unit-testing nunit

我正在使用nunit在C#中编写一些单元测试。请考虑以下代码:

    [Test ()]
    public void TestCarCost () {
        for (int i = 0; i < Examples.exampleCount; i++) {
            Car car = new Car(Examples[i]);
            Assert.AreEqual (car.getCost (), Examples[i].cost, "Test " + (i + 1) + " failed");
        }
    }

让我们说例子是一个带有一些静态数据的类,用于测试汽车类型的不同可能输入,你可以看到我试图测试car.getCost()函数中的任何错误。现在在循环中使用它会在某种程度上感觉不对,因为例如当任何断言失败时它总是会将您发送到同一行代码。而且,据我所知,只要[Test()]中的断言失败,nunit会立即终止其余的测试代码。这意味着如果我在循环中拥有所有内容并且断言nr 1失败,我就不会看到其他断言是否失败。明确地编写所有测试本质上是编写copypeasted代码,因此它也感觉不对。在这种情况下,什么是良好做法?是否可以在单元测试中使用大量类似的代码?我缺少一些优雅的解决方案吗?

2 个答案:

答案 0 :(得分:7)

NUnit内置了对parameterized tests的支持。如果您的示例数据很简单(即值可以显示在属性中,例如string),那么您的测试可以使用TestCase attributes,如下所示:

[TestCase("Example Value 1", ExpectedResult=123.4)]
[TestCase("Example Value 2", ExpectedResult=567.8)]
[TestCase("Example Value 3", ExpectedResult=901.2)]
public void TestCarCost (string exampleValue) {
    Car car = new Car(exampleValue);
    return car.GetCost();        
}

如果您的示例值(实际上是测试输入)无法显示在属性中,您可以使用TestCaseSource attribute来指示将为您提供值的成员:

[TestCaseSource(nameof(Examples))]
public void TestCarCost (ExampleInput exampleValue) {
    Car car = new Car(exampleValue);
    return car.GetCost();        
}

public IEnumerable<ITestCaseData> Examples {
    get {
        yield return new TestCaseData(new ExampleInput(1,2)).Returns(123.4);
        yield return new TestCaseData(new ExampleInput(3,4)).Returns(567.8);
        yield return new TestCaseData(new ExampleInput(5,6)).Returns(901.2);
    }
}

答案 1 :(得分:5)

最好使用TestCaseAttribute代替循环。请在以下link中详细了解。

在你的情况下应该是:

[TestCase(1)]
[TestCase(2)]
[TestCase(3)]
public void TestCarCost (int id) 
{           
    Car car = new Car(Examples[id]);
    Assert.AreEqual (car.getCost (), Examples[id].cost, "Test " + (i + 1) + " failed");

}

在这里,您可以为单个测试方法创建多个测试用例。对于每个测试用例,您可以在TestCase()属性中提供参数,并将id作为测试方法传递。

基于id,您可以访问您的资源`例子[id]。&#39;

我宁愿使用这种方式,因为我可以监控每个案例,并且它不需要额外的逻辑。

此外,如果您在单元测试中添加其他逻辑,则会增加失败的可能性,并且您将依赖于该逻辑的准确性。