编写单元测试的时间问题

5
我知道TDD的方式是先编写测试代码,然后运行测试看是否失败,接着修改代码使其通过测试。这是一个好的方法,有时候对我很有效。
但是,当我尝试一些新东西(例如不确定设计是否正确,不确定是否能够工作)或者焦急地编写代码时,我不想编写单元测试,因为它会打断我的思路。
我倾向于稍后编写单元测试,特别是在代码变得更加复杂之前。另外,晚些时候编写单元测试通常更加乏味。
我不确定这是否是一个好的方法(绝对不是最好的方法)。
你认为呢?你会在以后编写单元测试吗?或者你如何解决这种情况下的流程问题或实验性设计/代码阶段的问题?
10个回答

16

我学到的是在生产环境和/或紧急时间内,没有实验性代码。通常会进行实验直到某个点“可行”,这时它就成为了生产代码。

另一方面,从一开始就采用TDD会导致你的代码设计更好。你会更多地思考、重构和频繁地改进代码,而不是事后再编写测试。


9

我事后编写了测试。迟到总比不到好。它们总是值得拥有的。

然而,我必须说,第一次在编写被测试代码之前编写测试,感觉非常令人满意。不再需要手动测试。我很惊讶它的效果如此之好。

此外,我倾向于在重构遗留代码之前编写单元测试 - 这几乎意味着我正在编写测试来测试已经编写的代码。提供了一个安全保障,使我更舒适地进入由他人编写的大块代码。


3

“我不确定这是否是一个好的方法(绝对不是最好的)。”

不好吗?为什么?

你是在设计可测试性吗?在这种情况下,你的设计是测试驱动的。还有什么更多的要求呢?

无论测试是先进行、中间进行还是最后进行,都没有设计可测试性重要。最终,对设计的更改会使测试失败,然后你可以修复问题。对于预测设计更改而进行的测试更改也会使测试失败。这两种方法都可以。

如果你完成了设计工作,但在中途遇到了难以测试的部分,那么你就没有做好TDD。你需要重构你的设计,使其可测试。


2

我经常采用你所说的方法。看起来有效的方法是将实验代码视为实验代码,然后根据你所学到的知识开始进行适当的设计。从这里开始,你可以先编写测试。否则,你就会留下许多被编写为临时或实验性代码的代码,并且可能无法为其中所有代码编写测试。


我认为将实验性代码放在一边,使用TDD进行适当规划是一个非常好的观点。 - dr. evil

2
我认为对于正常开发而言,测试驱动开发(TDD)非常有效。虽然有时候可能不需要先写测试(甚至根本不需要),但这种情况并不常见。然而,有时你需要进行一些探索才能确定哪种方式最适合项目。我认为这是一个“尝试”,在这种情况下,我并不认为 TDD 是绝对必要的。我可能不会在我的项目中使用实际的“尝试”代码。毕竟,它只是探索过程,现在我更清楚它应该如何工作了,我可能可以编写比“尝试”代码更好的代码(和测试)。如果我决定使用我的“尝试”代码,我可能会回去为它编写测试。
如果您发现自己违反了 TDD,先编写一些生产代码再编写测试 - 这是很常见的情况 - 那么我也会回过头来编写测试。事实上,在我遇到这种情况时,我经常发现当我开始编写测试时,我忽略了一些东西,因为脑海中会浮现出更多未被代码处理的测试案例。最终,您会重新进入TDD节奏,并发誓再也不犯同样的错误。

2
考虑与沉没成本相关的心理倾向。也就是说,当你到达方程式的第二部分时,我们所有人都有的懒惰基因会让我们想保护我们已经完成的工作。结果呢?
如果你先写测试...
你往往会编写适合测试的代码。这鼓励了“解决问题最简单的方法”类型的开发,并使你专注于解决问题而不是处理元问题。
如果你先写代码...
你会被诱导编写适合代码的测试。实际上,这相当于编写适合答案的问题,这有点反其道而行之,往往会导致价值较低的测试。
尽管我很惊讶50个程序员中只有1个总是先写测试,但我仍然认为,如果你想写出好的软件,这是一个值得追求的目标。

1

我通常先写测试,但有时在尝试时会先写代码。一旦我明确了我的代码应该做什么,我就停止编写代码并开始测试。


0

VS 2008有一个很好的功能,可以为对象生成测试类,测试需要进行微调,但它可以为您完成大部分繁重的工作。这对于为您不太勤奋的同事创建测试非常有用。

另一个好处是它有助于防止您错过某些东西,特别是当您在处理不属于自己的代码时。

如果您使用的是不同的测试框架而不是MSUnitTest,则将测试从MSUnit转换为Nunit等相对简单,只需进行一些复制和粘贴即可。


这是一个很棒的功能。但不幸的是(或者幸运的是!),我正在使用nUnit。 - dr. evil
需要一些工作,但你可以通过复制粘贴将MSUnitTest转换为nUnit测试。 - Bob The Janitor
说实话,回去并不容易,真是让人费解。 - Bob The Janitor

0

当你试图弄清楚代码如何工作时,先编写代码是很自然的。但是,先编写测试可以帮助你确定代码应该做什么(而不是如何做)。如果你先编写代码,那么你正在尝试在完全定义问题之前解决问题。这并不一定是“坏事”,但你正在将单元测试用作回归工具而不是开发工具(再次强调,这并不是“坏事”,只是不符合TDD的原则)。


0

我想说,我总是先写单元测试,但当然我并不总是这样做(对于任何真正的程序员来说,这是众所周知的原因 :-)). 我(好吧,也不总是总是...)做的是将每个花费我超过五分钟时间才能找到的错误转换成一个单元测试。甚至在我修复它之前。这有以下优点:

  • 它记录了错误,并在以后再次出现时提醒我。
  • 它有助于找到错误,因为我有一个明确定义的地方可以放置调试代码(设置我的数据结构、调用正确的方法、设置断点等)。在我发现单元测试之前,我修改了main()函数来进行这个测试代码,结果在忘记之后删除它时产生了奇怪的结果...
  • 通常它会给我很好的想法,还有其他可能出错的地方,所以它经常演变成一堆单元测试,导致发现或修复多个错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接