假设我有几个小测试用例。设置简单,易于执行 假设每个小测试用例可以执行多次检查。
当我考虑到一个测试用例应理想检查一个条件这一事实时,我认为有几个选项可以实现这样的要求。
由于我不太喜欢解决方案1或2,因为它需要您查找测试的设置和练习部分,您是否会在这种情况下使用NUnit的Sequential属性进行分类是一种气味或解决方案。
原文:多项检查/测试方法
[Test]
public void MyTest1()
{
// Setup
IMyObject object1 = new MyObject(/* Parameter combination X */)
this.myObjectList.Add(object1);
// Exercise
result = this.LPSolve(this.myObjectList);
// Check
Assert.AreSame(null, result.Object);
Assert.AreEqual(-1, result.Number);
Assert.True(result.Messages.Contains(ErrorMessage1));
}
[Test]
public void MyTest2()
{
// Setup
IMyObject object1 = new MyObject(/* Parameter combination Y */)
IMyObject object2 = new MyObject(/* Parameter combination Y */)
this.myObjectList.Add(object1);
this.myObjectList.Add(object2);
// Exercise
result = this.LPSolve(this.myObjectList);
// Check
Assert.AreSame(object2, result.Object);
Assert.AreEqual(8, result.Number);
Assert.True(result.Messages.Contains(ErrorMessage1));
Assert.True(result.Messages.Contains(ErrorMessage2));
}
解决方案1:具有设置和延迟代码的基类
[Test]
public virtual void MyTest1()
{
// Setup
IMyObject object1 = new MyObject(/* Parameter combination X */)
this.myObjectList.Add(object1);
// Exercise
result = this.LPSolve(this.myObjectList);
// Check
MyTest1Check();
}
[Test]
public virtual void MyTest2()
{
// Setup
IMyObject object1 = new MyObject(/* Parameter combination Y */)
IMyObject object2 = new MyObject(/* Parameter combination Y */)
this.myObjectList.Add(object1);
this.myObjectList.Add(object2);
// Exercise
result = this.LPSolve(this.myObjectList);
// Check
MyTest2Check();
}
...
/* Class ObjectCheck */
/* Check result object */
public override MyTest1Check()
{
Assert.AreSame(null, this.result.Object);
}
public override MyTest2Check()
{
Assert.AreSame(this.myObjectList[1], this.result.Object);
}
...
/* Class NumberCheck */
/* Check result number */
public override MyTest1Check()
{
Assert.AreSame(-1, this.result.Number);
}
public override MyTest2Check()
{
Assert.AreSame(8, this.result.Number);
}
...
/* and so on */
解决方案2:调用设置/练习方法的测试方法
public void SetupMyTest1()
{
// Setup
IMyObject object1 = new MyObject(/* Parameter combination X */)
this.myObjectList.Add(object1);
// Exercise
this.result = this.LPSolve(this.myObjectList);
}
[Test]
public void MyTest1ObjectShouldBeNull()
{
SetupMyTest1();
// Check
Assert.AreSame(null, this.result.Object);
}
[Test]
public void MyTest1ResultShouldBeMinus1()
{
SetupMyTest1();
// Check
Assert.AreEqual(-1, this.result.Number);
}
[Test]
public void MyTest1MessageShouldContainErrorMessage1()
{
SetupMyTest1();
// Check
Assert.True(this.result.Messages.Contains(ErrorMessage1));
}
public void SetupMyTest2()
{
// Setup
IMyObject object1 = new MyObject(/* Parameter combination Y */)
IMyObject object2 = new MyObject(/* Parameter combination Y */)
this.myObjectList.Add(object1);
this.myObjectList.Add(object2);
// Exercise
this.result = this.LPSolve(this.myObjectList);
}
[Test]
public void MyTest2ObjectShouldBeObject2()
{
SetupMyTest2();
// Check
Assert.AreSame(this.myObjectList[1], this.result.Object);
}
[Test]
public void MyTest2ResultShouldBeEight()
{
SetupMyTest2();
// Check
Assert.AreEqual(8, this.result.Number);
}
[Test]
public void MyTest2MessageShouldContainErrorMessage1()
{
SetupMyTest2();
// Check
Assert.True(this.result.Messages.Contains(ErrorMessage1));
}
[Test]
public void MyTest2MessageShouldContainErrorMessage2()
{
SetupMyTest2();
// Check
Assert.True(this.result.Messages.Contains(ErrorMessage2));
}
解决方案3:使用属性将设置/执行/检查保存在一个地方并执行一次检查/测试(两种方法分别执行3和4次)
[Test, Sequential]
public void MyTest1([Values("CheckObject", "CheckNumber", "CheckErrorMessage1") string check)
{
// Setup
IMyObject object1 = new MyObject(/* Parameter combination X */)
this.myObjectList.Add(object1);
// Exercise
result = this.LPSolve(this.myObjectList);
// Check
if (check == "CheckObject") Assert.AreSame(null, result.Object);
else if (check = "CheckNumber") Assert.AreEqual(-1, result.Number);
else if (check = "CheckErrorMessage1") Assert.True(result.Messages.Contains(ErrorMessage1));
else throw new ArgumentOutOfRangeException(check);
}
[Test, Sequential]
public void MyTest2([Values("CheckObject", "CheckNumber", "CheckErrorMessage1", "CheckErrorMessage2") string check)
{
// Setup
IMyObject object1 = new MyObject(/* Parameter combination Y */)
IMyObject object2 = new MyObject(/* Parameter combination Y */)
this.myObjectList.Add(object1);
this.myObjectList.Add(object2);
// Exercise
result = this.LPSolve(this.myObjectList);
// Check
if (check == "CheckObject") Assert.AreSame(object2, result.Object);
else if (check = "CheckNumber") Assert.AreEqual(8, result.Number);
else if (check = "CheckErrorMessage1") Assert.True(result.Messages.Contains(ErrorMessage1));
else if (check = "CheckErrorMessage2") Assert.True(result.Messages.Contains(ErrorMessage2));
else throw new ArgumentOutOfRangeException(check);
}
答案 0 :(得分:1)
在我看来,您原来的两个单元测试很容易理解,可以单独使用。在给定的单元测试中,您要检查一个“单元”功能,这不一定在单个断言中表示。
在原始代码中,查看MyTest1()。在我看来,您正在使用无效参数并返回验证错误。我通常将单元测试命名为LPSolveReturnsErrorWithInvalidParameters()。这定义了一个要测试的单元。要证明此功能已完成,必须满足三个输出要求
在单个单元测试中使用这三个断言似乎是合理的。您提供的其他潜在解决方案似乎过于复杂和不必要