测试驱动开发与观察循环
2014年5月9日,作者:Max Kanat-Alexander
今天,Kent Beck、Martin Fowler和David Heinemeier Hansson之间进行了一场关于测试驱动开发(TDD)本质和使用的有趣讨论。在TDD中,开发者先写测试,然后再写代码。
对话中的每位参与者对编写代码的方式都有不同的个人偏好,这是很合理的。然而,从每位参与者的个人偏好中,你可以提炼出一个相同的原则:“在做出决策之前,我需要观察某些东西。”
Kent经常(虽然不总是)喜欢先写测试,这样他就能在编码时观察它们的行为。David经常(虽然不总是)想先写一些初始代码,观察它来决定如何编写更多代码,依此类推。即使当他们谈论他们的替代方法时(例如Kent谈到他不使用TDD的时候),他们仍然总是谈到将观察某些东西作为开发过程的内在部分。
可能会有人轻视这一点,认为它只与调试或测试相关。确实,它在这些领域很有用,但当你与许多资深开发者交流时,你会发现这个想法实际上是他们整个开发工作流程的基本基础。他们希望看到一些能帮助他们关于代码做出决策的东西。这不仅发生在代码完成时或存在错误时——它发生在软件生命周期的每一刻。
这是一个如此广泛的原则,以至于你可以说所有软件开发的循环是:观察 → 决策 → 行动 → 观察 → 决策 → 行动 → 等等。
如果你想要一个术语,你可以称之为“观察循环”或“ODA”。
示例
我所说的这一切是什么意思?让我们举一些例子来使其更清晰。
在进行TDD时,循环看起来像这样:
- 发现问题(观察)。
- 决定解决问题(决策)。
- 编写一个测试(行动)。
- 查看测试,看看API看起来是否良好(观察)。
- 如果看起来不好,决定如何修复它(决策),更改测试(行动),并重复观察 → 决策 → 行动,直到你喜欢API的样子。
- 现在API看起来不错,运行测试并看到它失败(观察)。
- 决定你将如何使测试通过(决策)。
- 编写一些代码(行动)。
- 运行测试并看到它通过或失败(观察)。
- 如果失败,决定如何修复它(决策)并编写一些代码(行动),直到测试通过(观察)。
- 根据软件设计原则、对问题的了解或在编写先前代码时获得的数据,决定下一步要做什么(决策)。
- 依此类推。
另一种有效的方法是先编写代码。与上述序列的区别在于,第3步将是“编写一些代码”而不是“编写一个测试”。然后你观察代码本身以做出进一步的决策,或者在代码之后编写测试并观察它们。
有很多有效的流程。
开发流程与生产力
有趣的是,据我所知,每个有效的开发流程都遵循这个循环作为其主要指导原则。即使是像Agile这样涵盖整个团队的大规模流程也内置了这一点。事实上,Agile在某种程度上是试图为团队实现比先前破碎的模型(瀑布模型,又称“前期大设计”)更短的观察-决策-行动周期(每隔几周),后者需要数月或数年才能完成一个单一周期。
因此,较短的周期似乎比较长的周期更好。事实上,开发者生产力的大部分目标可能仅仅通过将ODA周期缩短到对开发者、团队或组织合理的最小时间范围来实现。
通常,你可以通过专注于观察步骤来实现这些较短的周期。一旦你这样做了,周期的其他两部分往往会自行加速。(如果它们没有,还有其他补救措施,但那是另一篇文章的内容。)
在观察中需要解决三个关键因素:
- 信息传递给开发者的速度。(例如,拥有快速的测试。)
- 传递给开发者的信息的完整性。(例如,拥有足够的测试覆盖率。)
- 传递给开发者的信息的准确性。(例如,拥有可靠的测试。)
这有助于我们理解近几十年来某些开发工具成功背后的原因。持续集成、生产监控系统、性能分析器、调试器、编译器中更好的错误消息、突出显示不良代码的IDE——几乎所有“有效”的东西之所以有效,是因为它们使观察更快、更准确或更完整。
有一个注意事项——你必须以人们能够实际接收的方式传递信息。如果你将大量信息倾泻给人们,而不让他们容易地找到他们关心的特定数据,那么这些数据就变得无用。如果没有人收到生产警报,那它就无关紧要。如果开发者从不确信收到信息的准确性,那么他们可能会开始忽略它。你必须成功地传达信息,而不仅仅是生成它。
第一个ODA
有一个“大ODA循环”代表了软件开发的整个过程——看到问题,决定解决方案,并将其作为软件交付。在那个大循环中,有许多较小的循环(看到对功能的需求,决定功能应如何工作,然后编写功能)。其中还有更小的循环(观察单个变更的需求,决定实现方式,编写一些代码),等等。
最棘手的部分是任何这些序列中的第一个ODA循环,因为你必须在没有先前决策或行动的情况下进行观察。
对于“大”循环,可能看起来你开始时没有任何东西可以观察。还没有代码或计算机输出可看!但实际上,你开始时至少可以观察自己。你周围有你的环境。你可以与其他人交谈,有一个世界可以探索。你的第一次观察通常不是关于代码,而是关于现实世界中需要解决的、能以某种方式帮助人们的问题。
然后,当你进行开发时,有时你会遇到一个点,你必须决定“我接下来该做什么?”这就是了解软件设计法则可以有所帮助的地方,因为你可以将它们应用于你编写的代码和你观察到的问题,这让你可以决定工作的顺序。你可以将这些原则视为一种二手观察的形式——数千人年的经验被压缩成法则和规则,可以帮助你现在做出决策。只要准确,二手观察是完全有效的观察。
你甚至可以将观察过程本身视为它自己的小ODA循环:观察世界,决定将注意力放在某物上,将注意力放在那件事物上,观察它,基于此决定观察其他事物,等等。
使用这个原则的方式可能是无限的;以上所有内容仅代表几个例子。
-Max