单元测试的爱恨情仇,作为码农们,你们写单元测试么?

2022-10-11 19:01:43 +08:00
 tikazyq

作为从事软件开发多年的资深码农,看遍了各种事故和火葬现场。在接触测试驱动开发以及敏捷之后,发现这正是解决 bug 丛生、issue 漫天,最终导致 996 、007 修 bug 的困境。

这里将单元测试的一些看法分享给大家,希望能够提供一些启发。英译版同步发布在 dev.to,欢迎一起交流学习。

下面是正文。


浅谈测试:单元测试的爱恨情仇

引子

"开发安全可靠的应用程序的最好方式,就是不写代码。"--Kelsey Hightower

很多开发者应该或多或少听过单元测试( Unit Tests ),甚至编写过,也或许对其有所了解。不过,在如今瞬息万变的环境下,单元测试似乎正在成为鸡肋。程序员们都知道它的好处,但是对其显得比较冷淡。“进度这么赶,还有什么时间写单元测试呢?”这样的话是不是听着很熟悉?

单元测试是什么?

所谓单元测试,简而言之就是程序员编写测试代码来验证自己写的功能代码是否能按照要求运行。如果测试代码不能通过,就说明自己写的功能代码是有问题的。

这种自己测自己的方式似乎有些可笑,相当于考试时看着答案做题。然而在测试领域,这样的方式有个专业术语叫白盒测试。而白盒测试的对立术语叫黑盒测试,也就是用其他方式来验证。单元测试属于白盒测试,而更高级的测试例如集成测试( Integration Tests )、端到端测试( End to End Tests )、UI 测试( UI Tests ),都属于黑盒测试。单元测试仅仅是测试代码本身。

单元测试有什么用?

单元测试在敏捷开发( Agile Development )中是非常有用的工具。甚至有些敏捷框架,例如极限编程( XP ),就要求每一个功能必须被单元测试覆盖。在之前的文章《浅谈敏捷:你的团队在正确实践敏捷吗?》就提到过单元测试的重要性。

概括来说,单元测试有下面几个重要作用:

因此,表面上来看,单元测试对于软件开发来说会带来比较大的收益。

为什么不写单元测试?

单元测试可以提高我们的产品质量、测试效率,那为什么程序员还是不喜欢写单元测试呢?据 JetBrains 统计,被调查者中仅有 57% 要写单元测试,仅有 35% 会在大部分项目中实施自动化测试。

那么,为什么?有几个可能的主要原因:

然而,这几个原因都经不起推敲:第一,长期来看自己修复 bug 写的代码量肯定远不止这么点;第二,不管是多么牛逼的程序员,代码写多了,根据大数定理,都会有失误的时候;第三,简单功能如果被引用多了,也会变得重要;第四,QA 的主要工作是保证整体质量,而单元测试是保证局部质量,缺陷部件组装出的产品会优质么?

变得有远见

其实,这里最主要的原因是思维模式,程序员大部分时候会站在个体的角度,思考短期的问题,从而忽略了长期的成本收益。作为一个合格的开发者,最主要目标是用最有效的方式开发出最大价值的功能。因此,单元测试在短时间内无法创造价值,从而被很多人忽视。

单元测试就像读书,短期内不能让人知识渊博、名利兼收,但长期来看是会有效果的。单元测试如果成为习惯或组织文化,就会更容易打造高质量产品和持续交付。要在团队中推广单元测试,需要更根本的流程,例如极限编程、测试驱动编程,或者更高决策者,例如 CTO 、架构师。

社区

如果您对笔者的文章感兴趣,可以加笔者微信 tikazyq1 并注明 "码之道",笔者会将你拉入 "码之道" 交流群。

本篇文章英文版同步发布在 dev.to,技术分享无国界,欢迎大佬们指点。

6215 次点击
所在节点    程序员
79 条回复
tikazyq
2022-10-12 10:19:54 +08:00
@lysS 可以用 mock 来做
tikazyq
2022-10-12 10:20:37 +08:00
@wszzh 这种方式也可以,虽然有依赖,但也足够简单,也属于单元测试
tikazyq
2022-10-12 10:21:22 +08:00
@Menkou 一般 UI 测试、集成测试用的这类工具,其他还有 playwright 、selenium 、puppeteer
tikazyq
2022-10-12 10:22:56 +08:00
@wolfie java 有 junit 还是挺好用的,写单元测试还是很考验经验的,如果设计的好,整个架构都会良性优化
wupher
2022-10-12 10:23:22 +08:00
很有好处,尤其是有问题可以直接回归测试,发版本前自动测试。

业务越复杂,mock 越麻烦。
有专门测试数据库,但是数据库表的测试数据维护又是另外一个麻烦和依赖。

测试让代码可维护可依赖。但有时候测试代码本身又需要维护和依赖。TDD 不是坏事,只是,嗯,要看业务和管理是否愿意承认它的价值和代价了。
tikazyq
2022-10-12 10:24:10 +08:00
@unco020511 客户端没怎么接触过,不知道 ut 是否能有收益
urnoob
2022-10-12 10:24:16 +08:00
业务开发不要写单元测试!!!!!!!!!!!!!
tikazyq
2022-10-12 10:26:42 +08:00
@rodrick 前端的 ut 确实需要看看大神们如何写的
tikazyq
2022-10-12 10:28:40 +08:00
@wupher 很有道理,大佬应该是 TDD 专家,看起来很有经验。UT 的收益一般在代码覆盖率不饱和的情况下收益很大,越到后面边际效应越明显,所以中庸之道才是正解
tikazyq
2022-10-12 10:28:57 +08:00
@urnoob 有什么故事?😂
frank1256
2022-10-12 10:29:28 +08:00
项目刚开始开发,不稳定,写单测来不及写就业务变化了。稳定后再补充单测。提交代码时会走单测和自动化测试脚本,过了才可以 review
tikazyq
2022-10-12 10:30:40 +08:00
@frank1256 这也是可以的,跟敏捷类似,没有课本中那种教条的规则,只要适合自己团队和开发模式就可以
JasonLaw
2022-10-12 10:38:03 +08:00
@dayeye2006199 #7 <amp-youtube data-videoid="fr1E9aVnBxw" layout="responsive" width="480" height="270"></amp-youtube>&t=577s - Write Your Tests First!
zhuweiyou
2022-10-12 11:06:00 +08:00
又不是做开源, 业务开发不写, 测试没写完, 需求又改了.
james2013
2022-10-12 11:08:07 +08:00
不写
写单元测试是额外的时间,需要加班
而且需求改了后,是不是又要重新写?
GeorgeGalway
2022-10-12 11:09:48 +08:00
国内的单元测试会加速内卷
hsuyeung
2022-10-12 11:15:09 +08:00
以前不写,在学习如何写。

借楼问下,我有一个方法,根据传入参数会有多种不同的错误信息。我应该是为每一种情况编写一个测试方法还是在一个测试方法里把所有情况都写一遍?
coldmonkeybit
2022-10-12 11:19:36 +08:00
@tikazyq 十分感谢,很有帮助
rekulas
2022-10-12 11:24:53 +08:00
基本不写 个别项目偶尔会写-时间很充裕的情况下
写测试比开发还费时间,更大的问题实际测试异常复杂 单测压根覆盖不了多少情况,性价比极低
rekulas
2022-10-12 11:30:35 +08:00
我们都是开发完了把所有开发完了人工测试一遍所有可能相关的流程,虽然麻烦但是稳

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/886162

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX