单元测试有必要吗?

2021-12-12 09:51:22 +08:00
 RuLaiFo

单元测试有必要吗?

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

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

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

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

13210 次点击
所在节点    程序员
101 条回复
smilingsun
2021-12-12 16:59:09 +08:00
不知道有没有这样的感受,修 bug 的时候是最需要想想是否要补一下 UT
wu67
2021-12-12 17:11:33 +08:00
别的不知道. 我是个前端打字员, 我只知道除了核心逻辑和几乎永远不会变的模块封装逻辑, 其他的业务代码写测试真是扯淡.... 且不说改动频繁与否, 但是在规定排期完成就够你喝一壶了
iyaozhen
2021-12-12 17:14:19 +08:00
个人觉得 tdd 实现需求会花更多的时间 可以肯定的说,是的

这个就看现在产品质量在什么阶段。比如一开始做一下接口测试,基本上能够 70 分了,再加上业务端的功能测试做到 80 分也很容易。但项目要想继续往下发展,质量要求更高的话,就需要整体来看了,比如需求流程、上线流程,还有就是代码阶段 CR 、UT 。这些都是需要投入之前几倍的精力只是为了做到 90 分以上。

就和高考一样吧,你要考 985 ,比本科就是要付出更多
akira
2021-12-12 17:20:31 +08:00
很有必要
2i2Re2PLMaDnghL
2021-12-12 17:25:20 +08:00
Write Everything Twice
重构的时候,因为你只改动一边,可以通过另一边进行确认改动是否正确
举个不是严格对照的例子,地球上稍复杂的物种的遗传信息都是 DNA 了(
2i2Re2PLMaDnghL
2021-12-12 17:28:50 +08:00
不过我觉得既然都这么推 TDD ,又吹 Copilot
感觉就应该把测试写好,实际代码就 Copilot 生成(
zhanlanhuizhang
2021-12-12 17:33:26 +08:00
我是非常想写,但是公司不给时间。
palemoky
2021-12-12 17:41:15 +08:00
我觉得很有必要。之前维护过某个大家日常几乎都在用的产品代码,各个业务线代码都是通过 if else 判断,一个方法能有一千多行,公司的业务快速发展导致代码迭代快,人员流动强,现在很多方法堆积在一起根本不敢随便动,大家改逻辑也是尽量加新的 if ,因为没有单元测试,你无法保证影响面可控,尤其是公司还是微服务架构,这种复杂度就更大了。

虽然上线前会有 QA 测试,但 QA 也只能测到他了解的范围,而无法测到他不知道的,这可能直接导致重大事故,而且随着公司的微服务化,人员间的沟通成本极大。有些 QA 不太懂开发,反馈问题只会说表现不符合预期,自己需要停下手里的活,打断思路去排查故障,可能查了几个小时候发现是一个很简单的问题,然后 QA 再去验证,QA 一般工作量也是很满,所以要等他有时间测试后再反馈结果,这样导致简单的问题一来一回浪费了不少的时间。

我去过两家大点的公司,我做的项目是都没有单元测试的,领导都是先上线、再优化,大家都是加班写 bug ,再加班改 bug 。因为公司 KPI 的原因,不少领导更乐于快速推进项目,而项目只要能跑就行,这样才更能让领导在述职有的讲,这种压力不断向下传达,最后到一线开发这里,原本两周的项目,就开始倒排一周加班搞定了。
opengps
2021-12-12 17:57:01 +08:00
如果你的程序每次修改不用保证其他地方不影响,那么可能用处不大,单元测试我的用法是,整体发布前的整体验证
palemoky
2021-12-12 18:01:34 +08:00
@palemoky 有了单元测试,不一定能解决上述的所有问题,但能带来很多非常多的收益:

1. 根据《代码大全》,越晚发现 bug ,纠正 bug 所付出的成本也就越高,而单测能够让开发者在开发阶段就及早发现一些 bug ,避免将 bug 带入联调或 QA 环节。尤其在微服务架构下,这种收益会更加的明显,尽可能减少高薪工程师的低效沟通,让他们更有时间去创造更多的价值。

2. 团队成员的开发水平一定是良莠不齐的,即便在上线前有 Code Review ,但这个阶段太晚了,除非代码有重大问题,一般都不会打回去,毕竟马上要上线了,一个开发写了一个 500+ 行的方法,重新修改意味着 QA 这部分的工作都白做了,极大影响上线时间,一般大家都不愿意背上上线卡自己这了。通过单元测试,能让开发者及早发现自己除了实现业务外,代码是否设计合理,及早纠正这个问题,从而提升团队的编码水平。

3. 单元测试能保证代码的健壮性,而不只是能跑就行。有些不重要的功能随着人员的流动,交接着交接着就没人知道这是啥了,但突然某天这个功能出了线上 bug 或者需要项目重构,根据之前的单元测试,让新手也能了解影响范围,保障项目质量。
janxin
2021-12-12 18:52:37 +08:00
@2i2Re2PLMaDnghL Copilot 重要的是写好评论
satoru
2021-12-12 19:56:44 +08:00
这里有几个概念,分开来可能比较好讨论:单元测试、测试覆盖率、TDD 。

分享一下我自己写测试的经验:
我一般是把单元测试当成一个效率工具,我会遵守“单元测试不能连接网络、不能连数据库”这样的规则,来确保我在开发时可以快速频繁执行单元测试,尽早发现错误。
但是测试覆盖率我一般不会刻意追求,特别是一些测试不好写的编程语言(例如 Go 的测试一般没有 Python 的好写),为了去覆盖某些分支可能要投入很多额外时间,这样就与我把单元测试作为效率工具的初衷就冲突了。不过这点很无奈,有些高管就喜欢去量化一些不好量化的东西,而不幸的是,测试覆盖率一般是他们拍脑袋容易想到的一项指标。
TDD 我很少实践,虽然偶尔刚创建新项目时会有热情去尝试,但是时间长了又回到原来先写实现再管测试的模式,后面慢慢就顺其自然了 ……
tyrantZhao
2021-12-12 20:01:52 +08:00
需求变化大,排期紧张,就没有必要
wyx119911
2021-12-12 20:03:49 +08:00
我觉得比较合理的是,基础组件开发写单测,关键业务由质量管控团队(一般是测开)写接口拨测。
picone
2021-12-12 21:36:08 +08:00
单元测试我觉得是可以针对不同的情况进行测试。
比如我写一个接口,我要找到走到某个逻辑的 case 很难,但是我通过单测 mock 数据能很轻易走到哪个逻辑,那我开发的时候就能很好调试了。
如果你养成习惯使用单测来调试开发的代码,你就不觉得单测是累赘。
l00t
2021-12-12 23:39:18 +08:00
单元测试没必要,不写。有功能测试就行了。
功能测试相对来说输入输出更稳定,测试用例的选择和对输出的预期都从业务而来,业务不变用例就可以不变。而单元测试是白盒测试,要追求覆盖率的话,代码怎么写你就得怎么测,改一次代码没准还得给改一次测试,改了之后测试程序自己没准还引入了新 bug ,没完没了。
并且,程序出 bug 大多数时候是没想到,而不是笔误写错。功能测试一般都是黑盒,无所谓你程序怎么写,输入输出只考虑业务需求,相比单元测试更有意义也更容易覆盖没想到的意外情况。功能的概念还大点,可能由多个单元组成,在一些校验方面也更容易做责任划分。
curoky
2021-12-12 23:44:09 +08:00
基础库一定要写的,可不是开玩笑的;业务就没必要了吧,不是专门招了 QA 干这活吗?
elfsundae
2021-12-13 00:00:32 +08:00
太有必要了,尤其是公共库、基础组件等,这是应用稳定的最基础。
当然,如果老板只关心需求啥时能搞完,那就别写了。KPI 优先级大于一切。
nine
2021-12-13 00:20:59 +08:00
高质量的软件,必须要有单元测试。

没改过线上运行中的复杂的项目,一定不知道单元测试的意义。
改过线上运行中的复杂的项目,也未必知道单元测试的意义。

如果一个项目很复杂,那么在修改局部的时候,很有可能牵一发而垮全身。你不会知道项目里有多少代码调用你,或是继承你。

如果改的是别人的代码,没有单元测试,改完直接上线,后果不堪设想。如果恰巧是个金融项目,分分钟能让你公司破产。

当然,你的需求方可能并不要求你的代码质量。

而单元测试不等于 TDD ,事实上能真正合格的实施 TDD 的项目可能也就是 1%。
l00t
2021-12-13 00:51:40 +08:00
@nine 这我就要杠一下了。多少代码依赖你继承你调用你,这你做了单元测试也不知道啊。你修改局部,然后通过了这个局部的单元测试,爽了对吧,然后别的地方崩掉了。这种场景你需要的是系统回归测试而不是单元测试。

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

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

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

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

© 2021 V2EX