是否有确凿的证据证明单元测试的投资回报率?


127

单元测试对我来说听起来很棒,但我不确定除非我可以说服其他人具有重大价值,否则我不应该花任何时间真正地学习它。我必须说服其他程序员,更重要的是,要让管理中的bean计数器相信,花在学习测试框架,编写测试,保持它们更新等上的所有额外时间都可以收回成本,然后付出一些。

有什么证明?有没有人实际上由两个独立的团队来开发相同的软件,一个使用单元测试,另一个不使用单元测试,并比较结果?我对此表示怀疑。我是否应该以“在Internet上查找它,每个人都在谈论它,所以它一定是正确的事情”来证明它的合理性?

在哪里有确凿的证据可以使外行信服单元测试值得努力?

Answers:


98

是。这是一个链接在NCST的调查结果表明波比乔治和劳瑞·威廉姆斯和另一个由Nagappan等。我敢肯定还有更多。Williams博士有关测试的出版物可能为找到它们提供了一个很好的起点。

[编辑]上面的两篇论文特别提到了TDD,并表明采用TDD后初始开发时间增加了15-35%,但释放前缺陷减少了40-90%。如果您无法获得全文本版本,建议您使用Google学术搜索查看是否可以找到公开版本。


14
第一项研究将敏捷+ TDD与瀑布项目进行了比较,如果将两个敏捷团队进行比较,其结果将更加相关。第二项研究提到了其他研究,这些研究发现TDD项目的质量奖励很少甚至没有。而且,当您比较管理层对TDD所需额外时间的估计时,这两个具有较高领域专业知识的团队的估计值明显更高,但他们的测试覆盖率也降低了20%。这证实了我的经验,我发现在尚未使用过的系统中,保证要重要得多,而测试对其他所有方面都是一个障碍。
LearnCocos2D

两项研究都没有将可比较的过程模型与测试方法学的变化进行比较。那就是花在UT上的时间实际上要花在例如上。系统测试。从目前的情况来看,最好还是研究“如果我们更聪明地测试会有所帮助”。
符文FS 2014年

1
那么,如果修复发布后的bug的成本占总开发量的0.01%,该怎么办?在这种情况下,TDD将是一项糟糕的投资。如果错误很少?没有上下文,这些%s毫无意义。公平地说,我尚未阅读整个研究。但就目前情况而言,您的帖子很有用(良好的链接),但不能回答有关ROI(投资回报率)的问题,IMO。
Instine 2014年

1
@Instine幸运地(?)有充分的证据表明事实并非如此。修复发布后的错误比开发早期发现的错误(TDD所做的事情)成倍增加。在这种情况下,似乎不太可能为所有发布后的错误花费0.01%的总开发成本。(有关详细信息,请参见Code Complete,尤其是Boehm 等人,“理解和控制软件成本”,IEEE Trans Softw Eng(1988))。
Konrad Rudolph 2014年

可能值得注意的是,第一项研究的样本量为24位程序员(成对工作,因此有12个团队)。我不确定统计学上有效的样本量是多少,但这些数字似乎很低。也许别人知道吗?
Zachary Yates

29

“我必须劝服其他程序员,更重要的是,要帮助管理中的bean计数器,所有花在学习测试框架,编写测试,保持它们更新等上的额外时间都将自己付出代价,然后再付出一些。 ”

为什么?

为什么不安静地,离散地这样做呢?您不必一次完成所有操作。您可以分小块来完成。

框架学习花费很少的时间。

编写一项测试,只需一项,只需很少的时间。

没有单元测试,您所拥有的只是对软件的信心。通过一项单元测试,您仍然可以放心,并证明至少有一项测试通过了。

这就是全部。没有人需要知道您正在这样做。去做就对了。


9
如果bean计数器的生命依赖于它,则无法从其余代码中分辨出单元测试。我支持这样做的建议。但是,有一个警告:如果您并不孤单,则需要其他开发人员来接受这种做法。如果没有,他们会无意间破坏您的测试。
Thomas Eyde

只要做就不要告诉他们,然后在喝咖啡休息时间把这个想法卖给你的大学;-)
约翰(Johan)2009年

3
因为您一再未能按时完成任务会被解雇吗?
安德鲁(Andrew)2010年

3
@Neko:单元测试不会增加“开销”。它们通过防止大量的愚蠢错误来减少总体工作量。工作没有增长;它只是本质上从不良代码转变为良好的单元测试和良好的代码。
S.Lott 2012年

1
bean计数器希望他们的工程师为域问题提供合理的解决方案。您可以只编写测试作为解决方案的一部分。他们甚至不会注意到。如果他们要求您告诉他们,您将花更多的时间在此上,以确保其功能强大并且不需要返工。如果您建议向他们编写单元测试,那么您正在征求他们对他们一无所知的批准。
约克郡人

16

我对此采取了不同的方法:

您有什么保证您的代码正确?还是当团队中的某人更改func1()时,它不会破坏假设X?如果没有单元测试使您保持“诚实”,我不确定您是否有足够的把握。

保持测试更新的概念很有趣。测试本身不必经常进行更改。我有3倍的测试代码相比,产品代码和测试代码已经改变非常小。但是,这是让我在晚上睡个好觉的原因,也是使我告诉客户我有信心可以在不破坏系统的情况下实现Y功能的事情。

也许在学术界有证据,但是我从来没有在商业世界的任何地方工作过,任何人都愿意为这种测试付费。但是我可以告诉您,它对我来说效果很好,花了很少的时间就习惯了测试框架,编写测试使我真正考虑了自己的要求和设计,远远超过了在团队中工作时所经历的时间。没有写测试。

这就是它的回报:1)您对代码有信心,2)您比以前更早发现问题。您没有质量检查人员说:“嘿,您没有麻烦检查xyz()函数,对吗? 没有找到该bug,因为一个月前就发现了。这对他,对您有好处,对公司有好处,对客户也有好处。

显然,这是轶事,但它为我带来了奇迹。不确定我可以为您提供电子表格,但是我的客户很满意,这就是最终目标。


我的质量检查人员非常敏锐,但是他没有看代码,但是很容易看出未检查界限。
itmatt

完全同意单元测试,这迫使您多考虑设计和正确性,而不是
鲁less地

7
客户不付钱给我们写测试。再说一次,他们也不付钱给我们写代码。他们付钱给我们解决他们的问题,当他们遇到问题时,我敢打赌他们也希望问题继续得到解决。有了证据,令人难以置信的客户不想获得他们的投资。
Thomas Eyde

10

我们有充分的证据表明,无需进行单元测试就可以编写糟糕的软件。我相信,甚至有证据表明单元测试中的软件太差劲了。但这不是重点。

单元测试或测试驱动开发(TDD)是一种设计技术,而不是测试技术。编写为测试驱动的代码看起来与没有代码完全不同。

即使这不是您的问题,但我想知道这是否真的是最简单的方法,可以回答错误的问题(并提供可能受到其他报告质疑的证据)。即使您找到了确凿的证据,也可能有人反对。

确定技术人员的工作方式是bean柜台的业务吗?他们是否在所有情况下都提供了最便宜的工具,因为他们认为您不需要更昂贵的工具?

该论点要么基于信任而获胜(敏捷团队的基本价值之一),要么基于获胜方的角色力量而丧失。即使TDD支持者基于角色能力获胜,我也将其视为失败。


13
听,听:) TDD的许多确凿证据也来自经验丰富的团队,如果没有它,他们已经取得了良好的成绩。TDD只是改善了结果,而不是凭空创造出来的。真正的投资回报率是聘请体面的编码人员,并让他们决定如何做事情。
workmad3

“确定技术人员的工作方式是bean柜台的业务吗?” ->所有业务决策都归结为金钱。答案还是不错,+ 1
jcollum

@jcollum,但是您的工作方式与金钱无关,如果您希望承担责任,您可以让他们决定如何执行您要求的工作
Rune FS

TDD不是一种设计技术,它只是一种编码技术。blog.ploeh.dk/2010/12/22/TheTDDApostate许多评论者不同意TDD涉及重构(这是一种设计技术),但重构并不意味着TDD。一个人可以在没有测试的情况下进行重构,大型的复杂重构无论如何都会影响单元测试,即测试也需要重构,因此也可能变为无效/假绿色;更简单的重构很多不会影响测试,但是出错的风险更低-因为重构很简单。
KolA

@KolA良好,10。5年这个答案后,我可能会句话反映这一点更具防御性的今天,但还是:我不认为TDD是唯一的,你永远需要设计技术和马克它是打开在断定根本不是一个设计技术之前。我会削弱他的意见,并说,它不能唯一的设计技术。曾经写过TDD的每个代码看起来都与我没有编写过的代码不同。我称其为设计的结果。除了TDD之外,我还可以最好地使用白板,讨论和其他工具。但感谢您的链接
Olaf Kock


6

关于TDD的更多内容,不仅仅包括严格的单元测试,它还涉及通过测试驱动的开发实现质量改进: Nagaappan,E。Michael Maximilien,Thirumalesh Bhat和Laurie Williams 的四个工业团队论文的结果和经验。由Microsoft 经验软件工程与测量(ESM)组发布的论文,此处已提及。

该团队发现,TDD团队所产生的代码(在缺陷密度方面)比非TDD团队高出60%到90%。但是, TDD团队花费了15%到35%的时间才能完成他们的项目。


5

这是一个很棒的有趣的读物,讲述了一个人从内部改变公司的经历。不限于TDD。http://jamesshore.com/Change-Diary/请注意,他已经有一段时间没有说服“反击”了,而是采取了“游击战术”。


该链接看起来很有趣...值得一试:重新更改组织的工作流程...
讨厌的糊糊

5

只是为了向这些答案添加更多信息,有两种荟萃分析资源可以帮助弄清生产力和质量对学术和行业背景的影响:

客座编辑介绍:TDD —无所畏惧的编程艺术[ link ]

所有研究人员似乎都同意TDD鼓励更好地专注于任务和测试覆盖范围。仅仅是更多测试的事实并不一定意味着软件质量会更好,但是程序员对测试设计的更多关注仍然令人鼓舞。如果我们将测试视为对大量潜在行为的抽样,那么更多的测试意味着更彻底的采样。在某种程度上,每个测试都能找到其他人都找不到的重要问题,所以这些测试很有用,特别是如果您可以廉价地运行它们。

表1.测试驱动开发的一些经验研究摘要:行业参与者*

https://www.computer.org/cms/Computer.org/dl/mags/so/2007/03/figures/s3024t1.gif

表2. TDD的一些经验研究摘要:学术参与者*

在此处输入图片说明

测试驱动开发对外部质量和生产率的影响:一项荟萃分析[ link ]

抽象:

本文对27项研究进行了系统的荟萃分析,这些研究调查了测试驱动开发(TDD)对外部代码质量和生产率的影响。

结果表明,总体而言,TDD对质量的影响较小,但对生产率的影响却很小甚至没有。但是,亚组分析发现,与学术研究相比,工业研究的质量提高和生产率下降都更大。在研究中发现生产率的下降更大,在这些研究中,TDD和对照组过程之间的测试工作量差异很大。当测试工作的差异很大时,在学术研究中也发现质量有较大提高。然而,由于缺乏数据,无法得出有关工业研究的结论。

最后,研究了开发者经验和任务大小作为主持人变量的影响,并且发现任务大小与质量改进幅度之间存在统计学上的显着正相关。


4

好吧,有些大型公司要求您使用单元测试,但是如果您是小型公司,为什么要模仿大型公司?

对我来说,很多年前开始进行单元测试时(今天我们主要使用行为模型)是因为我无法控制一个应用程序中的所有路径。

我习惯了将程序设计和REPL放在首位,所以当我进行单元测试(每个功能一个测试)时,就像将REPL带回了很多可编译的语言一样。它把乐趣带回到了我编写的每一行代码中。我感觉到上帝了。我喜欢 我不需要报告就可以告诉我我开始更快地编写更好的代码。我的老板不需要报告就可以注意到,因为我们在做疯狂的事情,所以我们突然没有错过最后期限。我的老板不需要报告就可以注意到,由于编写非生产性代码这一非常奇怪的事情,“普通”错误的数量从(很多)下降到了几乎为零。

正如另一位发帖人所写,您不使用TDD进行测试(验证)。您编写它来捕获规范,单元(对象,模块,函数,类,服务器,集群)的工作行为。

在许多公司中,有很多失败和成功的故事,它们都转向了不同的软件开发模型。

每当我有新东西要写时,我就开始使用它。有句古话对我来说很难翻译成英语,但是:

从简单的事情开始,您不会注意到自己在做。训练马拉松时,首先要步行9米,然后跑步1米,然后重复。


所以,我应该这样做吗?它可以保证工作,并且没有人与我无关紧要吗?
乌鸦

实际上,这是一个Joel测试:joelonsoftware.com/articles/fog0000000043.html。在我看来,您可能比没有获得诺贝尔奖单元测试研究更大的问题
Jonke,

4

有统计数据表明,修复在单元/集成测试中发现的错误的成本要比在实时系统上修复错误的成本低很多倍(它们基于监视数千个现实项目)。

编辑:例如,如前所述,“ 代码完整 ” 这本书报告了此类研究(第20.3段,“质量技术的相对有效性”)。但是咨询领域也有私人研究证明了这一点。


1
这是史蒂夫·麦康奈尔(Steve McConnell)的《代码完成》Code Complete)所涵盖的,由于其他原因,您可能希望将此书放在书架上。
罗伯特·罗斯尼,

这与测试方法无关,但与报告过程中的错误时间有关,并且进一步地,花时间查找规范中的错误会更好,因为据报告,在开发时发现它们时修复它们的成本据称高达1000倍(每个开发阶段10倍)
Rune FS

OTOH,如果您只解决人们在现实生活中实际遇到的问题,那么您可能最终必须解决的错误要少得多。对我来说还不清楚,早日修复错误确实便宜,因为在规范中检测到一个错误可能比在实现中检测到相同的错误需要更多的工作,而检测到的错误是错误修复成本的一部分。这是每个人都相信的事情之一,因为这听起来不言而喻,但我从未见过能证明这种效果的声音研究。
LKM

0

我确实有一组数据点-来自在单元测试中卖给我的经验。

许多个月前,我刚毕业,从事大型VB6项目的工作,并有机会编写大量的存储过程代码。我正在编写的子系统中,它约占整个代码库的1/4-在50K左右的范围内,约有13,000 LOC。

我为存储过程编写了一组单元测试,但是如果没有像Rational Robot这样的工具,单元测试VB6 UI代码实际上是不可行的。至少那时还没有。

从QA的统计数据来看,整个子系统上出现了大约40或50个缺陷,其中两个源自存储过程。这是每6,500行代码中一个缺陷,而整个每1000-1,200。还请记住,大约VB6代码的2/3是用于错误处理和记录的样板代码,在所有过程中都是相同的。

无需花费过多的精力,就可以将缺陷率的改善至少提高一个数量级。

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.