作者GALINE (天真可爱CQD)
看板Soft_Job
标题Re: [讨论] Unit test 的撰写请益
时间Wed Nov 9 14:19:33 2022
※ 引述《shane87123 (阳光大肥宅)》之铭言:
先说在前面
虽然听起来很干话,但很多东西没有标准答案
有时是合适度的问题,也可能是喜好(品味?)的问题
同一个题目,实际的 code 长得不一样,可能也会用不同的方法处理
另外,除了资源丰富到人力充沛到不行的专案,以及几乎没有时程压力
的专案(很多开源专案属於後者),少有专案能把测试能做到真正完整
很多时候是取舍,花时间写多少测试,能 cover 到最大的范围
剩下的部分靠整合测试(包含自动与手动)来抓
经验能让人能更快做出效益更好的取舍
: 先说我对 Unit test 的看法:测试单元(可能是 function)的逻辑是否正确
: 常常会有一份 code 内其实呼叫了很多别份 code 的 function,
: 举例来说
: A() {
: B();
: C();
: if (check)
: D();
: }
在「unit test」的前提之下,A() 这个「单元」要怎麽被定义?
- B() C() D() 的集合体?
- 负责分派逻辑前往 B() C() D() 的 router?
- A() 本身就做了一大堆事情,BCD 只是辅助?
- 其他?
在不同的状况下,该测的单元功能会完全不一样
适合的可能做法也完全不同
例如说对於状况1
- 也许该把那个 if 检查丢进 D(),让 A() 就只是依序呼叫三个其他人的传声筒
接着不测 A() 但认真测 B() C() D()
- 没有副作用可以,有副作用的话怎麽验证副作用?
例如说对於状况2
- 是不是该把 B / C / D 弄成变数传进 A?
- 没在写 C 不知道 C 能怎麽做,function pointer?
- 或是有某种类似 router 定义的东西,然後测 router 功能?
例如说对於状况3
- 全部 fake 是不是比较快?
- 是不是该把这个 function 拆掉?
- 诶,看到七层的 if else,真的觉得拆的掉吗?
- 诶,看到七层的 if else,真的觉得要伴他一生一世吗?
其实「重构」是个很常该被考虑的选项。
但当然,重构有时是个繁重的工作,也不见得是最常被选择的选项
这也是 TDD 曾经风行一时的一部分原因,因为脑袋正常的工程师走 TDD
会避免自己写出「啊,这要能测会把测试写的有够屎」的 code
但走 TDD 也可能写出「看得懂想测什麽,但逻辑怎麽会这样切」的东西
另外自己经验是通常测试难写是跟资料有关
「某些时候」如果非常辛苦的把资料 IO 全部 mock 一层,後面会好做一点
例如之前看过 api 专案平常线上是戳 MySQL 拿资料
在跑测试的时候直接开一个 in memory 的 sqlite 来当後端
测试逻辑会先把资料塞好好再来跑测试
於是就可以测「拿文章的时候会把内文特定 tag 换成其他 table 的资料」
之类资料连结度高的东西
走这条路的话不 fake 直接把逻辑跑完也是个好选项了
或者不用全部 fake,可以只 fake 几个
这大概不算是「单元」测试吧
但该测的有测到,而且在艰苦的工程之後可以轻松往上叠一堆其他测试
(但..如果没有那麽多东西要测,这会不会太厚工?)
另外不同程式语言(或不同辅助函式库?)的状况会天差地北
例如上面的 A(),如果是 python 的话可能可以不改 code
直接用 patch() 把 B() C() D() 变成 mocker,会回传需要的值
测试就直接检查 B/C 是不是每次都被呼叫到
D() 是不是条件对的时候有呼叫到
因为 mock 容易写,全部 fake 掉会变成更有吸引力的选项
所以回到原本的题目:
全部 fake 跟全部不要 fake,选哪边?
我的回答是:
这两个都是选项,但不是只有这两个选项。
例如重构,例如在其他地方准备抽象资料层,也都是选择。
甚至手上的专案也可能变出不同的把戏。
这些都是能打的牌,要看场上环境怎样,再来取舍该打哪几张。
--
莉~娜~在~我~们~之~间~有~名~吗~?
打倒了魔王大人,被那位大人附体之後平安无事地打倒了冥王大人
击退了霸王大人,然後又打倒了魔王大人。
这种家伙还不有名?魔族有那麽粗神经吗?有那麽没危机意识吗?
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 218.166.60.66 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Soft_Job/M.1667974776.A.0BC.html
1F:→ hackfox: 靠金燕,a.k.a姊姊 11/09 14:50
2F:推 FatFatPig: 推推 11/09 16:49
3F:推 t64141: 推,满全面的分析 11/09 16:56
4F:推 Burwei: 推 11/09 19:41
5F:推 k7ji91ab5m: 推 说得很好 11/09 19:58
6F:推 markbex: 推 敝单位也是视情况测"服务"或是测"单一元件" 11/09 21:21
7F:推 viper9709: 推这篇 11/09 23:56
8F:推 sssyoyo: 推 11/10 08:48
9F:推 devilkool: 推这篇 11/10 09:18
※ 编辑: GALINE (218.166.49.121 台湾), 11/10/2022 11:02:45
10F:推 strlen: 我一直认为当初业界一堆在洗风向要写测试的主因之一 就是 11/10 14:14
11F:→ strlen: 要利用测试来强迫大家做好封装与架构分离 11/10 14:15
12F:→ GALINE: 也许喔,但 TDD 最大问题是写测试的人通常不控制 spec... 11/10 14:31
13F:推 NDark: 就跟 product owner 其实不是真正能决定事情的人一样 11/10 17:23
14F:推 scottxxx666: 推 11/10 21:55
15F:→ akitoex: 推 11/10 22:58
16F:推 claymath: 推一下 11/11 00:20
17F:推 nec1002: 找本专业书籍k一下 11/15 15:12