提问人:Pavel Dubsky 提问时间:8/17/2014 更新时间:8/17/2014 访问量:28
我是否应该使用不同的方法为相同的行为创建不同的测试?
Should I create different tests for the same behavior using different methods?
问:
我有这样的代码:
public class Foo
{
...
public override bool EqualsTo(object obj)
{
...
}
public static bool operator==(Foo left, Foo right)
{
...
}
public static bool operator!=(Foo left, Foo right)
{
...
}
}
此代码示例的主要目的是说明类可以有多种方式来执行相同的操作,例如检查对象的相等性。所以方法和运算符 和 只是为了简单起见。它可以是任何不同的方法集。主要的一点是,有多种方法可以获得相同的行为。EqualsTo
==
!=
我有两种单元测试的变体:
变式1:
[TestClass]
public class FooTest
{
[TestMethod]
public void ShouldCheckEqualityWhenObjectsEqual()
{
var foo1 = new Foo(1);
var foo2 = new Foo(1);
Assert.IsTrue(foo1.EqualsTo(foo2));
Assert.IsTrue(foo2.EqualsTo(foo1));
Assert.IsTrue(foo1 == foo2);
Assert.IsTrue(foo2 == foo1);
Assert.IsFalse(foo1 != foo2);
Assert.IsFalse(foo2 != foo1);
}
[TestMethod]
public void ShouldCheckEqualityWhenObjectsNotEqual()
{
var foo1 = new Foo(1);
var foo2 = new Foo(2);
Assert.IsFalse(foo1.EqualsTo(foo2));
Assert.IsFalse(foo2.EqualsTo(foo1));
Assert.IsTrue(foo1 == foo2);
Assert.IsTrue(foo2 == foo1);
Assert.IsTrue(foo1 != foo2);
Assert.IsTrue(foo2 != foo1);
}
}
变式2:
[TestClass]
public class FooTest
{
[TestMethod]
public void ShouldCheckEqualityWhenObjectsEqualUsingMethod()
{
var foo1 = new Foo(1);
var foo2 = new Foo(1);
Assert.IsTrue(foo1.EqualsTo(foo2));
Assert.IsTrue(foo2.EqualsTo(foo1));
}
[TestMethod]
public void ShouldCheckEqualityWhenObjectsEqualUsingEqualityOperator()
{
var foo1 = new Foo(1);
var foo2 = new Foo(1);
Assert.IsTrue(foo1 == foo2);
Assert.IsTrue(foo2 == foo1);
}
[TestMethod]
public void ShouldCheckEqualityWhenObjectsEqualUsingInequalityOperator()
{
var foo1 = new Foo(1);
var foo2 = new Foo(1);
Assert.IsFalse(foo1 != foo2);
Assert.IsFalse(foo2 != foo1);
}
[TestMethod]
public void ShouldCheckEqualityWhenObjectsNotEqualUsingMethod()
{
var foo1 = new Foo(1);
var foo2 = new Foo(2);
Assert.IsFalse(foo1.EqualsTo(foo2));
Assert.IsFalse(foo2.EqualsTo(foo1));
}
[TestMethod]
public void ShouldCheckEqualityWhenObjectsNotEqualUsingEqualityOperator()
{
var foo1 = new Foo(1);
var foo2 = new Foo(2);
Assert.IsTrue(foo1 == foo2);
Assert.IsTrue(foo2 == foo1);
}
[TestMethod]
public void ShouldCheckEqualityWhenObjectsNotEqualUsingInequalityOperator()
{
var foo1 = new Foo(1);
var foo2 = new Foo(2);
Assert.IsTrue(foo1 != foo2);
Assert.IsTrue(foo2 != foo1);
}
}
对我来说,变体 1 更短且易于理解,但变体 2 在完成的内容和完成方式方面更加精确,并且具有更多的样板代码,例如数据初始化和设置。我想知道这两种变体中哪一种更受欢迎。或者也许有比这些更好的变体。
相等性测试仅用于简单起见,并且数据设置和初始化可能会更长。
另一个例子:
public class Bar
{
...
public int this[short index] { ... }
public int this[int index] { ... }
public int this[long index] { ... }
}
我应该为每个索引器创建单独的测试,还是可以在一个测试中针对同一对象测试它们,假设它们的行为应该相同。
答:
1赞
Lasse V. Karlsen
8/17/2014
#1
是的,你应该这样做,我也会投票支持结束你的问题,以征求意见。
原因如下。
一个测试应该只测试一件事。
1 件事。
如果你想测试该方法是否有效,那就是 1 个测试。Equals
如果要测试运算符是否正常工作,则这是另一个测试。==
有些人可能认为这两者是相同的,特别是如果其中一个方法调用另一个方法。
因此,我投票决定结束这个问题,以征求意见。
但在我看来,每次测试应该只测试 1 件事。如果有多个方法实现相同的概念,则每个方法都需要进行自己的测试。
最后,你希望一个失败的测试能具体告诉你哪里出了问题。如果这个“具体”可以是任意数量的方法,那么你的测试就太宽泛了。
但这是我的看法。
评论