为什么乔尔测试中缺少测试驱动的开发?


23

我正在阅读Joel Spolsky撰写的此博客,其中介绍了12步改进代码的步骤。没有测试驱动开发使我感到非常惊讶。所以我想把问题交给上师。TDD真的不值得付出努力吗?


13
该文章写于2000年8月9日(星期三)(大约12年前)。并不是说TDD当时还没有出现,但我不认为它现在享受的嗡嗡声差不多。
Mike

12
Joel测试只是一组通用准则。并非所有“值得付出的努力”都可以满足要求。
扬尼斯

2
' 我提出了我自己的,高度不负责任的草率测试,以评估软件团队的质量。它最重要的部分是大约需要3分钟的时间。乔尔测试(Joel Test)的整洁之处在于,您可以轻松地快速回答每个问题。您不必弄清楚每天的代码行数或每个拐点的平均错误 ……” -决定您的项目是否将受益于TDD会花费3分钟以上的时间, ,可能需要弄清楚每个拐点的平均错误 -这就是为什么它不在列表中
gna 2013年

移至Joel Stack plz。这是一个有趣的问题。
Erik Reppen

您应该考虑接受直接链接到Joel并从Joel引用的答案,因为它没有比这更权威的了。参见programs.stackexchange.com/a/189493/6586
Bryan Oakley

Answers:


30

乔尔(Joel)撰写该帖子两年后的 2002年,肯特·贝克(Kent Beck)的问世之前,几乎没有人进行过测试驱动的开发。问题变成了为什么乔尔没有更新他的测试,或者如果TDD在2000年更广为人知,他会把它包括在他的标准中吗?

我相信他没有,原因很简单,重要的是您要有一个定义明确的流程,而不是该流程的具体细节。这与他建议不指定特定版本控制系统的版本控制,或建议不建议特定品牌的错误数据库的原因相同。好的团队会不断改进和适应,并使用在特定时间适合其特定情况的工具和流程。对于某些团队来说,这绝对意味着TDD。对于其他团队,则不那么多。如果您确实采用了TDD,请确保它不是出于对货物的狂热


1
另外...哦,您在TDD上有点打,是Kool Aid点吗?
Erik Reppen


27

乔尔实际上已经在几个地方专门解决了这个问题。

他解释说,事物测试无法捕获许多重要问题,尤其是主观问题,例如“此软件的用户界面是否糟透了?” 据他介绍,过度依赖Microsoft的自动化测试是我们最终使用Windows Vista的方式。

根据他的经验,他写了用户实际上发现的错误类型通常分为两类:1)经常出现的错误,如果程序员在使用之前运行自己的代码,他们会发现自己的错误或2)边缘案例太晦涩,以至于没有人会想到编写测试来覆盖它们。他说过,他和他的团队在FogBugz中修复的错误中,只有很小一部分是单元测试所能发现的。(我现在找不到该文章,但是如果有人知道我的意思,请随时在此处编辑链接。)

他写了这本书所带来的麻烦,它比其价值更大,尤其是当您的项目成长为具有许多单元测试的非常大的项目,然后您有意地更改某些内容并最终导致大量损坏的单元测试时。 他特别使用了单元测试可能引起的问题,作为他没有将其作为Joel测试的第13点添加的原因,即使有人建议他这样做也是如此。


2
其实你是对的。乔尔(Joel)通常的MO是稻草人。就像TDD不会为我捕获任何错误一样,所以它不是很好。这有点遗漏了TDD不是关于测试,而是关于设计的观点。留下的测试是一个奖励。或者说一个小小的改变会破坏许多单元测试,这表明他做错了。或者在攻击之前完全重写SOLID原理。那种事 实际上,使用循环逻辑的是他的支持者,而不是他。
pdr 2013年

7
我完全同意乔尔的这些评论。我认为语言是一个更大的问题-对于许多动态语言,如果没有单元测试,我无法想象做任何事情-您还能如何判断简单的错字是否会引起您在关键问题之前看不到的问题时刻?在旨在减少错误的静态类型的编译语言中,您会被引导远离所有最简单的错误,而大多数情况下会遇到逻辑错误。这减少了对TDD提供的全覆盖类型的需求。
Bill K

2
@MasonWheeler:您是在认真争论编译器/类型安全性消除了对单元测试的需要吗?您也可能会忽略TDD的设计优势,但更重要的是,您必须费时间重构任何东西。相反,事实恰恰相反:例如,遵循TDD方法的.NET开发人员突然发现,他们对自己需要写的代码量感到沮丧,这是为了使编译器变得越来越无益。
pdr 2013年

2
@pdr:我在认真地争论“首先需要进行单元测试”是缺少类型安全性。而且,由于我不是.NET开发人员,所以我不能真正谈谈他们的经验,但是以我自己的经验,我发现重构的困难完全取决于两个因素:是否在第一个代码中编写了代码位置,以及作者是否编写良好的代码。(请注意:点1和2不一定相互紧密关联!)
Mason Wheeler

3
@Pdr单元测试不能证明您的代码,它们主要是语法检查器,但是在开发过程中可能非常有用。集成和系统测试更有意义。同样,大多数静态类型语言的重构都可以被证明是安全的,实际上重构就是这样-一组已知的“安全”操作可以在不引入更改的情况下转换代码。在静态语言,IDE中往往能做出这些改变你,并确保他们是安全的,事中动态语言,其因此需要单元测试,以协助(未证实)相同的安全往往是不可能的
比尔ķ

25

乔尔·斯波斯基(Joel Spolsky)自己在2009年回答了这个问题

乔尔:关于测试驱动开发的争论……您是否应该对所有内容进行单元测试,诸如此类……许多人在阅读《乔尔测试》后写信给我,说:“您应该拥有第13个事情在这里:单元测试,所有代码的100%单元测试。”

这让我印象深刻,因为对于您可能不需要的某些东西而言,它有点过于笼统。就像,敏捷编程的整个思想不是在需要它们之前先做事,而是根据需要对它们进行页面错误处理。我觉得很多时候对所有内容进行自动测试只是无济于事。换句话说,您将编写大量的单元测试,以确保这些代码确实可以正常工作,并且您肯定会找出它是否不起作用[如果您不这样做,写测试),实际上仍然可以工作,……我不知道,我会收到这样的明文邮件,因为我的表达不够好。但是,我觉得如果一个团队确实在其单元测试中确实有100%的代码覆盖率,就会有两个问题。一,他们将花费大量时间编写单元测试,并且不一定能够以提高质量的方式为这段时间付出代价。我的意思是,他们可以提高质量,并且可以确信自己不会破坏任何东西,但是可以更改代码中的内容,仅此而已。

但是,正如我发现的那样,单元测试的真正问题在于,随着代码的发展,您倾向于进行的更改类型往往会破坏恒定比例的单元测试。有时,您将对代码进行更改,以某种方式破坏了单元测试的10%。故意地。因为您已经更改了某些内容的设计,所以您移动了菜单,现在所有依赖该菜单的内容都在其中...菜单现在位于其他位置。因此,所有这些测试现在都失败了。而且您必须能够重新创建这些测试以反映代码的新现实。

因此最终结果是,随着您的项目变得越来越大,如果您确实有很多单元测试,那么您必须在维护这些单元测试,保持它们的最新状态以及保持他们过去了,开始变得与您从他们那里获得的利益不成比例。


2
真?在张贴乔尔自己对OP问题的答案时是否投反对票?
罗斯·帕特森

1
很难估计。有些人使用投票的意思是“我赞成”,而不是“这是有用的”。这显然是应该接受的答案,因为它是确定的。
布莱恩·奥克利

我从未从事过具有100%测试覆盖率的项目。但是,如果您的测试覆盖率是0%... ...那就很说明问题了。
Kzqai

谢谢!我认为这应该标记为已接受的答案。
Jalal '18

5

除了乔尔,没有人可以肯定地回答。但是我们可以尝试一些原因/观察。

首先,乔尔测验不缺少测验

  • 直接以12个步骤(10和12)两次提到测试
  • 构建的存在是第一要点之一。进行构建的想法是获得查看它们是否损坏的能力,因此我们也在(这里)谈论测试。

其次,乔尔测验(据我所知)的整个想法是要有快速的,是的-没有问题。“你做TDD吗?” 将不完全适合(答案可能是:“我们中的某些人”,“针对该部分代码”或“我们进行单元测试”。

第三,我认为没有人说(甚至是乔尔)那些“唯一值得花时间的人”(顺便说一句,“你编程”不在上面)的意思,只是那些是来时要问的好问题与软件团队联系,无论是作为未来的团队成员,还是作为客户–这是我给周围一些非技术人员的清单,这些人正在寻找有关其IT部门的优劣的线索。这还不是全部,但是三分钟之内击败实在是太糟糕了。


3
“你做TDD吗?” 当然是一个肯定的问题。我的意思是,每个人都以明确的“是”回答这个问题,实际上是“否”。
yannis 2013年

2
@YannisRizos:很像“您使用金钱可以买到的最好的工具吗?” (是的... wellllll ...在合理范围内。)和“程序员的工作环境安静吗?” (哦,是的... wellllll ...我想取决于您的安静点。)
pdr

@pdr取决于您是否认为通过打开的窗户进入的警报声很安静。
罗伯特·哈维

另外,“是的,我进行自上而下的设计。” ;)
Izkata
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.