作者TonyQ (得理饶人)
看板Soft_Job
标题Re: [讨论] 工作上写单元测试的比例
时间Thu May 2 13:33:20 2024
先说我不是故意要回两篇,
但刚看到 landlord (就 joey chen, 江湖名 91) 在 FB 的回应,我觉得也蛮好的,
他说他最近在忙没空过来,我问过他之後帮他转过来。
以下基本上逐字照转
(source from
https://tinyurl.com/rxyerfyw )
其实讲到底根本原因反而是跟产品程式码的设计能力有关,
产品程式设计得越好,测试程式越容易写,越好测。
真正需要在测试中做假模拟(隔离)的部分,
属於外部(拥有权不在我们手上的部分),
例如外部系统的服务(走通讯协定出去,且不属於我们可以维护跟上版的服务)、
三方(package/SDK)。而 DB, redis之类的 cache 甚至是不需要特别被隔离开的。
这是由於现代科技的便利,让我们有机会把越来越接近端到端测试的一类,
比例逐步拉高的可行性比过去容易得多。
另一个重点则是当设计越来越偏向高内聚,simple design,
把 code smell 消除到最後回很自然地提炼出 domain model,
有了 domain model,
最复杂的 domain logic 处理一堆散落资料的逻辑都被内聚到model里面,
没有 application 层的依赖,model 的单元测试也很好写。
结论:
1. 要有能力在 legacy 上重构出可测试性
2. 要有能力做出稳定的端到端测试
3. 要能精炼设计,将散落的资料内聚在一起
来代表 domain 的概念提供 domain 的行为,
因为设计上本来就没有外层的依赖,model的方法也都精简短小,甚至鲜少回传值,
自然 API 易用性跟测试都可以比过去万恶的三层式架构+内嵌无限层依赖注入
的手风琴架构来得简单跟好测许多。
现在大部分的依赖(注入)都不是本质上需要的,而是被开发人员硬生生切得支离破碎的。
补充一下 TonyQ 内文最後一点:
「如果都没被报 bug,你也没有修改它的需要时,帮它加测试干嘛?」
这超级重要的,这种情况下加测试往往适得其反,
只会建立伪阳性/阴性的测试结果,劳民伤财还造成干扰。
※ 引述《TonyQ (得理饶人)》之铭言:
: 底下这是比较「野性」」的作法,算是实务专案的经验:
: 其实我觉得你到一个完全没有测试的专案,要分两个策略:
: 1. 补重要主线的 integration test 反正哪边常被报修就补哪边。
: 如果一开始补不上去就先做下一点,理论上常被报修的地方会一直出现在下一点,
: 累积多了就可以变成1了。
: 2. 假设自己是维护历史功能,提昇自己维护部分的可测试性。
: 举实际案例好了,假设我今天再做一个算金流手续费的专案,
: 发现过去算手续费假设有11个地方写了11次好了,所谓的高耦合不外乎如此。
: 我会先写个 util 把输入跟输出「去状态化」,然後针对这个 util 写,
: 然後这个 util 的单位以「去状态化」成本可控,可在手边开发时间允许的范围进行。
: 白话文:我横竖都得手动测试,那就把手动测试的部分,
: 尽可能的透过 test code 来进行。
: 如果不想接着维护的话也很单纯,任务结束後把 test code comment 掉或移除就行。
: 题外话,11个地方,我会选择先取代一个地方,
: 然後等其他10个地方有需求变更时,一个个整并,补强测试条件。
: 很多人会说,那为什麽不一次改11个,理由是你的开发时间跟成本允不允许。
: 更重要的是你的QA资源够不够,因为写正常的Test最累的是准备测试情境,
: 这真的是会花掉比写test更多的时间。
: 如果列不出完整场景,贸然修改既有的code只是在裸奔。
: 有需求的部分是被迫裸奔,但没需求的部分不用主动当暴露狂,
: 等待验证过再慢慢统一。
: 大原则就是:你横竖都是要测试的,只是手测还是写程式测,除了跟 gui 有关的东西,
: 多数的情况下写程式测试都还是比较省时间的。
: 更棒的地方是,在这种策略下,你往往可以用比同事少30% 的时间完成任务,
: 而且因为你的测试成本比较低,所以品质也会比较好,出问题的时候也更容易对焦。
: 然後我通常是会跟同事说我写了几个 test case,
: 他们愿意看就看,不愿意看我就放着。不会勉强他们加入。
: 如果你做不到可以用比不写测试更短的时间来完成任务,
: 那你学的测试根本性的就有问题,不写也罢。XD
: 3. 极端情况: 如果都没被报bug,需求也都很小?
: 那你操心他干嘛 XD
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 1.163.94.23 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Soft_Job/M.1714628003.A.C91.html
1F:→ s310143: 当runtime 遇到eos 或是os因资安规范须要升版 05/02 13:46
2F:→ s310143: 你没写测试 会很惨无从下手 尤其你的规模越大 服务越重要 05/02 13:47
3F:→ s310143: 是不允许 在正式环境 挂掉的.. 05/02 13:49
4F:→ chchang0820: 我菜鸡,觉得好多用词,有白话文版本吗? 05/02 13:49
5F:→ TonyQ: 直接问哪些词看不懂 比较快 XD 05/02 13:49
6F:推 Litfal: 但虫子就是会生在脏的地方,尤其是那一盘盘的陈年义大利 05/02 15:54
7F:→ Litfal: 面里面,被抓去救火就得在时间内细细品嚐 05/02 15:54
8F:→ superpandal: 依赖注入都不是致命的 致命的是隐藏实作细节 如果是 05/03 01:48
9F:→ superpandal: 普通使用者当然不用隐藏就很好的屏蔽了 但框架的使用 05/03 01:49
10F:→ superpandal: 者也是开发者 这时候隐藏实作细节绝对带来的麻烦很大 05/03 01:50
11F:→ superpandal: 封装是一定要封装的 但搞到无法无脑除错本身就不是很 05/03 01:52
12F:→ superpandal: 值得一而再再而三提出的优点 花费过多时间在关注无用 05/03 01:53
13F:→ superpandal: 的小细节也压根不会学到什麽东西 很多框架都是这样 05/03 01:55
14F:→ superpandal: 倒是容易被拿来搞人 我是不知道那些人职涯里心里阴影 05/03 01:57
15F:→ superpandal: 有多大 但这样搞何尝不是内卷 05/03 01:58
16F:→ banana13: 超烦的 一堆coverage要冲...升级个idk降到不行重写头好 05/03 13:12
17F:→ banana13: 爆掉出个logger不行吗 05/03 13:13
18F:→ banana13: 升级冲majito 套件重写也没有比较好QQ 05/03 13:13
19F:→ banana13: 我觉得可以增加常见utils 做基础条件测试,当整个程式专 05/03 13:16
20F:→ banana13: 案被要求覆盖率 05/03 13:16
21F:→ banana13: 真的是做给老板看的了xD” 写到吐 05/03 13:16