ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

工作5年,我还在坚持写单元测试的3个理由

工作5年,我还在坚持写单元测试的3个理由 五年前我刚入行带我的师傅老陈是个沉默寡言的中年人。他唯一让我印象深刻的是每次提交代码前都会对着终端敲下那行命令npm run test:unit。屏幕上滚动着绿色的“PASS”他才点下合并按钮。那时我觉得这动作像某种仪式甚至有点形式主义——功能都跑通了页面也点过了为什么还要花半小时去写那些“给机器看的注释”直到去年我接手了一个三年没有单元测试的遗留系统。改一个订单金额的bug上线后崩了三个隐蔽的边界场景全组人凌晨两点回滚版本。那一夜我第一次真心想如果当初有人替这些逻辑写下几行测试该多好。五年过去我依然在写单元测试。不是因为我有多自律而是因为三个越来越清晰的理由。第一个理由它是我和代码之间的一层“安全气囊”有人把单元测试比作代码的“安全带”我倒觉得更像“安全气囊”——平时完全感觉不到它的存在但碰撞发生时它真的能救命。上个月我重构一个支付路由模块。那是个两百多行的函数嵌套着七八层条件判断谁都不敢动。我花了一个下午先给每个分支补上测试用例正常路径、金额为0、货币类型不匹配、超时重试、降级通道……写完之后我用了四十分钟完成重构把函数拆成了四个小函数。跑一遍测试全绿。那一刻我才敢长舒一口气把代码推上去。没有测试的重构叫“赌博”有测试的重构才叫“工程”。单元测试不会让你写出更多代码但会让你有底气删掉代码、改掉结构、调整逻辑而不必害怕某次小小的改动会在深夜引发一场P0故障。第二个理由它强迫我在写代码之前先想清楚很多人以为写测试是“写完之后”的事但我逐渐发现最好时机是“写之前”。当你为一个函数准备测试用例时你必须回答几个问题它的输入是什么输出应该长什么样边界在哪里异常情况怎么处理这些问题在写生产代码时往往会被忽略因为人脑天然喜欢走“正常路径”而测试用例逼着你把那些“异常路径”提前摊在桌面上。我印象很深的一次是我准备给一个“计算折扣价”的函数写测试。写到第三个用例时我突然卡住了如果商品已经参加了满减活动还能叠加折扣券吗业务规则里其实没写。于是我去找产品确认才发现这是个隐藏的逻辑漏洞。如果等代码写完、上线跑一段时间才发现可能就是一次资损事故。单元测试像一面镜子照出的是你设计里的模糊地带。第三个理由它是写给未来自己的“情书”这个比喻听起来有点肉麻但我真心这么觉得。你有没有过这样的经历凌晨三点排查一个老模块的bug翻来覆去读那段逻辑越读越不确定它本来想干什么这时候如果你看到一段标注着“当用户等级为VIP且订单金额大于100时运费减免”的测试用例你会瞬间明白这段代码的意图——它不仅是测试更是一份可执行的文档。这份文档永远和代码同步不会过期不会像注释那样被遗忘在角落里。五年里我换过三家公司写过Java、Go、TypeScript但无论技术栈怎么变我依然会给核心逻辑留下一组单元测试。因为我知道六个月后的那个“我”可能已经忘了今天为什么要把某个条件写成而不是。而那个“我”会感谢现在的我多花了二十分钟给他留了一盏灯。如今老陈已经转行去了传统行业。偶尔聊天他说他现在写脚本还是会随手加几个assert。我笑了因为我也一样。单元测试不会让你成为技术大牛它不会优化性能不会解决架构问题更不会让你升职加薪。但它会在无数个深夜当你要修改一段陌生代码的时候轻轻说一句“别怕我帮你看着。”这大概就是五年过去我还在坚持写单元测试的全部理由。
返回列表