首先,最重要的是前期成本没有您想象的那么高。是的,与不进行测试相比,您花费更多的时间进行测试。但是,如果您采用“测试后”方法,那么您真正浪费的是什么?假设TDD需要10个小时,而DDT则需要6个小时。您的“额外”前期费用仅为4小时。现在,如果您应用代码度量标准或要求(例如90%的覆盖率),则TDD和DDT的成本将更加接近。
您将使用TDD编写更少的错误代码。即使只是因为您已将需求明确说明为测试,也可以在一天结束时证明您的代码完全按照您想要的去做。现在也许您想让它做错事,但这不是一个变更请求的错误。这个很重要。“销售”有效的产品比较容易,但是可以以不同的方式/更好地工作,然后出售被认为无效的产品。使用TDD,实际上不可能通过测试并编写不起作用的代码。您可能不理解这些要求,并且编写了错误但有效的代码。
代码库越旧,TDD越好。尝试在没有测试套件或实施不良的套件的情况下进行重构。即使是简单的更改也会引入错误。拥有覆盖面广的测试套件可确保随着产品的发展,它继续按预期运行。它还有助于突出显示冲突的业务规则(在较长时期内发生)。
您不知道它不起作用。如果没有测试套件,您将无法确定代码是否按照您认为的方式运行,或者看起来是否正常。
var foo = function(in) {
if(in == 0) {
return true
}
}
现在,在您的整个应用程序中,您都会调用if(foo()){ doStuff() }
修复foo时会发生什么?
var foo = function(in) {
if(in === 0) {
return true
}
}
您也应该重构和干燥测试。一个好的测试套件并不难维护。有了编写良好的原子测试,我几乎不必回过头去一次更改超过1-2个测试。如果对测试套件进行了较大的更改,这是一个巨大的危险信号,那就是某些事情不正确。
我只是看不到我应该如何知道我的所有方法以及事情将如何工作,直到我的代码出现为止。
好吧,你不应该这样。您应该编写一个测试来测试某个工作单元是否完成。如果您觉得自己正在测试一些您可能不知道的事情,那么您就在考虑太大,或者测试太小。
例如,您需要知道门已关闭并锁上。我将测试door.close()和door.lock(),当门被锁定时,door.open()返回false。这就对了。如果您的测试是door.lock(),则在数据库中设置一个标志。然后您测试得太小。该测试不需要知道door.lock()是如何工作的,只需要知道。
现在,如果您正在编写一个测试,说所有门窗都被锁定,house.isSecure()将返回true。如果不先看门或窗,那么您的想法就太大了。
最后,您可能正在考虑太大的工作单元。当您获得需求列表时,应该对它们进行整理,以便在最小的单元上工作。仅针对该单元编写测试,然后编写代码,然后冲洗并重复。
从本质上讲,您对TDD应该如何工作的理解(清单)已经关闭。您永远不会传2/100。您应该先通过1/1,再通过2/2,再通过3/3,再通过4/4,依此类推。
为您修改的清单
- 获取所有规格
- 选择一个规格
- 测试一下
- 编码
- 测试一下
- 如果测试通过,则转到7,否则转到4
- 如果已完成所有规格,则转到8,否则转到2
- 与使用者一起检查规格,并在需要时添加新规格。如果操作正确,则完全不必更改任何测试。只需添加新的。有时需求收集可能会崩溃,您必须添加与早期测试冲突的测试,但是您几乎不必更改测试。