为了账号安全,请及时绑定邮箱和手机立即绑定

单元测试值得付出努力吗?

/ 猿问

单元测试值得付出努力吗?

牛魔王的故事 2019-11-06 12:05:45

单元测试值得付出努力吗?

我正在努力将单元测试集成到我所工作的团队的开发过程中,有些人对此持怀疑态度。有什么好方法可以让怀疑的开发人员相信单元测试的价值呢?在我的具体案例中,当我们添加功能或修复错误时,我们将添加单元测试。不幸的是,我们的代码库并不适合简单的测试。



查看完整描述

3 回答

?
RISEBY

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

“伙计,我只是喜欢单元测试,我只是对某些事情的工作方式做了一系列的改变,然后通过再次运行测试来确认我并没有破坏任何东西…。

细节每天都在变化,但情绪却没有变化。单元测试和测试驱动开发(TDD)有很多隐藏的和个人的好处,也有显而易见的好处,只有在他们自己做完之后,你才能真正向他们解释。

但是,忽略了这一点,这是我的尝试!

  1. 单元测试允许您快速对代码进行重大更改。您知道它现在起作用了,因为您已经运行了测试,当您进行所需的更改时,您需要让测试再次正常工作。这样可以节省时间。

  2. TDD帮助您了解何时停止编码。你的测试给了你信心,你已经做得够多了,可以停止调整,继续下一件事。

  3. 测试和代码一起工作,以实现更好的代码。你的代码可能是坏的/错误的。你的测试可能很糟糕。在TDD中,你指望的是双管齐下坏/低。通常,需要修正的是测试,但这仍然是一个很好的结果。

  4. TDD有助于便秘的编码。当你面对一件艰巨的工作时,写测试会让你快速前进。

  5. 单元测试帮助您真正理解您正在处理的代码的设计。不是编写代码来做某事,而是从概述代码所受的所有条件以及预期的输出开始。

  6. 单元测试给你即时的视觉反馈,我们都喜欢那些绿灯的感觉,当我们做了。非常令人满意。在中断后,你可以更容易地找到你停下来的地方,因为你可以看到你要去的地方-下一个红灯,需要修理。

  7. 与流行的信念相反,单元测试并不意味着编写两倍的代码,或者编写得更慢。一旦你掌握了它的诀窍,它比没有测试的编码更快、更健壮。测试代码本身通常比较琐碎,不会给您所做的工作增加很大的开销。只有当你这样做的时候,你才会相信:)

  8. 我认为是福勒说的:“不完美的测试,经常运行,比从来没有写过的完美测试要好得多。”我将此解释为允许我编写我认为最有用的测试,即使我的代码覆盖率的其余部分非常不完整。

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

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

我参与的很多工作都没有很好地完成单元测试(web应用程序、用户交互等等),但即便如此,我们在这个商店里也都受到了测试的感染,而且当我们的测试被捆绑在一起时,我们也是最快乐的。我不能高度推荐这种方法。




查看完整回答
反对 回复 2019-11-07
?
忽然笑

单元测试就像去健身房一样。你知道这对你有好处,所有的争论都是有意义的,所以你开始锻炼。有一个最初的匆忙,这是很好的,但几天后,你开始怀疑这是否值得的麻烦。你每天要花一个小时换衣服,骑着仓鼠轮跑,你不确定除了腿和胳膊疼以外,你真的得到了什么。

然后,也许一两周后,就在疼痛消失的时候,一个大的最后期限即将到来。你需要把醒着的每一个小时都花在做“有用”的工作上,所以你把多余的东西都删掉了,比如去健身房。你摆脱了这个习惯,等到大期限结束的时候,你又回到了原点。如果你设法回到健身房,你会感到和你第一次去的时候一样的酸痛。

你做一些阅读,看看你是否做错了什么。开始时,你会对所有健康、快乐的人对运动的优点赞不绝口,感到有点不理智。你知道你们没有太多共同点。他们不需要开车15分钟就能去健身房,他们的楼里有一个。他们不需要和任何人争论锻炼的好处,这只是每个人都会做的,并且认为这是很重要的事情。当大截止日期临近时,他们并没有被告知锻炼是不必要的,就像你的老板要求你停止进食一样。

因此,要回答您的问题,单元测试通常是值得的,但所需的工作量对每个人来说都不一样。单元测试可能需要大量的努力,如果您正在处理公司的意大利面代码库其实价值代码质量(许多管理人员会对单元测试表示赞扬,但这并不意味着他们会在重要的时候坚持下去。)

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



查看完整回答
反对 回复 2019-11-07
?
萧十郎

会说话的核桃问道:

有什么好方法可以说服那些对单元测试的价值持怀疑态度的开发人员呢?

这里的每个人都会突然提出很多理由来解释为什么单元测试是好的。然而,我发现说服某人做某事的最好方法是他们的论点,并逐点阐述。如果你倾听并帮助他们表达他们的担忧,你可以解决每一个问题,也许你可以把它们转换成你的观点(或者至少,让他们没有一条腿站立)。谁知道呢?也许他们会说服你为什么单元测试不适合你的情况。不太可能,但有可能。也许如果你发布他们反对单元测试的论点,我们可以帮助识别反论点。

倾听和理解争论的双方是很重要的。如果您试图过于热情地采用单元测试,而不顾人们的关注,那么您最终将陷入一场宗教战争(而且可能真的是一文不值的单元测试)。如果您慢慢地采用它,并将它应用到您能以最少的成本获得最大效益的地方,那么您可能能够展示单元测试的价值,并且有更好的机会说服人们。我意识到这并不像听起来那么容易-通常需要一些时间和仔细的度量来构建一个令人信服的论点。

单元测试和其他测试一样,是一种工具,在应用时,其好处(捕获bug)要大于成本(编写bug的努力)。如果/在它们没有意义的地方,不要使用它们,记住它们只是工具库的一部分(例如检查、断言、代码分析器、正式方法等等)。我告诉我的开发者:

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

    • 如果开发人员认为方法看起来太简单而不能失败,那么花60秒编写一个简单的5行单元测试不值得吗?这5行代码将每晚运行(您每晚进行构建,对吗?)在接下来的一年或更长的时间里,如果只是偶然发现一个可能需要15分钟或更长时间才能识别和调试的问题,也是值得的。此外,编写简单的单元测试会增加单元测试的数量,这会使开发人员看起来很好。

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

  2. 开发人员需要在他们的单元测试应该有多全面的程度上划出一条“沙中线”。在以后的开发中,每当我们发现一个bug时,他们就应该确定更全面的单元测试是否已经解决了这个问题。如果是这样的话,如果这样的错误反复出现,他们需要将“行”转移到将来编写更全面的单元测试(从添加或扩展当前bug的单元测试开始)。他们需要找到正确的平衡。

重要的是要认识到单元测试并不是一颗灵丹妙药。这样的事情,如太多的单元测试。在我的工作场所,每当我们上一堂课,我都会不可避免地听到“我们需要编写更多的单元测试”。管理层点头表示同意,因为“单元测试”=“很好”被撞到了他们的脑子里。

然而,我们需要理解“更多单元测试”的影响。开发人员每周只能编写N行代码,您需要确定该代码中单元测试代码与生产代码的百分比。一个松懈的工作场所可能有10%的代码作为单元测试,90%的代码作为生产代码,从而产生了大量(尽管非常错误)特性的产品(比如MSWord)。另一方面,一个拥有90%的单元测试和10%的生产代码的严格的工厂将拥有一个功能非常少的坚如磐石的产品(比如“vi”)。您可能从未听说过关于后一种产品崩溃的报告,但这很可能与产品销售不佳有关,也与代码的质量有关。

更糟糕的是,软件开发中唯一确定的就是“改变是不可避免的”。假设严格的车间(90%的单元测试/10%的生产代码)创建了一个完全有两个特性的产品(假设5%的生产代码=1功能)。如果客户出现并更改了其中的一个特性,那么该更改就会破坏50%的代码(45%的单元测试和5%的生产代码)。松懈的商店(10%的单元测试/90%的生产代码)有一个有18个功能的产品,其中没有一个能很好地工作。他们的客户完全修改了4项功能的要求。尽管更改是原来的4倍,但只有一半的代码库被破坏(~25%=~4.4%的单元测试+20%的生产代码)。

我的观点是,你必须沟通,你明白,在太少和太多的单元测试之间的平衡-本质上,你已经考虑了问题的两个方面。如果你能说服你的同龄人和/或你的管理层,你就能获得可信度,也许你就有更好的机会赢得他们的信任。



查看完整回答
反对 回复 2019-11-07

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信