为什么 TDD 很重要
在一家负责开发软件产品的企业中,开发者们编写代码的方式是非常重要的。良好的技术实践意味着企业可以在更短的开发周期以更高的质量完成新的功能,以及在截止日期之前交付更可靠的软件。资深的技术开发人员会希望自己工作的企业有着高质量的代码、高效率的开发实践,以及健康的企业文化,另一方面,如果一家企业的代码质量粗糙且企业无法改善该问题,那么他们终将面对无法及时交付新功能或开发成本过高的困境,这对任何企业来说都是一场灾难。
研究证明,技术实践所带来的这些影响是实际存在的。Forsgren 等人在他们的《加速》一书中讲述了他们多年来针对软件开发企业的研究成果:通过分析诸多因素,他们发现了对商业的成功贡献最大的几个因素,其中,“持续交付”的实践尤为重要。这里的“持续交付”囊括了多种技术上及组织上的实践,其中就包括了 TDD。
当然,并不是说采用 TDD 就一定能使企业获得成功,但它对商业成功的重要性却也是不可否认的。高质量的代码是通过编写有效的自动测试、频繁地集成,以及不断地进行设计改良实现的。这套流程并不是所有的团队或软件开发者都有能力做到的。
在多年的技术指导中,我遇见过很多软件开发者都习惯于较长的交付周期和以周为单位的集成频率,他们除了手头工作中必要的改动很少进行设计优化。而在我看来,这些团队的工作效率只能达到那些广泛采用 TDD 的团队的一小部分。TDD 模式和在 TDD 的影响下形成的高质量代码库,对团队工作、合作能力,以及开发者们总体的身心健康的提升都是非常显著的。
现在的企业都在做什么
在《加速》一书中的研究表明,最佳企业和低绩效企业之间是存在巨大鸿沟的。在充斥着数字化、DevOps 和业务敏捷性的新世界中,企业需要提高其在软件开发方面的能力。我遇见的很多经理、架构师和技术负责人都非常乐意提升他们开发团队的实践效率。
在最近的 2021 年 ACCU 会议上,我向 300 多位参会者发起了问卷调查,调查他们企业正在使用的技术学习活动都有些什么。以下是最受欢迎的几个选项,排名越高票数越高。(当然,参加技术会议也算是其中一项活动,但鉴于我采访的对象都是会议参与者,所以在这里并没有被列出来)
代码审查
线上自学培训视频
每次 2-5 天的由讲师指导的培训课程
频繁的结对编程
黑客马拉松(Hackathons)
实践社区
我随后还询问他们是通过哪些活动成功地学习了 TDD 模式,不幸的是,大多数人都选择了“从未学习过 TDD”的选项,而排名第二和第三的则是“频繁的结对编程”和“线上自学培训视频”。
这个结果证明了我的观察:TDD 并不是能轻易上手的。最好的学习方式应该是向熟练掌握这项能力的前辈们学习,而学习者本身也需要通过大量的重复练习实践才能真正掌握它。想要简单通过黑客马拉松或代码审查这类的活动学习 TDD 是不行的。即使是有讲师指导的培训课程成功率也不怎么高,因为这些课程时间太短而且重复的次数太少,不足以让人们习惯新的开发方式。
与熟知 TDD 的人结对编程是少数几个在我看来真正有效果的。然而,大部分的团队并没有可以用于结对的人。另外,如果参与者有目的性且能坚持完成的话,自学线上培训搭配大量的练习也是有可能成功的。然而,如果在你的团队中只有少数的几人掌握了 TDD 模式,这对团队整体而言是没什么太大帮助的。
个人经验之谈
在 2005 年,一个名为代码道场(Coding Dojo)的论坛让我看到的前进的希望。在这个交流学习 TDD 的论坛中,我成功帮助我的同事掌握了 TDD 模式,并且于 2011 年,我出版了我的第一本书《代码道场的教学手册》。
在代码道场中,人们可以学习到 TDD 相关的基础知识,并开始着手尝试改变自己的开发方式。但在几年之后,我才清楚地意识到,它所带来的改变并非是长久的,这一点在那些代码质量差且无法顺利实施 TDD 的企业中尤为明显。人们从代码道场中尝试的 Kata 练习与他们在办公桌后真实世界中的代码开发存在了太大的差异。
下一步的尝试:Samman 方法
在 2018 年,我收到了来自 Llewellyn Falco 的热情邀请,作为他的客户,我在美国与他一起进行了两周的配对指导,在这段工作之中,我惊喜地发现他的方法似乎真的很有效。他在小组代码中使用的 Kata 课程正是我曾经在代码道场中曾见过的,再加上全团队共同动手实践生产代码库的课程,这二者的结合似乎是他成功坚持使用 TDD 的关键所在。
我从那次的工作中受到了很大的启发,并改变了我在技术指导中的方向。在接下来的三年中,我找到了四五个愿意进行这种新式技术指导的企业,并招募到了更多愿意以同样方式进行合作的人,我们一起将这种方法进行发展改进。而在下文中,我想与大家一起分享一些高效率的工作技巧。
为了将这种方法与其他方法相区分,也为了人们能够更准确地找到它,我决定给它起一个独特的名字。“Samman”,是瑞典语中“一起”的意思,对于这种涉及大量“合奏(ensemble)”的方法来说似乎很是合适,而“ensemble”在法语中也有“一起”的意思。另外,我的新书《Samman方法的Agile训练》已于 2021 年 1 月出版。
什么是 Samman 方法
Samman 方法是为寻求改变、优化软件搭建形式的人们设计的,着重于技术实践与代码编写方式。Samman 的导师可以同时负责多个软件开发团队,并将课程划分为两大组成部分:
学习时间
合奏工作
在“学习时间”中,导师会通过练习以及主动学习技巧来教授诸如 TDD 等理论和技术实践。在“合奏”环节,整个团队将与导师合作,在他们日常的生产代码库中应用 Agile 开发技术。“合奏工作”的另一个名字可能更为人所知:Mob 编程。
学习时间:短小而频繁的代码道场训练
当人们在学习一门新的技能时,无论是一种新乐器、一门外语、一种新的舞蹈风格、新的烹饪方式,或者是一项新的运动,成功地掌握新技能的背后一定会有某种形式的教学或辅导,以及相当时长的专门练习。最好的学习经历通常发生在友好的学习小组之中,有一位鼓舞人心的老师和趣味十足且难度恰到好处的动手练习。这也是学习时间的本质。
Sharon Bowman 在她的畅销书,《从房间后面开始训练》中所使用的名为“4C”的教学方式让我受益匪浅。在这个模式中,每个学习时间都是由这四个部分组成:
连接(Connect)
概念(Concept)
具体实践(Concrete Practice)
结论(Conclusion)
前文中我们所提到的新技能的学习过程就是一种“连接”。学习一门新技能需要我们将它与我们已有的知识结合起来,而在我们进入下一步“概念”之前,让学习者有机会温故而知新是很有帮助的。
站在幻灯片前的演讲是一种传递新概念的方式,但却不一定是最有效的。我们希望能够激发学习者的好奇心,让他们成为自己的学习过程中的主动参与者,人们的大脑会在多样性、活动、社交互动和自我发掘中茁壮成长。在教学过程中,我一般都会尽量减少幻灯片的张数。
如果说我想向成员们描述 TDD 的一个概念,那么我会通常选择用一个简短的演示(demo)进行技术展示。如果我需要教授的是一个设计模式或可测试的问题,那么我会让参与者尝试对代码进行审核。而对于像是参数化测试这类的新代码技术,我则会让参与者在网上搜索代码片段或设计建议。
“具体实践”通常意味着代码编写或 Kata 代码练习。这项活动通常是学习时间中耗时最长的部分;在大约 30-45 分钟内,进行团队全员“合奏”或者是二至三人的小组合作。在这段时间内,你可能不能写大量代码,这就是为什么导师需要首先确定团队的起始点,并给出清晰的指示,让参与者们可以直接开始应用他们在课程中所学到的概念。
我曾在代码道场中练习使用的 Kata 练习让我在多年之后依旧能从中受益,即使是在现在,我依旧会在学习时间中重复利用其中许多的 Kata 练习,并几乎没有任何修改。但我新提出的练习往往更小,并且更专注于某个特定的技巧。我在教学过程中也会经常使用同一个 Kata 练习来教授不同的技术,并在仓库(repo)中有不同的分支(branch)来设置不同的起点。“超市收据”就是一个很好的示例,我可以通过这个例子教授重构,也可以教授批准测试中的不同部分。
在学习时间结束之前,我会用几分钟时间来整理课程中的“结论”部分。如果人们自己动手写总结,或是向他人解释自己所学到的知识,会帮助人们更好地记住他们所学的内容。最后,我还会鼓励参与者在没有导师在旁指导的情况下自己动手尝试一次练习。熟能生巧,只有不断的练习才能带来技能上的进步。
日常任务中的合奏工作
我们将所有聪明的头脑在同一时间、同一空间、同一电脑上共同研究同一事物,称作是“Mob 编程”。——Woody Zuill
这段引用来自 Woody Zuill 和 Kevin Meadows 合著的《Mob 编程:全团队的方法》一书,他们也是我在 Mob 编程方面的启蒙者。但在之后的几年中,我更倾向于以另一个词来描述这种合作形式,“合奏”。合奏象征着人们如乐团中的演奏者一样相和谐的工作方式,这是我喜欢这个词的原因,但 Mob 与合奏技术的本质还是一样的。
就像是演奏者们需要经过排练才能演奏出优美的音乐一样,程序员们同样需要通过学习才能更加丝滑地合作。你可以在团队中担当不同的角色,不同角色所需要的技能也会有所不同。“引导者”的角色要面临的第一份挑战就是要如何向别人讲述代码与设计,他们需要将之前只用打字描述的“声明新变量”或“内联返回语句”更加直白地向别人描述出来。而人们在描述过程中习得的新的词汇将会让我们在更高的抽象层次上思考问题,并为设计讨论打开新的局面。最终,整个团队都可以参与到开发工作之中,汇集他们知识的力量,并生产出能令所有人都感到自豪的代码。
我在“合奏”中曾多次遇见过类似的情况:最初,团队中只有 A 知道该如何完成某个任务,但通过合奏中知识的传递,很快团队中的所有人都学会了如何完成这项任务。这种现象并不少见,人们通过互相学习,知识和技能得到了快速的传播。这也是我作为技术指导在观察得到的最令人印象深刻的现象,合奏团队中人们就像是拥有了超能力一般,在需要的时候,可以以非常自然的方式向整个团队传递知识。
当我在从旁指导合奏团队时,我会经常引导参与者们使用 TDD 模式,具体来说就是在讨论需要做什么时,我会要求参与者首先列出一份测试清单。而当参与者们开始实现代码时,我会建议他们从测试开始写。如果需要重构,我会建议他们从步子迈小一点,从更安全的部分开始。如果他们在任何一步遇到困难,我都会以引导者为他们做示范。我会尽量弱化我的存在感,只在必要的时候为团队提供前进方向上的指引,而当人们有自信接管时,我则会毫不犹豫地退后。
作为技术指导,在合奏团队中辅导的经历可以让我不断从团队成员中学习新的技能。仅仅是和不同的人们共事就可以让你学习到新的工具、框架,以及设计想法,更不用提个人层面上的回报了,当你不断在不同团队中辅导,传播你的知识时,这种工作模式最终会让整个企业都受益匪浅。
在合奏期间中,团队会选择一个他们日常工作中的任务,在导师的帮助下,团队会学着应用相关的 Agile 开发技巧。这一步很重要,如果你仅仅局限于刷题或做代码道场,你会跳过这一步。而这一步则是我们能看到 Agile 技能在生产代码中发挥作用的时候。
当人们最初开始学习合奏工作时,每天两小时的练习时长足矣。这也是为什么 Samman 方法可以让导师在需要的情况下,同时跟进不同的团队。在早上,团队 A 用两小时进行合奏,一小时学习时间,而在下午,团队 B 可以进行训练。如果你想再拼搏一下,每天三个团队合奏工作训练也是可以做到的,只是需要每天仅安排一个学习时间。但这样一来导师的压力也会变得非常大。
我曾进行过面对面培训和线上培训,两种方式都很好,只是各有优缺点。面对面的培训让你可以直接读到人们的肢体语言,也可以在团队进行工作时在一旁不打扰地说悄悄话。在线上时,所有人都可以清楚地看到你在电脑屏幕上展示的代码块,所有人都有舒适的椅子、电脑和显示器等等。人们如果想要查询文档或者其他代码部分时也会很容易,毕竟所有人都有自己的屏幕,也可以随时查看共享屏幕。
我发现在十天半的培训之后,进行一次几天或几周休息会更好,导师和团队都能从中受益。休息之后,可以进行新的一轮培训课程。这样一来,团队有一定时间在没有导师的情况下尝试新的工作方式,并且在导师继续下一轮辅导之前认识到自己知识方面的已掌握的和匮乏的。而导师则有机会为下一轮辅导备课,并在需要的情况下与成员进行一对一的辅导,或者是准备未来新团队的辅导训练。
观察结果
在经历 10 天半的训练周期之后,我观察到大部分的团队都已经能够掌握合奏工作的窍门,并且可以在导师不在的情况下独自完成任务。这项技能本身对于团队而言非常重要,在随后的工作中,开发者们可以自行决定什么时候采用这种合作技术:有的团队选择在大的设计变更和新团队成员入职时进行合奏训练,而有些企业甚至选择将其作为日常工作中的一部分。
我的另一项观察结果则是态度的改变。在结束辅导的调查中,大部分开发人员都认同了以下几点:
更愿意于编写单元测试
更愿意安全地改进设计和重构
更愿意于设计可读、可维护的测试案例
更愿意提交小增量的代码,更频繁地提交代码
改进的团队合作,更好的协作
目前为止,我还未曾与任何成功大规模采用 TDD 的大型公司进行过合作。而在小规模团队中,我见证过不少团队成功采用合奏工作,并且开始编写更多的单元测试。最明显的变化当属在其中几个案例中,团队中已经有颇为资深,且掌握了一些 TDD 技能的团队成员,他们能够在培训之后从纸上谈兵,进一步地与团队中的其他成员真正地采用 TDD。
Samman 训练对你是否适用?
我相信这个世界需要更多的技术导师。很多团队现在都在与糟糕的代码作斗争,并且缺乏取得良好进展所需的 Agile 技能。有许多的开发者和技术领导或许拥有这些技能,但他们却很难在企业中广泛且迅速地将这项技能进行传播。Samman 是一种具体的方法,将有效的开发实践带入需要它们的团队与企业之中。
原文链接:
https://www.infoq.com/articles/spread-technical-practices-organization/
评论