如何测试或描述无限的可能性?

时间:2010-03-06 15:41:56

标签: unit-testing testing tdd bdd

伪代码中的示例类:

class SumCalculator
  method calculate(int1, int2) returns int

测试这个的好方法是什么?换句话说,我应该如何描述我需要的行为?

test1: canDetermineSumOfTwoIntegers

test2: returnsSumOfTwoIntegers

test3: knowsFivePlusThreeIsEight

Test1和Test2似乎含糊不清,需要测试一个特定的计算,因此它并没有真正描述正在测试的内容。然而test3非常有限。

测试此类课程的好方法是什么?

5 个答案:

答案 0 :(得分:10)

我会测试边界条件(max-int,min-int,zero,positive,negative)和一些典型情况:

test1: sumOfPosAndPos
test2: sumOfPosAndNeg
test3: sumOfPosAndZero
test4: sumOfNegAndZero
test5: sumOfMaxIntAndMinInt

答案 1 :(得分:5)

有几种哲学。 The Art of Unit Testing的作者Roy Osherove似乎prefer using explicit values,并选择每个Equivalence Class的最低(或最简单)表示。

这个原则并不适用于您的示例,但在许多其他场景中效果非常好。

例如,如果某个类需要输入正整数,则选择数字 1 ,因为它是所有正整数的最简单表示。

就个人而言,我更喜欢我称之为Constrained Non-Determinism的原则。这里的要点是我们让某种工厂为给定类型的匿名变量提供服务,因为它迫使我们直接在测试中建立关系。

我正在使用AutoFixture来执行此操作(但您也可以使用其他内容),因此在这种情况下,我会像这样测试SumCalculator:

var fixture = new Fixture();
var int1 = fixture.CreateAnonymous<int>();
var int2 = fixture.CreateAnonymous<int>();
var expectedResult = int1 + int2;
var sut = fixture.CreateAnonymous<SumCalculator>();

var result = sut.Calculate(int1, int2);

Assert.AreEqual(expectedResult, result);

原则上,此单一测试为Calculate方法提供规范。我们永远不知道int1int2的价值是什么,而且在所有实际无关紧要的情况下都非常合适。

答案 2 :(得分:3)

如果你正在测试数学函数,我建议你应该针对它的反函数测试它,例如:对于x = a + b的函数,你应该测试它是否是ax = -b和xb = a,这只是为了说明,当然它不适用于每一个案例。

答案 3 :(得分:1)

此处的另一个替代方法是使用Parameterized Test Case删除测试中的重复。基本上,一个表包含测试的所有数据,以元组形式([term1,term2,sum]),然后在表上迭代调用参数化的测试用例来测试表中的行:

我还会添加负面(在这里溢出)测试:calculate(MAXINT, 1)应该返回什么?

答案 4 :(得分:1)

参见David Saff关于理论测试的工作; here (PDF)就是一个例子。这基本上是一种断言,某些东西(比如函数是其函数的反函数)对于某些集合中的所有值(包括所有可能值的集合)都是真的 - 并将该断言表示为测试。你可以通过随机选择的值运行测试来做一些有趣的事情(如果设置太大而无法完全运行),并自动将故障记录为具体的具体回归测试。

相关问题