单元测试有必要吗?

2021 年 12 月 12 日
 RuLaiFo

单元测试有必要吗?

我在现在的公司工作近半年了,公司的项目都需要写单元测试。但是写了这么久,感觉写单元测试费力不讨好,有时候写单元测试的时间大于写业务逻辑的时间,需要 mock 一大堆数据。要保证各种覆盖率,特别是分支覆盖率,需要覆盖到所写的每一个分支。

另外,大家写的单元测试质量参差不齐,因为感觉大家都是为了写测试而写测试,而不是真正的 tdd 。然而在迭代频繁,节奏紧凑的环境下,想要做到真正的 tdd ,还是有很大的难度的(个人觉得 tdd 实现需求会花更多的时间,可能是自己没正确认识和掌握 tdd?)。所以这就导致大家往往先去实现逻辑,再去写测试。

简而言之就是认为单元测试费时费力,又没有明显的收益,想请教一下大家怎么看待单元测试。

初次提问,如有不恰当的地方,请大家指出。

16948 次点击
所在节点    程序员
101 条回复
kaedea
2021 年 12 月 13 日
单元测试是快速调试代码的最好切面。
msg7086
2021 年 12 月 13 日
独立的功能代码做单元测试,其他地方用功能(集成)测试覆盖就行了。关键在于自动化测试覆盖绝大多数代码,而不是纠结这个测试是不是单元测试。
damai0419
2021 年 12 月 13 日
有必要... 没时间...
powerman
2021 年 12 月 13 日
@l00t 单元测试就是测试单元,集成出了问题,那不是单元的锅
abcbuzhiming
2021 年 12 月 13 日
@vishun 实践表明单元测试并不能保证检测出你所说的“基本的错误”,因为单元测试的执行过程本身也是业务逻辑的一部分。不要过于抬高单元测试,测试是必要的,但是单元测试也只是测试的一种手段而已,它能测试出来的东西用别的测试方法照样可以,同样的,有些很难弄出来的隐藏的问题,单元测试照样测不出来。这东西不是银弹,不要觉得这东西存在就能解决一切问题。

就目前来讲,单元测试这东西在规模不大的公司里演变成了老板不搞测试降低成本,变相给程序员加单位时间工作量的工具(要求写单元测试,却不允许延长项目时间)了。所以我个人建议是,如果你待的公司很正规,那你就按要求写单元测试,如果你待的公司不那么正规,老板是拿单元测试来压榨你们,那就想尽一切办法别写单元测试
powerman
2021 年 12 月 13 日
没有必要,单元测试只是一个仁者见仁,智者见智的事情,要根据项目实际情况以及开发人员的能力来做,首先要做的就是分层设计,哪些是业务逻辑,哪些是技术上的东西,耦合在一起是最难测试的,然后技术上的很多代码是没必要测试,因为很多不复杂,也没必要去做。

另外单元测试是要有懂技术的 leader 才有意义,像我在携程这个破公司,上头 leader 就 SB 地要求分支覆盖率跟行数覆盖率,然后我们没有用 JSR303 注解参数校验,一大堆的 if-else 判断参数是否为空,结果你发现单元测试编写的时间,全耗费在简单的参数校验逻辑 case 上了,真正重要业务逻辑的 case 校验反倒没人写,反正我现在写了个脚本,自动生成这些参数校验的单元测试让覆盖率上去,自己懒得动手测了
pkoukk
2021 年 12 月 13 日
经历过太多的项目了,如果不写 ut ,一个较大项目的可维护寿命一般就两年,两年之后就成一坨腐肉,没人愿意动了。
因为你无法判断你这一次的修改变更是否影响到了其他模块,而且两年的时间项目的初始成员应该也所剩不多了,那些没有测试覆盖的地方只能靠读代码去理解
而不写 ut 的代码一般都很烂,因为为了写 ut 必然要进行模块间的抽象,不然没办法 mock ,而没有 ut 的项目很多都放飞自我,能明显看出不同贡献者直接显著矛盾的设计逻辑
wuqiangroy
2021 年 12 月 13 日
你在写 unit test 的时候有没有发现代码 bug 呢?
这就是写 unit test 的价值所在。
nameyukan
2021 年 12 月 13 日
如果你的工程构建一次需要半个小时,那么你是否会有这么个小冲动,这段代码老子可以写单测的话,是不是就不用在写逻辑的时候要构建一遍才能验证了?
不能写单测的代码不一定烂,不能写单测的工程架构基本上过一段时间就烂。
把单测当成一种开发手段,也许能好受很多。
leeg810312
2021 年 12 月 13 日
单元测试一定要做,现在正在参与一个产品,1 年多了,至少有 50%以上的代码是我写的,而且经常会因为特性变更而重构部分核心代码,虽然商务方面压力大,开发计划很少有留给写单元测试的时间,但至少在核心模块都抽时间写单元测试,保证关键功能 bug 少,可以减少集成测试出 bug 的概率
yule111222
2021 年 12 月 13 日
建议试试 ATDD (验收测试驱动开发)
纯粹的单测颗粒度太小,适合对一些核心的类来做,比如 DDD 架构里面的领域对象,或者一些工具类
chunquchunyoulai
2021 年 12 月 13 日
TDD 是
1. 先写一个失败的测试
2. 写只让失败的测试通过的代码逻辑
3. 重构

----

而这 3 个点会对应以下几个点,并且会让你的关注点分离(一次只关心一件事)
1. 写测试 是为了只关注功能需求
2. 只关注让功能需求实现
3. 重构是关注代码设计
Raos
2021 年 12 月 13 日
有必要,不必须
sulfoh6
2021 年 12 月 13 日
单元测试和代码质量没有必然联系。首先用例都是在白盒的前提下设计,为了刷覆盖率,有很多种办法可以很鸡贼地避开边界,流水账一样走一遍过场,把字面的覆盖率做得足够漂亮。一个团队里你不能保证每个人都会在写用例时尽心去考虑边界,总有人能糊弄出覆盖率达标的稀烂代码。但如此花费极大的时间代价去凑覆盖率,还有意义吗?

我呆过的一个 MNC 公司里很多印度团队,他们搞 pipeline 的漂亮花哨程度可以把上层哄得不要不要的,单元测试覆盖自然是完美级别的,还有各种自动集成测试。然而,服务上线以后会花样扑街,出错错到匪夷所思。经常在救火,但往往一波未平一波又起。到底是哪个环节出篓子了呢?单元测试 90%以上的代码仍然是把用户、内部用户当小白鼠,藏满各种地雷。

也许你有过体会,写单元测试过程中可以顺手解决掉几个低级错误。但基本上就到此为止了。很多设计上的问题、接口的问题、性能问题、安全问题、并发问题...,单元测试都无能为力,必须得靠人工的系统测试来暴露。所以,我们为什么又得花这么大的工作量去刷覆盖率呢?单元测试的另一个副作用是巩固强化了旧有的设计与实现,让决策人在决定是否重构时畏首畏尾,也让每一次的代码更改变得无比磨叽,强制加到构建过程里也会浪费更多的时间。

从个人经历来看,虽然只是有限的视角,但已经很明显的看到讽刺性的一幕:零单元测试的商业产品,稳定地运行在客户的环境里,缺陷率在可预期范围里。这里还包括电信级的设备。另一面是追求覆盖率的产品,都还没到客户手里,内部已经炸开花了,坑了内部合作的团队。因为伴随着单元测试的还有敏捷开发的其它要素,势必让依赖内部基础库的其它产品团队充当小白鼠。当然这并不是单元测试本身的锅,问题还是出在人身上。但单元测试充当了很鸡肋的角色。也许在某些关键的算法上,适合用单元测试去查瑕疵;而对于 CRUD 或者接口层面的代码,写单元测试纯粹是走形式。为什么要欺骗自己呢?
GiantHard
2021 年 12 月 13 日
如果只是 crud ,那么写单元测试收益不大。
如果你的 crud 开始包含业务逻辑,那么你需要考虑怎么把业务逻辑跟 crud (也就是读写数据库或第三方 API )隔离开,这时单元测试的收益就比较明显了。
xylophone21
2021 年 12 月 13 日
说重构的,问一下你们重构的时候,只重构单个函数吗?否则如果函数改了,单测不一样要跟着改?除非是核心模块,保持一定的稳定性,但一个项目中,能有多少是核心代码呢?甚至有没有核心代码呢?

最近在看 Apple 、Google 开发的 Matter (一个物联网协议)的代码,CI 里确实配置了一大堆 test ,但基本上也是集成测试为主,客户端给服务端发一个什么包,期待收到一个什么回复之类的。mock 了做单测的,几乎没有。虽然在代码走读的过程中,他们会非常重视这个代码可否做单测。
matrix1010
2021 年 12 月 13 日
@sulfoh6 "写单元测试过程中可以顺手解决掉几个低级错误。但基本上就到此为止了" 首先,程序员是很容易犯低级错误的,就算是老司机也经常因为低级错误翻车。如果你的低级错误直到 QA 阶段才被发现是很严重的内耗,也会降低团队间的互相信任。
"很多设计上的问题、接口的问题、性能问题、安全问题、并发问题...,单元测试都无能为力" 真的无能为力吗, 还是只是你们团队的技术水平不太够,或是你只是为了糊弄一下随便写个测试?
"因为伴随着单元测试的还有敏捷开发的其它要素,势必让依赖内部基础库的其它产品团队充当小白鼠" 敏捷开发配合自动化测试配合严格的 Code Review ,再加上技术实力靠谱的团队,这样才能实现真正的高质量快速迭代,你可以专注于迭代新功能,而不是担心别人加了个功能 /改个功能把你原来能用的东西改坏了。当然,有测试的话甩锅也比较方便。
"我呆过的一个 MNC 公司里很多印度团队,他们搞 pipeline 的漂亮花哨程度可以把上层哄得不要不要的" 也别总是黑印度工程师,国内很多工程师可能并不如印度工程师。另外国内大厂很多是依靠很大的 QA 团队进行人肉测试,才确保了你用到的东西没问题。
sockpuppet9527
2021 年 12 月 13 日
https://v2ex.ih06.com/t/749125

老板不关心你的测试到底写成啥样,他 /她 只在乎 coverage 。有些时候,公司团队,人都是这样的,拿钱办事。
ah64zzpk
2021 年 12 月 13 日
作为一个曾经的软件测试,这个帖子看了让我感觉很欣慰啊,还是有很多开发人员重视代码质量和单元测试的啊
libook
2021 年 12 月 13 日
一方面单元测试只是一种手段,有没有必要还是得看你们工作痛点是什么;
另一方面任何方法想要发挥最大效用就得按照核心思想来做,应付的话相当于没用。

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

https://v2ex.ih06.com/t/821608

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

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

© 2021 V2EX