写点什么

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

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

关注

评论

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

320000字2021春招高频面试真题汇总

爱好编程进阶

Java 程序员 后端开发

2021 年最新版 68道Redis面试题,20000字,赶紧收藏起来备用

爱好编程进阶

Java 程序员 后端开发

Dart9

爱好编程进阶

Java 程序员 后端开发

Day141

爱好编程进阶

Java 程序员 后端开发

用户行为分析模型实践(二)—— 漏斗分析模型

vivo互联网技术

大数据 数据分析 Clickhouse

企评家,打造专业的企业大数据SaaS平台

企评家

企业大数据 企评家 企业成长性评价

BATJ内部Java求职面试宝典,尤其应届生如果还没有学过那后悔去吧,也许你已经错过N多家大厂offer

爱好编程进阶

Java 程序员 后端开发

Elasticsearch Document Bulk API详解、原理与示例

爱好编程进阶

程序员 后端开发

电商行业客户服务的解决方案

小炮

Java Swing图形化编程之JTextArea

爱好编程进阶

Java 程序员 后端开发

10-2 5-2 查询至少生产两种不同的计算机(PC或便携式电脑)且机器速度至少为133的厂商 (20 分)(思路加详解+测试用例

爱好编程进阶

程序员 后端开发

AQS中那些不得不说的理论知识

爱好编程进阶

Java 程序员 后端开发

Dubbo实战案例01【需求分析及项目创建】

爱好编程进阶

Java 程序员 后端开发

IDEA常用快捷键总结

爱好编程进阶

程序员 后端开发

Java 之基础程序设计

爱好编程进阶

Java 程序员 后端开发

Java 将字节数组转化为16进制的多种方案

爱好编程进阶

程序员 后端开发

java IO流

爱好编程进阶

Java 程序员 后端开发

Java EE 阶段小项目(小型商城商品展示 + 购物车

爱好编程进阶

Java 程序员 后端开发

15-拦截器

爱好编程进阶

Java 程序员 后端开发

50道大厂经典Spring面试题,你能答出来几题?

爱好编程进阶

Java 程序员 后端开发

apk瘦身;如何缩小体积呢?这篇文章来教你

爱好编程进阶

Java 程序员 后端开发

Day340

爱好编程进阶

Java 程序员 后端开发

Python 操作 Excel 第3篇博客,python openpyxl 模块一文打通

梦想橡皮擦

5月月更

什么是隐私计算,它是怎样保护我们的隐私安全

华为云开发者联盟

安全 联邦学习 隐私计算 隐私安全 可信智能计算服务

2021-6-1【利用指针方法求数组的最大值和最小值】

爱好编程进阶

Java 程序员 后端开发

2个不同的对象集合如何取交集和差集

爱好编程进阶

Java 程序员 后端开发

Day301

爱好编程进阶

Java 程序员 后端开发

中科凡语周玉:用我们这一代人的努力扛起国产NLP发展大旗

硬科技星球

呵呵,JavaScript 真好玩(苦笑脸)

Git 这样回退代码,才足够优雅

爱好编程进阶

Java 程序员 后端开发

HR面试都会问什么问题?(上

爱好编程进阶

程序员 后端开发

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