QCon 演讲火热征集中,快来分享技术实践与洞见! 了解详情
写点什么

James Grenning 访谈录:关于测试驱动开发及代码异味

  • 2015-08-31
  • 本文字数:4009 字

    阅读完需:约 13 分钟

OOP 2015 大会上,敏捷宣言的签署人 James Grenning ,就技术卓越和嵌入式C 的测试驱动开发做了两场报告。InfoQ 就以下几个问题采访了James Grenning:为什么开发者没能有效地或足够好地从事技术实践、为什么会认为TDD 是有趣的、单元测试的重要性、为什么程序员应具备优秀的代码嗅觉以及怎样才能更好地找出“糟糕的代码”。

InfoQ:您能否详细描述下“技术卓越”指的是什么?为什么它这么重要?

Grenning对我来说,技术卓越就是去成为一名工程师,去解决问题。在我们这个行业里,有太多的时候,人们似乎接受了代码一团糟并存在 bug。工程师们围坐在一圈,等待着构建他们庞大的代码。依赖的管理成了工程师们的噩梦,但他们接受了这一切现实。形如所处局面的受害者而不是主宰者。

当我去我的内科医生那看病的时候,他总是知道我所用药品的最新信息,或最新的疗法。他是个专业人士。他有在持续不断地学习新事物。他跟我说,当他开始执业的时候,医学知识的半衰期大约是 7 年。现在他说,事物变化如此之快以至于一年之内他就可能会被淘汰。

技术卓越意味着成为一名专业人士、学习以及持续改进。

InfoQ:在您看来,是什么原因导致大家在诸如 TDD或重构等技术实践上做的不够或不够好?

Grenning尽管 TDD 和重构的技术实践自 1999 年左右起就出现了(随着《解析极限编程》的出版),大多数软件开发领域的人却不知道那是什么。我记得当我还是一名年轻的工程师的时候,大量的时间花在我的雇主和我的家庭上面。没有很多的时间可以投入学习什么是最佳理念和技术。关于如何生产软件,市面上有很多的想法。但不是所有的都是那么有帮助的。所以,弄清楚把精力用在哪里是件困难的事情。当我还是一名在新领域的年轻工程师时,我认为我什么都知道。

随着经验的累积,我开始谦逊地意识到,并不是所有的事情我都懂。在这个博大精深的领域,有很多东西需要掌握。我们每个人学编程的方法都是独一无二的。就我而言,教授在展示了一些 C 程序的结构例子后,给我们布置了一道作业,去编写一个操作系统。自己去搞定它!最后我们每个人确实都用自己独特的方式把它编写出来了。好像没有人是被教会如何编程的。如果你认为自己已经是技术大师了,还会有什么动力去学习更多的知识呢?

我对准备来参加我的培训的人做了个调查。可以在培训准备答复里看到问题和回复。在那里可以看到编写软件和测试软件所用的技术存在很大的不同。大多数反馈结果显示,他们用的技术还是我们 70 年代在大学用的,以及行业在 80 年代 90 年代时使用的技术:打印语句、在调试器中下断点和执行单步跟踪。恭喜你,都 2015 年了,你却还处在使用产自上世纪 70 年代的调试技术的状态。试一下 1999 年的缺陷预防技术 TDD 怎么样!?

见识过 TDD 后,工程师们告诉我,他们没有时间去写测试用例代码。他们没有时间去积极主动地预防缺陷,但却有时间去应对这些缺陷。工程师们还告诉我,他们的老板不会允许他们编写单元测试用例。对我来说这就相当于,因为我要赶时间所以不用遵循医生的处方。

问题部分在于大多数开发者处于一个长的反馈回路中。例如我上报给老板的时间估期是三个月。两个半月后,我走向老板并带给他一个坏消息,我还需要一个月时间。不断如此。最终,在六个月后,交付了一部分原定功能。这只会让人觉得,工程师只在快到最后期限了才认真工作。这样对工程师的信誉有什么好的影响呢?不会有多少吧。

迭代地开展工作,将功能分解为一小块一小块,每隔几周交付一次,这对程序员的信誉和信心会很有益。通过测试用例的安全保障,可以捕获程序行为中的有害的变更。一旦程序员掌握了 TDD,这些都能轻松达成,而一开始就以 TDD 的方式进行编码所花费的时间与用 70 年代的方法所需的时间相差无几,70 年代的编程方法主张后续调试(见测试驱动开发的原理)。

InfoQ:您在演讲中提到 TDD实施起来充满乐趣。能举一些例子吗?

Grenning我还向参加我的培训的学员们提了一些问题,包括:你最喜欢软件开发的哪一点以及你最不喜欢软件开发的哪一点

我这样做是为了确保坐在房间里参加培训的是合适的人选。从学员们的答复中我发现,他们喜欢解决问题、创造新东西、从事设计以及挑战智力。一些人喜欢调试程序所带来的挑战。他们不喜欢花太长时间去找 bug,也不喜欢不现实的最后期限、需求变更、文档、其他人的烂代码。

我设法向他们展示,他们能在喜欢的部分(解决问题、创造价值)做得更多,并且少做些他们不喜欢做的事情(找 bug、没用的文档、延期)。

下面这段话是我在嵌入式 C 的测试驱动开发一书中对 TDD 的论述:

“TDD 是有趣的!它就像是一场游戏,你穿行在一个由技术抉择组成的迷宫中,意图得到一个高度健壮的软件同时避免泥潭般的漫长调试阶段。每通过一个测试用例,能收获到新的成就感,刷新了目标完成进度。自动化测试用例记录下假设条件、捕获判定结果并解放了心力让其能专注于接下来的挑战。”

InfoQ:您提到执行单元测试非常关键,它奠定了软件的基础。对此您能解释一下吗?

GrenningTDD 让代码去完成程序员认为代码应做的事情。开发出的模块包括可执行规格,即测试用例。测试用例精确记录了代码应做之事。如果代码开始违反规格了,测试用例就执行失败。代码的一大问题是很难预估那些多余的副作用。对一部分代码做了更改,却会导致似乎并不相关部分的代码出现问题。

如果只想让代码做你想要它做的,需要通过测试来让代码保持可控。我不是 Web 开发者,但我有学过相关内容,所以我也能控制并更新我的网站,用它来支撑我的培训和业务。在我从头开始创建了一个新的服务器之前,我的 Web 部署脚本运行良好。在我原来的服务器上,有一个命名错误的目录。同时发现在我的脚本上也存在几处错误的命名。用于校验目录的判定逻辑恰好反过来允许部署我的网站。部署脚本运行在错误的原因上。因为我恰好把错误给抵消了。

当我修复了部署脚本后,我还得在一些其他脚本上也修复出错的目录。很多时候系统可以工作是因为凑巧。对于一个可靠的系统而言,有着坚实基础的代码至关重要,这样的代码只做程序员认为它应做的事情。

InfoQ:为什么您认为程序员需要拥有良好的代码嗅觉呢?

Grenning那些想改进他们的工作代码的程序员需具备三项核心技能。良好的代码嗅觉、构想出改进设计的技能以及将烂代码改好的技能。

简单地说,如果你不能以一定的精确度甄别出代码结构中的问题,你怎么能修复问题?回想起我的职业生涯,代码评审通常只不过是一个观点。“我不喜欢那样,我会这样做”,完全没有任何论据支持。随便一个程序员都能说出“这份代码糟糕透了”类似的话,但这远不够好。厨房里的大厨闻一下空气的味道就能说“把土豆扔出去,它们坏掉了,去拿些新鲜的过来”。程序员需能甄别出代码的具体的不足之处,且能想出该如何改进代码。

InfoQ:程序员要怎么做才能在找“烂代码”方面变得更好?

GrenningMartin Fowler 在他的书中对此下了一个很好的定义。在我的书中,我又增加了一些条款。Bob Martin 在他的 SOLID 设计原则中就讨论模块化和耦合问题给出了具体的建议。开发者需要以代码异味以及编码原则来阐述这些。

为了能在找烂代码上做得更好,开发者需将自己置身于干净的代码中。干净的代码不需要注释来告诉别人代码在做什么。干净的代码能很容易做到在过后重回代码。干净的代码有测试用例,能用来说明预期结果。干净的代码的命名经过了深思熟虑。干净的代码使用元音。代码评审也有帮助,不过得少关注些观点,多聚焦代码特性,比如 DRY、SOLID 和避免代码存在明显的异味。结对编程是个编写更好的代码的好办法。你知道的,两个脑袋比一个脑袋强。关于这方面,有很多相当不错的资源,找找就能有。

InfoQ:通过加大实施技术实践来提升技术的卓越,需要做些什么?

Grenning我认为强调独自工作以及专业化的文化在某种程度上是错误的。如果你所能见的都只是你自己的代码,你会产生这样的观念,一切都很好并且已经没有什么新东西要学的了。在开发周期的后段进行代码评审意味着改进将变得最困难。公司应当鼓励员工更紧密地一起工作。结对编程对传播技术的卓越之处非常有益,这是个双向的过程。

如果你正在看这篇文章,很可能你已经理解了这个问题。那么请把它给你的朋友,看看能否帮忙把这样的信息传播出去。

InfoQ:您对员工该如何说服他们的主管(以及他们主管的主管)支持员工学习和持续改进有什么建议吗?

Grenning两千年初在 Object Mentor 的时候,我们成功说服自己接受了这样的观点,极限编程的技术实践真的很重要。我们想,既然我们信服了这个观点,我们要把这些告诉其他人,他们也会被说服的。好吧,进展没有这么快。我们开始对尚未被识别出或被接受的问题提出解决方案。我又再次发现工程师最重要的技能是解决问题。但解决问题也应该成为管理者和公司执行官的一项重要技能。所以我的建议是,不要强推解决方案。甄别出问题,然后为解决问题提供支持。要超越你个人的经验去寻找解决方案。

采访嘉宾简介

James Grenning,Wingman Software 的创始人,在全球范围内从事培训、教练及咨询。拥有超过 30 年包括在技术上和在管理上的软件开发经验,James 给软件开发团队以及团队管理带来了丰富的知识、技能和创造性。他的专业根植于嵌入式软件领域,同时在向该富有挑战性的领域引入敏捷开发实践上走在了前列。可阅读 James 的文章获取关于在嵌入式软件开发中应用敏捷的内容。他感兴趣的领域有软件过程改进、面向对象设计、编程、嵌入式系统、项目管理、极限编程、测试驱动开发、自动化测试以及敏捷软件开发。James 熟悉 Scrum,拥有 Scrum Master 及 Product Owner 资格证书。

查看英文原文: Q&A on Test Driven Development and Code Smells with James Grenning


感谢邵思华对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。

2015-08-31 11:062613
用户头像

发布了 30 篇内容, 共 86795 次阅读, 收获喜欢 1 次。

关注

评论

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

企业必看:10款知名的公司内部网盘推荐

易成研发中心

如何使用Postman优雅地进行接口自动加密与解密

LLLibra146

Python Postman 代码技巧 自动加解密 调试技巧

构建高效AI工作流:打造灵活自动化的分步指南

代码忍者

OmniFocus Pro 4 v4.4.3正式激活版 mac最佳GTD时间效率工具

理理

Audition 2025 全新升级:多轨编辑超进化与协作功能大突破

理理

如何通过高效的缓存策略无缝加速湖仓查询

镜舟科技

开源 StarRocks Data Cache

双十一站在中小企业的角度,谈谈我为什么选择华为云Flexus数字人

平平无奇爱好科技

华为鸿蒙智家,推开未来之家的三重门

脑极体

AI 鸿蒙智家

文献解读-Transcriptional Start Site Coverage Analysis in Plasma Cell-Free DNA Reveals Disease Severity and Tissue Specificity of

INSVAST

基因检测 基因数据分析 生信分析 Sentieon

Rhinoceros 8 (犀牛8):建模实力大爆发,复杂曲面构建轻松拿捏

理理

双十一我为什么选择华为云Flexus数字人?广告输出更高效率、更有创意

平平无奇爱好科技

双十一华为云Flexus数字人性价比有多高?百元投入即可轻松入手

平平无奇爱好科技

鸿蒙NEXT元服务:利用App Linking实现无缝跳转与二维码拉起

zhongcx

鸿蒙

霍尼韦尔拟将个人安全防护设备业务出售给PIP公司

财见

企业如何选型区块链电子合同系统?6个推荐方案

爱吃小舅的鱼

区块链 电子合同系统

Mac代码管理软件:SnippetsLab for mac v2.6激活版

理理

RGB/INT8 输入注意事项

地平线开发者

自动驾驶 算法

传媒行业必备!双十一购买华为云Flexus数字人后,我总结了3大优势

平平无奇爱好科技

Ai2025新增功能介绍 Illustrator 2025 激活版下载安装

理理

CRISPR-detector:快速、准确地检测、可视化和注释基因组编辑事件引起的全基因组范围突变

INSVAST

基因测序 基因数据分析 生信服务 生信分析 Sentieon

Scheduled线程池实践

FunTester

专为中小型企业设计!双十一华为云Flexus数字人性价比更高

平平无奇爱好科技

日立携手APIX启动绿色金融创新挑战赛:征集创新绿色融资解决方案

财见

淘宝直播弹幕数据接口爬虫项目技术文档

tbapi

淘宝API接口 淘宝直播间弹幕接口 淘宝直播间接口 淘宝数据分析接口

GeneMind 公司的 GenoLab M 测序平台 WGS 和 WES 数据基准测试

INSVAST

基因测序 基因数据分析 生信服务 生信分析 Sentieon

双十一入手数字人!华为云Flexus数字人3大优势赋予硬核体验

平平无奇爱好科技

《Django 5 By Example》阅读笔记:p339-p358

codists

Python django

伟创力完成对Crown Technical Systems公司的收购

财见

直播预告丨大模型+知识库(RAG):如何使能行业数智化?

平平无奇爱好科技

ForkLift for mac:文件管理超能力,高效传输、智能预览全掌控

理理

James Grenning访谈录:关于测试驱动开发及代码异味_架构_Ben Linders_InfoQ精选文章