如何测试或描述无限的可能性?
伪代码中的示例类:
class SumCalculator
method calculate(int1, int2) returns int
测试这个的好方法是什么?换句话说,我应该如何描述我需要的行为?
test1: canDetermineSumOfTwoIntegers
或者
test2: returnsSumOfTwoIntegers
或
test3: knowsFivePlusThreeIsEight
Test1 和 Test2 看起来很模糊,它需要测试特定的计算,因此它并没有真正描述正在测试的内容。然而 test3 的功能非常有限。
测试此类课程的好方法是什么?
Example class in pseudocode:
class SumCalculator
method calculate(int1, int2) returns int
What is a good way to test this? In other words how should I describe the behavior I need?
test1: canDetermineSumOfTwoIntegers
or
test2: returnsSumOfTwoIntegers
or
test3: knowsFivePlusThreeIsEight
Test1 and Test2 seem vague and it would need to test a specific calculation, so it doesn't really describe what is being tested. Yet test3 is very limited.
What is a good way to test such classes?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我会测试边界条件(max-int、min-int、零、正、负)和一些典型情况:
等等。
I would test the boundary conditions (max-int, min-int, zero, positive, negative) and some typical cases:
etc.
有几种哲学。 Roy Osherove,单元测试的艺术一书的作者,似乎更喜欢使用显式值,并选择每个等价类的最低(或最简单)表示。
该原则并不特别适用于您的示例,但在许多其他场景中非常有效。
例如,如果一个类需要输入一个正整数,您可以选择数字 1,因为它是所有正整数的最简单表示。
就我个人而言,我更喜欢一个称为约束非确定性的原则。这里的要点是,我们让某种工厂为给定类型提供匿名变量,因为它迫使我们直接在测试中建立关系。
我使用 AutoFixture 来执行此操作(但您也可以使用其他东西),所以在这种情况下我会像这样测试 SumCalculator:
原则上,这个单一测试为计算方法提供了规范。我们永远不知道
int1
和int2
的值是什么,这在许多实际上并不重要的情况下非常合适。There are several philosophies. Roy Osherove, author of The Art of Unit Testing, seems to prefer using explicit values, and selecting the lowest (or simplest) representation of each Equivalence Class.
That principle doesn't apply itself particularly well to your example, but works really well in many other scenarios.
If, for example, a class requires an input of a positive integer, you pick the number 1 because it's the simplest representation of all positive intergers.
Personally, I rather prefer a principle I call Constrained Non-Determinism. The point here is that we let some kind of factory serve us anonymous variables for the given type, because it forces us to establish the relationship directly in the test.
I'm using AutoFixture to do this (but you could also use something else), so in this case I would test the SumCalculator like this:
In principle, this single test provides a specification for the Calculate method. We never know what the values of
int1
andint2
are, and that is very appropriate in all those many cases where it actually doesn't matter.如果你正在测试数学函数,我建议你应该根据它的反函数来测试它,例如:对于执行 x = a + b 的函数,你应该测试它是否 ax = -b 和 xb = a,这只是作为说明,当然它并不适用于所有情况。
if you're testing mathematical function, i would suggest you should test it against its inverse function, for example: for function that do x = a + b, you should test it whether a-x = -b and x-b = a, this is just for illustration, ofcourse it won't work on every case.
这里的另一种选择是使用参数化测试用例来删除重复
我还会添加负数(此处溢出)测试:
calculate(MAXINT, 1)
应该返回什么?Another alternative here would be to used a Parameterized Test Case to remove the duplication in the tests. Basically a table contains all the data for the tests, in a tuple form ([term1, term2, sum]), then a testcase iterates on the table on invoke the parameterized testcase to test a row in the table :
I would also add negative (overflow here) testing : what is
calculate(MAXINT, 1)
supposed to return ?请参阅 David Saff 的理论测试著作; 此处 (PDF) 是一个示例。这基本上是一种断言,某些集合(包括所有可能值的集合)中的所有值(例如函数是其函数的反函数)都为真 - 并将该断言表达为测试。您可以通过使用随机选择的值运行测试(如果集合太大而无法彻底运行)来做一些有趣的事情,并自动将失败记录为特定的具体回归测试。
See David Saff's work on Theory Tests; here (PDF) is an example. This is basically a way of making an assertion that something (like a function being the inverse of its function) is true for all values in some set (including the set of all possible values) - and expressing that assertion as a test. You can do some fun stuff by running your test with randomly selected values (if the set is too large to run exhaustively), and automatically recording the failures as specific concrete regression tests.