我开始(至少尝试)使用TDD原理进行编码,我有一个问题:在实际开始编码之前我需要编写多少测试?
以假设Math
类和方法Divide(int a, int b)
为例。
a)在开始编码Math
之前,我是否必须完全测试Sum
类(Average
,Math
,...)的所有方法?
b)在开始编写方法之前,我是否必须完全测试Divide
方法,例如断言为零?
c)或者我可以创建一个简单的测试断言并验证它是否失败,编写代码并检查它是否正常,为每个方法的断言重新处理过程?
我认为选项 c)是正确的,但我找不到答案(我做了一些搜索,但找不到明确的答案)。
答案 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)
如果您想要完整性,您应该在开发之前设计和编码单元测试,然后为创建的单元测试开发主要功能。您越彻底,范围越清晰,最终质量越好。如果时间和功能允许,我会为每个方法/函数创建测试。