写点什么

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:062517
用户头像

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

关注

评论

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

关系数据库:定义、模型、排名

Frank

关系型数据库

HBase入门指南

Java随想录

Java 大数据 habse

可以拯救陈年老视频的Topaz Video AI

展初云

Mac软件 视频修复工具

央国企数字化转型的破局者:低代码引领变革,高效应对未来挑战

优秀

低代码 数字化转型 央国企数字化转型

软件测试/测试开发丨利用ChatGPT 生成自动化测试脚本

测试人

人工智能 程序员 软件测试 测试开发 ChatGPT

Scala语言入门:初学者的基础语法指南

Java随想录

Java scala 大数据

有限状态机在国际计费中的应用探索 | 京东物流技术团队

京东科技开发者

状态机 有限状态机 企业号10月PK榜 系统应用

深度学习算法:从模仿到创造

小魏写代码

Spring扩展-自定义标签

官宣|2023开放原子开发者大会来了!

开放原子开源基金会

与客户携手共进|博睿数据客户最佳实践精选

博睿数据

可观测性

DAPP钱包单币丨多币丨LP质押挖矿系统开发

l8l259l3365

数字赋能,联通未来——数划云亮相“2023创源工业互联网创新大赛暨优秀项目路演”

数划云

数划云受邀参与2023甄云用户大会,分享数据驱动经营新经济企业业财一体新路径

数划云

如何搭建一个集成导航与在线工具的个性化浏览器私有书签(附详细搭建教程)

百度搜索:蓝易云

云计算 Linux 运维 书签 Mtab

ICCV 2023 | 当尺度感知调制遇上Transformer,会碰撞出怎样的火花?

阿里云大数据AI技术

人工智能

飞桨大模型套件:一站式体验,性能极致,生态兼容

飞桨PaddlePaddle

nlp 大模型 套件 大语言模型

开放原子开源大赛 | OpenAnolis赛题正式启动,诚邀报名!

开放原子开源基金会

Redis中的Big Key问题:排查与解决思路

Java随想录

Java redis

Mac平台的视频编辑和调色软件 DaVinci Resolve Studio 18

展初云

Mac软件 视频编辑 达芬奇18

MySQL分区表详解

Java随想录

Java MySQL

基于火山引擎云搜索服务的排序学习实战

字节跳动云原生计算

大数据 搜索引擎 云原生

Spark入门指南:从基础概念到实践应用全解析

Java随想录

Java 大数据 spark

【稳定性】稳定性建设之弹性设计 | 京东物流技术团队

京东科技开发者

系统稳定性 限流算法 企业号10月PK榜 弹性设计

全场景流量验证系统 | 京东物流技术团队

京东科技开发者

系统设计 测试 企业号10月PK榜 流量验证

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