单元测试值得吗?[关闭]


572

我正在将单元测试集成到我所工作的团队的开发过程中,对此有些怀疑。有什么好的方法可以使怀疑的开发人员相信团队中单元测试的价值?在我的特定情况下,我们将在添加功能或修复错误时添加单元测试。不幸的是,我们的代码库无法使其易于测试。


25
你怎么能问这样的事情。单元测试是如此时髦:)?认真地...总体思路是一样的...如果您认为收益大于成本,则进行单元测试...如果您有理由相信其他方法..找到其他有用的方法。
Gishu

14
(使用debug \ release build +干净的类接口+专用虚拟测试器的常规断言)>单元测试
Viktor Sehr 2010年

110
在以相同的态度参加过几个团队之后,我的经验是您在浪费时间。怀疑论者只会给您带来麻烦,并会破坏和阻碍您,直到您感到沮丧并搬到一家拥有共同价值观的组织。这可能是您应该做的。如果团队的“领导”是怀疑者之一,请认真考虑下车的想法。我已经看到这种对单元测试的抵制只是不良开发实践的冰山一角。
罗布

7
@ViktorSehr:单元测试并不与干净的接口相反,实际上,它们在应用TDD时是相反的。要么,要么驾驶员座椅+方向盘>车库。
乔纳斯·拜斯特伦(JonasByström)2013年

5
单元测试是浪费大量时间,很少发现错误,但却消耗了30%的错误修复和开发时间以及预算
Dominic 2013年

Answers:


722

每天我们办公室里都有这样的交流活动:

“伙计,我只是喜欢单元测试,我已经能够对某些工作方式进行大量更改,然后能够通过再次对它进行测试来确认我没有破坏任何东西……”

细节每天都在变化,但情绪却没有变化。单元测试和测试驱动的开发(TDD)具有许多隐藏的和个人的好处,以及显而易见的好处,您只是在他们自己做之前就无法真正向他人解释。

但是,忽略它,这是我的尝试!

  1. 单元测试使您可以快速更改代码。您知道它现在可以正常运行,因为您已经运行了测试,在进行需要进行的更改时,需要使测试重新运行。这样可以节省时间。

  2. TDD可帮助您了解何时停止编码。通过测试,您可以确信自己已经做了足够的工作,并且可以停止调整并继续进行下一步。

  3. 测试和代码可以一起工作以获得更好的代码。您的代码可能是错误的/错误的。您的测试可能是错误/错误的。在TDD你指望的机会被坏/越野车存在低。通常,这是需要修复的测试,但这仍然是一个很好的结果。

  4. TDD帮助便秘编码。面对大量艰巨的工作,编写测试将使您快速前进。

  5. 单元测试可帮助您真正了解正在处理的代码的设计。您无需编写代码来执行某些操作,而是先概述要使代码遵循的所有条件以及从中获得的期望输出。

  6. 单元测试可为您提供即时的视觉反馈,我们都喜欢完成后所有这些绿灯的感觉。非常令人满意。中断后在哪里停下来也容易多了,因为您可以看到到达的地方–下一个需要修复的红灯。

  7. 与流行的信念单元测试相反,这并不意味着编写两倍的代码或编写速度较慢的代码。一旦掌握了它,它比没有测试的编码更快,更强大。测试代码本身通常是相对琐碎的,不会增加您的工作量。这是您只有在执行此操作时才会相信的方法:)

  8. 我认为正是福勒说:“经常运行的不完美测试比根本没有编写的完美测试要好得多”。我将其解释为允许我在我认为最有用的地方编写测试,即使我的其余代码覆盖范围很不完整。

  9. 好的单元测试可以帮助记录和定义应该做什么

  10. 单元测试有助于代码重用。将您的代码测试都迁移到新项目。调整代码,直到测试再次运行。

我参与的许多工作都无法很好地进行单元测试(Web应用程序用户交互等),但是即使如此,我们在这家商店中都被测试感染,而当我们将测试捆绑在一起时,这是最快乐的。我不能高度推荐这种方法。


您链接的演示文稿是.xul吗?
user2427 2010年

3
问题是关于单元测试。TDD与单元测试完全不同。
ZunTzu 2014年

421

单元测试很像去体育馆。 您知道这对您有好处,所有论点都是有道理的,因此您开始锻炼。最初很急,这很不错,但是几天后,您开始怀疑这是否值得解决。您每天要花一个小时的时间去换衣服,骑仓鼠轮子,而且除了腿和胳膊酸痛以外,您不确定自己还能获得其他好处。

然后,大概一两个星期后,就在酸痛逐渐消失的时候,一个大限期开始了。您需要花每个醒来的时间来尝试完成“有用的”工作,因此您要切掉多余的内容,例如去健身房。您已经习惯了,到“大限期”结束时,您将回到第一位。如果您设法完全回到健身房,您会感到和第一次去时一样疼痛。

阅读一些内容,看看是否做错了。您开始会感到有些不合理的恶意,赞扬所有健康,快乐的人赞美运动的美德。您意识到自己没有太多共同点。他们不必开车15分钟即可去健身房。他们的大楼里有一个。他们不必与任何人争论运动的好处。这只是每个人都做并被接受为重要的事情。当“最后期限”临近时,他们不会被告知没有必要做运动,而老板会要求您停止进食。

因此,为了回答您的问题,单元测试通常值得您付出努力,但每个人所需的工作量并不会相同。 如果您要处理的公司中的意粉代码库实际上并不重视代码质量,那么单元测试可能需要大量的精力。(很多经理都会赞扬单元测试的赞美,但这并不意味着他们会坚持下去。)

如果您试图将单元测试引入您的工作中,而没有看到您期望得到的所有阳光和彩虹,请不要怪自己。您可能需要找到一份新工作才能真正使单元测试为您工作。


15
很棒的轶事!
Sander Versluys'Apr 15'10

68
您的想法令我着迷,我希望订阅您的时事通讯。
Christopher Parker

165
废话,我已经进行了单元测试,但是现在您让我觉得我需要去体育馆。
文斯2010年

16
我也不喜欢 我作为一个极客和一个人类都失败了。
格雷格

13
+1:很多经理都会赞扬单元测试的赞美,但这并不意味着他们会坚持下去,这很重要……您可能需要找到一份新工作才能真正使单元测试为您服务。-好点 非常真实
Jim G.

136

最好的说服方法...查找错误,为其编写单元测试,修复该错误。

该特定错误不太可能再次出现,您可以通过测试来证明。

如果您这样做足够,其他人将很快赶上。


56
仅当您的代码以促进单元测试的方式构建(或使用TypeMock)时,此方法才有效。否则,您将花费大量精力进行测试。大多数没有单元测试的代码都是用硬依赖性(即到处都是新的)或静态方法构建的。这使得几乎不可能仅仅进行快速的单元测试。
安德鲁(Andrew)2010年

7
@Rei-可证明的错误报告非常棒,但是您只打算一次重现该错误。两年后,在错误报告被关闭并遗忘很久之后,您的单元测试仍将检查代码。
Orion Edwards

4
它保存了修复错误1 ...测试...好。用户发现错误2 ...修复...测试...很好。用户再次发现错误1。泡沫,冲洗,重复。发生这种情况是因为您对一个错误的修复导致了另一个错误,反之亦然。
CaffGeek

1
@Rei Miyasaka:“也许如果您有几个人来维护该项目”,我会说几乎所有不重要的项目都可以。关于“只发表评论”:问题是可能(即将)与其他代码进行交互,这可能会导致错误浮出水面。这就是为什么您实际上必须对此进行测试。
sleske 2010年

5
但是请注意,防止回归的测试通常是集成测试,而不是单元测试(因为根据我的经验,大多数错误并非仅出现在代码的一部分中,而是由几部分代码的组合产生的,因此您只能通过组合所有这些片段来复制它们)。
sleske 2010年

69

thetalkingwalnut问:

有什么好的方法可以使怀疑的开发人员相信团队中单元测试的价值?

这里的每个人都会出于很多原因而突然想到单元测试良好的原因。但是,我发现,说服某人某事的最好方法通常是听取他们的论点并逐点解决。如果您倾听并帮助他们表达他们的疑虑,则可以解决每个问题,并可能将其转换为您的观点(或者至少让他们站稳脚跟)。谁知道?也许他们会说服您为什么单元测试不适合您的情况。不太可能,但可能。也许如果您发布他们反对单元测试的论点,我们可以帮助您确定反论点。

聆听和理解论证的两面很重要。如果您过于热心地采用单元测试而不考虑人们的担忧,那么您将陷入一场宗教战争(并且可能真的是毫无价值的单元测试)。如果您慢慢采用它,并从最低成本中获得最大收益的地方开始应用它,您也许能够证明单元测试的价值,并更有说服力。我意识到这并不像听起来那么容易-通常需要一些时间和谨慎的指标来提出令人信服的论点。

单元测试是一种工具,与其他工具一样,应该以这样的方式进行应用:收益(捕获bug)胜于成本(编写成本)。如果它们在没有意义的地方/地方,请勿使用它们,并记住它们只是您工具库中的一部分(例如检查,断言,代码分析器,形式化方法等)。我告诉开发人员的是:

  1. 如果他们有一个很好的论据,为什么没有必要(例如,太简单而不值得,或者太难了却不值得)以及如何以其他方式验证该方法(例如检查,断言),则可以跳过为该方法编写测试的过程,正式方法,互动/集成测试)。他们需要考虑到某些验证,例如检查和形式证明,是在某个时间点进行的,因此每次生产代码更改时都需要重复进行,而单元测试和断言可以用作回归测试(编写一次,然后重复执行) )。有时候我同意他们的观点,但是更多时候我会争论一种方法是真的太简单还是太难以进行单元测试。

    • 如果开发人员认为某个方法似乎太简单而无法失败,那么花60秒为此写一个简单的5行单元测试是否值得?这5行代码将在下一年或以后的每天晚上运行(您每晚进行一次构建,对吗?),即使只是遇到一个可能花费了15分钟或更长时间才能发现的问题,也值得付出努力。和调试。此外,编写简单的单元测试会增加单元测试的数量,这使开发人员看起来不错。

    • 另一方面,如果开发人员认为一种方法似乎很难进行单元测试(不值得进行大量工作),那么这可能很好地表明该方法需要进行分解或重构以测试易用的部件。通常,这些方法依赖于不寻常的资源(例如单例,当前时间)或外部资源(例如数据库结果集)。通常需要将这些方法重构为获取资源的方法(例如,调用getTime())和将资源作为参数的方法(例如,将时间戳作为参数)。我让他们跳过测试检索资源的方法,而是为现在将资源作为参数的方法编写单元测试。通常,这使编写单元测试更加简单,因此值得编写。

  2. 开发人员需要在单元测试的全面程度上划清界线。在开发的后期,每当我们发现错误时,他们都应确定是否进行更全面的单元测试可以解决问题。如果是这样,并且如果此类错误反复出现,则它们需要朝着将来编写更全面的单元测试的方向发展(从为当前错误添加或扩展单元测试开始)。他们需要找到适当的平衡。

重要的是要意识到单元测试不是万能的 这样的事情太多了单元测试。在我的工作场所,每当我们吸取教训时,我都会不可避免地听到“我们需要编写更多的单元测试”。管理层点头表示同意,因为它被人们嘲笑为“单元测试” ==“好”。

但是,我们需要了解“更多单元测试”的影响。开发人员一个星期只能编写约N行代码,您需要确定该代码占单元测试代码与生产代码的比例。宽松的工作场所可能有10%的代码作为单元测试,而90%的代码作为生产代码,从而导致产品具有很多(尽管很容易出错)功能(例如MS Word)。另一方面,拥有90%的单元测试和10%的生产代码的严格车间将拥有功能很少的坚如磐石的产品(认为“ vi”)。您可能永远不会听到有关后一种产品崩溃的报告,但这可能与该产品的销量不佳以及与代码质量的影响不一样。

更糟糕的是,也许软件开发中的唯一确定性是“改变是不可避免的”。假设严格的车间(90%的单元测试/ 10%的生产代码)创建的产品正好具有2个功能(假设5%的生产代码== 1个功能)。如果客户出现并更改其中一项功能,则更改将浪费50%的代码(45%的单元测试和5%的生产代码)。宽松的工厂(10%的单元测试/ 90%的生产代码)的产品具有18个功能,但都无法很好地发挥作用。他们的客户完全改变了其4种功能的要求。即使更改是前者的4倍,也只会浪费掉一半的代码库(约25%=约4.4%单元测试+ 20%的生产代码)。

我的观点是,您必须传达自己的信息,即了解单元测试太少和太多之间的平衡-本质上,您已经考虑了问题的两个方面。如果您可以说服您的同龄人和/或您的管理层,那么您将获得信誉,并可能更有机会赢得他们。


47
如果Vi仅具有很少的功能,则说明您没有使用它。;)
Stefan Mai 2009年

1
如果可以的话,请给斯蒂芬+20 :)
罗伯·格兰特


一个很好的分析,尽管我要说两件事。您似乎假设更改功能需要重写它所依赖的所有代码,而是假设更改与“代码量”更改之间存在线性关系。同样,低测试的产品更可能具有较差的设计,因此“很多功能”产品几乎肯定会为每个功能花费更长的时间(因为几乎没有测试且隐含不良的设计)。
nicodemus13 2013年

为简单的代码块编写测试用例可作为一种回归机制-我所见的唯一的负面影响是添加了更多的堆栈框架...
bgs

38

我曾多次进行过单元测试,但我仍然坚信,鉴于我的情况,值得付出努力。

我开发网站,其中许多逻辑涉及创建,检索或更新数据库中的数据。当我试图“模拟”数据库以进行单元测试时,它变得非常混乱,似乎毫无意义。

当我围绕业务逻辑编写单元测试时,从长远来看,它并没有真正帮助我。因为我主要是独自从事项目工作,所以我倾向于直观地知道哪些代码区域可能受到我正在处理的内容的影响,因此我手动测试了这些区域。我想尽快为客户提供解决方案,而单元测试通常看起来很浪费时间。我列出了手动测试,并亲自完成了这些测试,并在进行过程中将其选中。

我可以看到,当一个开发人员团队从事一个项目并更新彼此的代码时,这可能是有益的,但是即使如此,我仍然认为,如果开发人员的素质很高,那么良好的沟通和良好的编写代码通常就足够了。 。


8
我知道这已经很老了,但是我不得不发表评论。我个人发现为持久层编写测试很成功。只需在测试之前开始交易,然后再回滚即可。无需嘲笑。有时,我有一个类来提取数据数组,然后将数据数组传递给对数据进行“处理”的第二个类。第二类不涉及数据库。在这种情况下,我将测试分组,测试第一类并接触数据库的测试是“功能测试”,并且很少运行,而用于后一类的测试是单元测试,并且经常运行。
Josh Ribakoff 2013年

4
测试与幸福有关。我有一个3900行的程序包(PL / SQL),它可以处理自动过帐到总帐系统的信息。现在,我个人讨厌与会计师打交道-他们对小数便士和诸如此类的东西非常挑剔。Buncha保持肛门的算术极客...我不知道。我的会计程序包的单元测试程序包大约22000行,运行的测试程序不到18000。这使主管会计的Honcho一直很高兴,只要他小的无檐小便帽计数帽上的推进器旋转得很开心,我就很开心... :-)
Bob Jarvis-恢复莫妮卡

31

单元测试的一大优点是它们可以作为文档说明代码的行为。好的测试有点像参考实现,团队成员可以查看它们,以了解如何将代码与您的代码集成在一起。


26

单元测试非常值得初始投资。自几年前开始使用单元测试以来,我发现了一些真正的好处:

  • 回归测试消除了对代码进行更改的担心(没有像每次执行更改时看到代码正常工作或爆炸一样的热情)
  • 其他团队成员(以及您自己在六个月的时间内..)的可执行代码示例
  • 无情的重构 -这是令人难以置信的回报,请尝试一下!

代码段可以大大减少创建测试的开销。创建片段可以在几秒钟内创建类大纲和相关的单元测试夹具,这并不难。


25

您应该尽可能少地进行测试!

意思是,您应该编写足够的单元测试以显示意图。这经常被掩盖。单元测试会花费您。如果您进行更改并且必须更改测试,那么您的敏捷性就会降低。保持单元测试简短有趣。然后,它们具有很大的价值。

我经常看到很多测试永远不会失败,又大又笨拙,并且没有提供太多价值,它们只会使您放慢速度。


23

我在其他任何答案中都没有看到这一点,但是我注意到的一件事是,我可以更快地进行调试。您不需要按照正确的步骤顺序来深入研究您的应用程序即可得到要修复的代码,只需发现您犯了一个布尔错误并需要再次执行所有操作即可。通过单元测试,您可以直接进入要调试的代码。


21

[我要指出的是,我在上面看不到]

“每个单元测试,他们不一定都意识到这一点-事实”

考虑一下,您编写了一个函数来解析字符串并删除换行符。作为新手开发人员,您可以通过在Main()中实现它来从命令行运行一些案例,也可以通过按钮将视觉前端组合在一起,将函数绑定到几个文本框和一个按钮,然后查看怎么了。

那就是单元测试-基本的和糟糕的组合在一起,但是您只在少数情况下测试代码。

您写的东西更复杂。当您通过一些案例(单元测试)并调试代码并进行跟踪时,它将引发错误。您在浏览过程中会查看值,并确定它们是对还是错。这是某种程度上的单元测试。

这里的单元测试实际上就是采取这种行为,将其形式化为结构化模式并保存下来,以便您可以轻松地重新运行这些测试。如果您编写一个“适当的”单元测试用例而不是手动测试,那么它所花费的时间是相同的,或者可能比您所经历的要少,并且可以重复一次


16

多年以来,我一直试图说服人们他们需要为其代码编写单元测试。无论他们是先编写测试(如在TDD中),还是在编写功能代码之后,我总是试图向他们解释为代码进行单元测试的所有好处。几乎没有人不同意我。您不能不同意显而易见的事情,任何聪明的人都会看到单元测试和TDD的好处。

单元测试的问题在于,它需要改变行为,并且很难改变人们的行为。用言语,您会得到很多人的同意,但是您做事的方式不会看到很多变化。

您必须通过说服人们。您个人的成功将吸引更多的人,而不是您可能拥有的所有论点。如果他们看到您不仅在谈论单元测试或TDD,而且您正在做自己的演讲,并且您成功了,那么人们会尝试模仿您。

您还应该担任领导角色,因为没有人第一次正确编写单元测试,因此您可能需要指导他们如何进行单元测试,向他们展示方法以及可供他们使用的工具。在他们编写第一个测试时帮助他们,回顾他们自己编写的测试,并向他们展示您从自己的经验中学到的技巧,习语和模式。一段时间后,他们将开始自己看到收益,并且他们将改变其行为,以将单元测试或TDD纳入其工具箱。

改变不会在一夜之间发生,但是只要有一点耐心,您就可以实现自己的目标。


12

通常会掩盖测试驱动开发的主要部分是可测试代码的编写。乍看起来似乎是一种折衷,但是您会发现可测试代码最终还是模块化的,可维护的和可读的。如果您仍然需要说服他人的帮助,是一个关于单元测试优点的简单演示。


11

如果您现有的代码库不适合进行单元测试,并且已经在生产中,则可能会尝试重构所有代码以使其可以进行单元测试,从而产生比解决方案更多的问题。

您不妨全力以赴来改善集成测试。那里有很多无需单元测试就可以编写的代码,如果QA可以根据需求文档验证功能,那么就可以了。装运它。

我想到的经典示例是嵌入到链接到GridView的ASPX页面中的SqlDataReader。该代码全部在ASPX文件中。SQL在存储过程中。您要进行什么单元测试?如果页面做了应有的功能,您是否应该将页面真正地重新设计为几层,以便进行自动化处理?


10

关于单元测试的最好的事情之一就是您的代码将变得更容易测试。在没有测试的情况下创建的预先存在的代码始终是一个挑战,因为由于它们并不是要进行单元测试的,因此在类之间,类中难以配置的对象之间进行高级别的耦合并不是罕见的,例如电子邮件发送服务参考-等等。但是,不要让这让您失望!您会发现,随着开始编写单元测试,您的总体代码设计会变得更好,并且测试越多,您就越有信心对其进行更多更改,而不必担心会破坏您的应用程序或引入错误。 。

进行单元测试代码的原因有很多,但是随着时间的推移,您会发​​现节省测试时间是最好的理由之一。在我刚刚交付的系统中,尽管声称与手动测试系统相比,我花费更多的时间进行测试,但我仍坚持进行自动化的单元测试。完成所有单元测试后,我在不到10分钟的时间内运行了400多个测试用例,每次必须对代码进行小改动时,我所要做的全部工作是确保代码仍能正常工作而没有错误,只有十个分钟。您能想象一个人花时间手动运行这400多个测试用例吗?

当涉及到自动化测试(无论是单元测试还是验收测试)时,每个人都认为浪费精力来编写您可以手动执行的操作,有时候这是对的-如果您计划只运行一次测试。自动化测试最好的部分是您可以毫不费力地运行它们几次,并且在第二次或第三次运行之后,您已经浪费了时间和精力。

最后一条建议是不仅要对代码进行单元测试,还要先开始进行测试(有关更多信息,请参见TDDBDD


8

当涉及重构或重写一段代码时,单元测试也特别有用。如果您具有良好的单元测试覆盖范围,则可以放心地进行重构。没有单元测试,通常很难确保您没有破坏任何东西。


7

简而言之-是的。在某种程度上,它们值得每一刻的努力。最终,测试仍然是代码,并且就像典型的代码增长一样,最终将需要重构测试以保持可维护性和可持续性。一吨的GOTCHAS!当涉及到单元测试时,但是,天哪,没什么,我的意思是,NOTHING比一组丰富的单元测试更能使开发人员更自信地进行更改。

我现在正在开发一个项目...。有点TDD,并且我们将大多数业务规则封装为测试...我们现在大约有500个左右的单元测试。在过去的迭代中,我不得不修改数据源以及桌面应用程序与该数据源的接口。花了我几天的时间,整个过程中我一直在运行单元测试,以查看发生了什么问题并进行修复。做出改变; 建立并运行测试;修理你弄坏的东西。洗涤,漂洗,根据需要重复。传统上需要几天的质量检查和大量的压力,这是一次短暂而愉快的经历。

预先做好准备,需要付出一些额外的努力,而当您不得不开始关注核心功能时,它需要支付10倍的费用。

我买了这本书-这是有关xUnit Testing的圣经-可能是我书架上参考最多的书之一,并且我每天都在浏览它: 链接文本


+1:但是,老兄,老兄,老兄,没什么,我的意思是,NOTHING比一组丰富的单元测试更能使开发人员更自信地进行更改。- 如此真实。我希望我能早点解决这个问题。
Jim G.

7

有时我自己或我的一位同事都会花几个小时来探究稍微模糊的错误的根源,一旦发现错误的原因,有90%的时间未对代码进行单元测试。单元测试不存在,因为开发人员在偷工减料以节省时间,但随后又放开了它并进行了更多调试。

花很少的时间编写单元测试可以节省数小时的未来调试时间。


+1:花费少量时间编写单元测试可以节省未来调试的时间。- 对!
Jim G.

7

我正在做一个记录不佳,糟糕而又庞大的代码库的维护工程师。我希望编写代码的人已经为此编写了单元测试。
每当我进行更改并更新生产代码时,我都会担心由于未考虑某些条件而可能引入错误。
如果他们编写了测试,则对代码库的更改将变得更加容易和快捷(同时,代码库将处于更好的状态)。

我认为单元测试在编写必须持续多年并且要由原始编码人员以外的人员使用/修改/发展的api或框架时非常有用。


您是否为新代码或所做的修复添加单元测试?
oɔɯǝɹ

6

单元测试绝对值得付出努力。不幸的是,您选择了一个困难的(但不幸的是很常见)的方案来实现它。

从单元测试中获得的最大好处是从头开始使用它-在一些精选的小型项目中,我很幸运在实现类之前就编写了单元测试(接口已经完成了)点)。通过适当的单元测试,您可以在班级中仍处于初级阶段的错误中发现并修复错误,而这些错误无疑会在将来毫无疑问地集成到复杂的系统中。

如果您的软件是面向对象的,那么您应该能够在类级别上添加单元测试,而无需花费太多精力。如果不是那么幸运,那么您仍应尽可能尝试合并单元测试。确保在添加新功能时,使用清晰的界面就可以很好地定义新部件,并且会发现单元测试使您的工作变得更加轻松。


6

当您说“我们的代码库无法使其易于测试”时,这是代码气味的第一个迹象。编写单元测试意味着您通常以不同的方式编写代码,以使代码更具可测试性。在我看来,这是一件好事,因为多年来我在编写必须为其编写测试的代码时所见,这迫使我提出更好的设计。


6

我不知道。很多地方不做单元测试,但是代码的质量很好。微软进行单元测试,但是比尔·盖茨在演讲中给出了蓝屏。


请注意,这差不多是15年前,当时单元测试并不像今天这样流行。
fwielstra

1
而且Internet Explorer仍然无法保存许多网页。
Cees Timmerman

5

我写了一篇有关该主题的大型博客文章。我发现单靠单元测试是不值得的,通常会在截止日期临近时被削减。

与其从“测试后”验证的角度谈论单元测试,不如着眼于在实施之前编写规范/测试/想法时发现的真实值。

这个简单的想法改变了我编写软件的方式,并且我不会回到“旧”方式。

测试第一次开发如何改变了我的生活


1
+1-我必须说,令人难以置信的是,该博客条目吸引了多少个巨魔(如果没有记错的话,在此之前发布)。
杰夫·斯坦恩

哈哈同意了:) </ reddit的首页确实如此>
Toran Billups 2010年

3

是的-单元测试绝对值得付出努力,但您应该知道这不是万灵丹。单元测试是可行的,您将不得不努力保持测试的更新和相关性,因为代码会发生变化,但是所提供的价值值得您付出一定的努力。不受惩罚的重构能力是一项巨大的好处,因为您可以始终验证功能在任何更改代码之后运行测试。诀窍是不要过于迷恋要测试的工作单元或脚手架测试需求的方式,以及何时单元测试确实是功能测试等。人们会争论数小时。最后,现实是,在编写代码时进行的任何测试总比不进行测试要好。另一个公理是质量而不是数量-我见过1000'的代码库 测试基本上没有意义,因为其余测试实际上并没有测试任何有用的东西或特定领域的任何特定领域,例如业务规则等。我也看到过代码库覆盖了30%的代码,但是这些测试是相关的,有意义的,并且确实很棒,因为它们测试了所编写代码的核心功能并表达了应如何使用该代码。

在探索新框架或代码库时,我最喜欢的技巧之一是为“ it”编写单元测试以发现事物的工作方式。这是一种学习更多新知识的好方法,而不是阅读干燥的文档:)


3

最近,我在工作场所经历了完全相同的经历,发现他们中的大多数人都知道理论上的好处,但是必须将这些好处专门卖给他们,所以这是我(成功地)使用的要点:

  • 它们可以在执行负面测试时节省时间,在负面测试中您可以处理意外的输入(空指针,超出范围的值等),因为您可以在单个过程中完成所有这些操作。
  • 它们在编译时提供有关更改标准的即时反馈。
  • 它们对于测试在正常运行时可能不会公开的内部数据表示形式很有用。

还有那个大...

  • 您可能不需要进行单元测试,但是当其他人进入并修改代码而又不完全理解时,它可能会捕获很多他们可能犯的愚蠢错误。

+1:•您可能不需要单元测试,但是当其他人进入并在不完全了解的情况下修改代码时,它可能会捕获许多他们可能犯的愚蠢错误。- 对。鉴于软件行业的营业额,这是一个巨大的好处。
Jim G.

3

几年前,我发现了TDD,从那时起,我就使用它编写了所有宠物项目。我估计完成TDD项目和共同完成牛仔项目大约需要相同的时间,但是我对最终产品的信心越来越大,以至于我不禁感到成就感。

我也觉得它改善了我的设计风格(如果需要一起模拟的话,它会更多地面向界面),并且,如顶部的绿色文章所述,它有助于“编码便秘”:当您不知道什么时接下来写,或者您面前有艰巨的任务,可以写小写。

最后,我发现到目前为止,TDD最有用的应用是在调试中,这仅仅是因为您已经开发了一个查询框架,您可以使用该框架来促使项目以可重复的方式产生错误。


3

还没有人提到的一件事是,让所有开发人员共同致力于实际运行和更新任何现有的自动化测试。由于新开发而导致您回到并发现自动测试失败的自动测试失去了很多价值,并使自动测试真的很痛苦。由于开发人员已经手动测试了代码,因此大多数测试都不会指示错误,因此花在更新它们上的时间只是浪费。

说服怀疑论者不要破坏其他人在单元测试中所做的工作对于从测试中获取价值非常重要,而且可能会更容易。

每次从存储库进行更新时,花费数小时来更新由于新功能而中断的测试既无益又无聊。


2

如果您正在使用NUnit,则一个简单而有效的演示就是在它们前面运行NUnit自己的测试套件。看到一个真正的测试套件为代码库提供了锻炼,值得一千个单词。


2

单元测试对大于任何开发人员所能承受的项目有很大帮助。它们使您可以在签入之前运行单元测试套件,并发现是否损坏了某些内容。这减少了很多事情,不必坐下来不停地旋转手指,而又等待其他人修复他们签入的错误,或者麻烦恢复他们的更改,以便您可以完成一些工作。它在重构中也非常有价值,因此您可以确保重构后的代码能够通过原始代码所做的所有测试。


2

使用单元测试套件,您可以更改代码,同时保留其余功能不变。这是一个很大的优势。完成新功能编码后,是否使用单元测试支持和回归测试套件。


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.