在开始编写方法/类之前要进行多少单元测试?

时间:2010-02-10 01:05:22

标签: unit-testing tdd

我开始(至少尝试)使用TDD原理进行编码,我有一个问题:在实际开始编码之前我需要编写多少测试?

以假设Math类和方法Divide(int a, int b)为例。

a)在开始编码Math之前,我是否必须完全测试Sum类(AverageMath,...)的所有方法?

b)在开始编写方法之前,我是否必须完全测试Divide方法,例如断言为零?

c)或者我可以创建一个简单的测试断言并验证它是否失败,编写代码并检查它是否正常,为每个方法的断言重新处理过程?

我认为选项 c)是正确的,但我找不到答案(我做了一些搜索,但找不到明确的答案)。

6 个答案:

答案 0 :(得分:8)

您的选项 c 完全由书籍TDD代表。

您编写了一个失败的测试,其中包含您正在处理的类的功能,然后只编写 足够的代码以使该测试通过。然后再次执行此操作,以进行下一次测试。

通过这种方式,您应该看到您编写的每一段新代码都非常关注特定的用例/测试,并且还发现您的测试在所涵盖的内容中保持不同。

您希望最终以红绿重构的方式工作,以便定期回顾您的代码和测试,以便您可以将事物重构为更好的设计。

当然,在现实世界中,您最终可能会编写许多红色测试,或者编写比特定测试所需更多的代码,甚至编写没有测试的代码,但这样做会远离TDD,只能谨慎行事

维基百科的文章实际上非常好。 http://en.wikipedia.org/wiki/Test-driven_development

答案 1 :(得分:2)

您要做的第一件事是为要实现的每个方法编写规范。在您的规范中,您需要解决您关心的尽可能多的极端情况,并定义执行这些情况时您的方法应该导致的行为。

一旦您的规范完成,您就可以为规范的每个部分设计测试,确保每个测试都没有因角落情况而通过或失败。此时,您已准备好编写功能实现和测试代码。完成后,您可以根据需要优化规范/测试/实施,直到结果完全符合您的实施要求。

然后你记录所有内容(特别是你处理角落案件的原因)。

答案 2 :(得分:1)

与其他人提到的一样,您的选项c将是纯TDD方式。我们的想法是以小的红绿重构增量构建您的代码。一个很好的例子就是罗伯特·马丁的Bowling Kata

答案 3 :(得分:0)

你可以写

@Test
public void testDivide() {
   Math math = new Math();
   int result = math.divide(20,2);
   Assert.assertNotNull(result);
}

就是这样,现在当你运行它时你的测试会失败,所以你修复了你的Math.divide方法。并在下一步中添加案例

这是一种非常理想的方式,但每个人都知道并非总是如此。

答案 4 :(得分:0)

“单位”的定义是not universal,有时单位是类,有时它可以是一种方法。所以没有真正的普遍答案。

在这种特殊情况下,我会认为该单元是一种方法,因此在开始编码之前并不是所有方法都不是。相反,我会逐步做事,方法之后的方法。这消除了a)。

但是,在为方法编写测试时,我会写一个严格的测试,即我会测试通过和不通过的情况,在极限测试,测试特殊值等。在编写测试时,你'重新定义合同,该合同应包括特殊情况。从一开始就思考它们会有所帮助。对我而言,要做绿灯的目的是要做到这一点,所以我希望我的测试能够详尽无遗。我认为这是b)。

如果您的测试并非详尽无遗,那么即使测试通过,您实际上也没有完成您的测试,我真的没有看到这一点。我猜这是c)。

所以我的选择是 b)

答案 5 :(得分:0)

如果您想要完整性,您应该在开发之前设计和编码单元测试,然后为创建的单元测试开发主要功能。您越彻底,范围越清晰,最终质量越好。如果时间和功能允许,我会为每个方法/函数创建测试。