写点什么

我讨厌单元测试:滕振宇谈如何进行单元测试

  • 2012-02-26
  • 本文字数:1402 字

    阅读完需:约 5 分钟

说起单元测试的好处相信大家都能列举出不少,可是很多时候,开发人员面对自己产品的代码,想写单元测试却无从下手,久而久之,便会有人大喊:“我讨厌单元测试。”资深敏捷咨询师腾振宇(Daniel Teng)在 GTUG-TopGeek 开发工程管理沙龙就以此为题,结合最近的一个项目,和大家分享了他对单元测试的一些看法。

Daniel 先介绍了下最近的一个项目,虽然不是遗留系统,但代码已经惨不忍睹,而且缺乏必要的测试保障,要修改代码可谓举步维艰。例如,一段代码和结对伙伴读了半小时没读懂,找来原作者看着注释又想了 10 分钟,终于才搞明白这段代码是做什么的。根据二八原则,先找到那 20% 的点,修改它带来 80% 的价值。最直接的做法就是寻找代码库里最常被修改的文件,一般的文件只有几次修改,有的文件则被修改了几十次,每个人都在往复杂的代码里加入新的东西,但没有人往里面加测试,于是第一步就是为它增加测试。

很多开发者会说老项目就算了,如果新启动一个项目,我就会写单元测试了,Daniel 认为这是一个“美好的梦想”,很多原因会打破它:

  • 代码已经很烂了,又没办法下手了
  • UI 不好测
  • 认为这是 QA 的工作
  • 写的单元测试找不到 Bug
  • 代码的外部依赖太多
  • 代码稍作修改,测试也要一并修改,太麻烦了

究其根本原因,是开发者根本不会写单元测试!满足什么标准的测试才是单元测试呢?根据《修改代码的艺术》,需要访问数据库的测试不是单元测试,需要访问网络的测试不是单元测试,需要访问文件系统的测试不是单元测试……

为了更方便地进行单元测试,业务代码应避免以下情况:

  • 存在太多条件逻辑
  • 构造函数中做的事情太多
  • 存在太多全局状态
  • 混杂了太多无关的逻辑
  • 存在太多静态方法
  • 存在过多外部依赖

例如,在代码中存在硬编码,或者是直接创建了一个数据库连接,这种做法都是比较危险的,因为在测试时没有办法“偷梁换柱”。

想要写好单元测试,学会重构是很重要的,重构的过程类似于清理厨房,虽然和做饭没太大关系,但可以让您下次做饭更方便,心情更好。可以重构的地方包括,在待测试类与其依赖之间增加一层 Test Fixture;将创建逻辑与业务逻辑分开等等。重构可以采取以下策略:

  • 编写测试代码建立基本的防护网。在单元测试和功能测试之间要有取舍,如果单元测试实施成本很高,可以先加功能测试。
  • 通过增加中间层来打破依赖,不是为了去掉依赖,而是为了后续的修改以及测试的便利。
  • 将第一步中编写的功能测试换成单元测试。

最后,Daniel 还为大家提了一些建议:

  • 项目里的破窗要修好,别容忍别人加新的破窗,用测试将破窗保护起来。
  • 当你离开一个地方的时候,要让它比你来的时候更整洁干净。(童子军军规)
  • 不停地重构你的代码,每次走一小步。

随后有人提问,如何评估一个单元测试的质量,用代码行覆盖率是否可行。Daniel 认为没必要去追求代码行覆盖率,真正要覆盖的是逻辑,而不是代码行。通过结对编程可以减少低质量的单元测试,人都喜欢改变,但没人喜欢被改变,不要强求结对编程,让他看到好处,尝到甜头,吸引他来做结对编程,没有人喜欢落后,比如 50% 的人在做结对了,剩下的人自然会想尝试。

当被问及单元测试是否是必须的时候,Daniel 回答这并不是必要的,而是需要进行综合的衡量,比如你的竞争对手一周前推出了一个产品,你需要在一周内完成产品研发并上线,这时可以选择写或者不写单元测试,对于没有写过单元测试的人,一开始是需要上手的成本的。

如果您也对单元测试的话题感兴趣,不妨关注腾振宇的博客微博,也可以观看会议视频

2012-02-26 00:0914095
用户头像

发布了 135 篇内容, 共 61.8 次阅读, 收获喜欢 43 次。

关注

评论

发布
暂无评论
发现更多内容

数据库+chatGPT3.5 优化、索引、注释、SQL就是一句话的事了

非喵鱼

Java 数据库 openai ChatGPT ChatGPT4

Error:SyntaxError:JSON Parse error:Unexpected EOF 解决办法

Rose

adobe 安装报错

内部开发者平台与门户:二者有何关联?

SEAL安全

企业号 3 月 PK 榜 内部开发者平台 内部开发门户

Redis链表底层实现以及生产实战

做梦都在改BUG

Java redis 缓存 源码 链表

Microsoft 365 for Mac(原Office 365) v16.71正式版

理理

Office 365 office许可证

MacDroid mac版:实现安卓手机数据传输

理理

android Mac 数据传输 MacDroid for mac

周杰伦在唱什么?数据可视化告诉你!

博文视点Broadview

Acrobat DC弹窗:“未找到IMSlib,Acrobat服务将无法正常工作”,如何解决?

Rose

Acrobat DC 服务将无法正常工作

循序渐进讲解负载均衡vivoGateway(VGW)

vivo互联网技术

负载均衡 网关

SecureCRT for Mac(强大的终端SSH工具)附许可证 v9.3.2正式版

理理

SSH工具 SecureCRT下载 SecureCRT破解版 SecureCRT许可证

视频回放编辑工具:Mitti 激活版

真大的脸盆

Mac 视频处理 Mac 软件 视频编辑 视频回放工具

这5个有趣、强大的AIGC,你值得拥有

没有用户名丶

pd虚拟机专用windows系统镜像(m1/intel)

理理

pd 18 pd虚拟机 Win11系统下载

linux环境arm64架构编译iotDB

小黄鱼

Thrift IoTDB arm64

来啦!OceanBase DevCon • 2023议程公布!

OceanBase 数据库

数据库 oceanbase

IntelliJ IDEA 2022 for Mac(Java开发工具) v2022.3.3汉化版

理理

IntelliJ IDEA IntelliJ IDEA激活码 IntelliJ IDEA2022

MobPush Android 厂商通道回执配置指南

MobTech袤博科技

GtiHub上点赞已破百万!阿里内部并发编程四套全彩手册开源

架构师之道

Java 程序员 面试

MQTT安全专题01|构建可靠的物联网系统

EMQ映云科技

物联网 IoT mqtt 物联网安全 企业号 3 月 PK 榜

Movist Pro for mac播放流畅、观影愉悦!

Rose

苹果电脑 视频播放器 Movist Pro Mac Movist Pro 中文版

QPSK/DQPSK 调制解调系统仿真

timerring

通信系统仿真

火山引擎基于 Dragonfly 加速实践

SOFAStack

开源 开发者 开发

深入浅出RPC服务 | 不同层的网络协议

京东科技开发者

网络协议 RPC调用 应用层 jsf 企业号 3 月 PK 榜

江苏银行与易观千帆达成合作,打造金融服务“新样本”

易观分析

金融 银行 经济

活动回顾|龙蜥社区云原生 SIG 首届 MeetUp 圆满落幕 持续打造面向云时代的竞争力

OpenAnolis小助手

开源 云原生 Meetup 龙蜥社区 sig

什么是 LuaJIT?为什么 Apache APISIX 选择了 LuaJIT?

API7.ai 技术团队

lua api 网关 APISIX API Gateway

OpenAI 发布ChatGPT 插件支持,官方文档译文

B Impact

Ableton Live 11 Suite 音乐制作软件v11.2.11中文版安装教程

Rose

音乐制作 Ableton Live 11 Suite Ableton Live

窄带高清画质增强之生成式细节修复

阿里云CloudImagine

云计算 窄带高清

华大北斗上榜“深圳知名品牌”

江湖老铁

大模型时代的异构计算平台

百度Geek说

人工智能 深度学习 AI 企业号 3 月 PK 榜

我讨厌单元测试:滕振宇谈如何进行单元测试_研发效能_丁雪丰_InfoQ精选文章