测试驱动开发与观察循环:提升开发效率的核心模式

本文深入探讨测试驱动开发(TDD)的本质,提出软件开发的核心循环模式"观察-决策-行动"(ODA),分析如何通过缩短观察周期提升开发效率,并讨论持续集成、测试覆盖率等工具如何优化观察过程。

测试驱动开发与观察循环

2014年5月9日 by Max Kanat-Alexander

今天,Kent Beck、Martin Fowler和David Heinemeier Hansson之间进行了一场关于测试驱动开发(TDD)本质和使用的有趣讨论。TDD是一种先写测试再写代码的开发方法。

对话中的每位参与者对编写代码的方式都有不同的个人偏好,这是合理的。然而,从每位参与者的个人偏好中,可以提取出一个相同的原则:“在做出决策之前,我需要观察一些东西。” Kent经常(虽然不总是)喜欢先写测试,以便在编码时观察它们的行为。David经常(虽然不总是)想先写一些初始代码,观察它来决定如何编写更多代码,依此类推。即使他们谈论替代方法(例如Kent谈到他不使用TDD的时候),他们仍然总是将观察作为开发过程的内在部分。

可能有人会最小化这一点,说它只与调试或测试相关。确实,它在这些领域很有用,但当你与许多资深开发人员交谈时,你会发现这个想法实际上是他们整个开发工作流程的基本基础。他们希望看到一些能帮助他们做出代码决策的东西。这不仅仅发生在代码完成或有错误时——它发生在软件生命周期的每一刻。

这是一个如此广泛的原则,以至于你可以说所有软件开发的循环是:观察 → 决策 → 行动 → 观察 → 决策 → 行动 → 等等。

如果你想要一个术语,你可以称之为"观察循环"或"ODA"。

示例

我这么说是什么意思?让我们举一些例子来更清楚地说明。当进行TDD时,循环看起来像:

  1. 看到一个 problem(观察)。
  2. 决定解决问题(决策)。
  3. 写一个测试(行动)。
  4. 看测试,看API是否看起来好(观察)。
  5. 如果看起来不好,决定如何修复它(决策),更改测试(行动),并重复观察 → 决策 → 行动,直到你喜欢API的样子。
  6. 现在API看起来不错,运行测试并看到它失败(观察)。
  7. 决定如何使测试通过(决策)。
  8. 写一些代码(行动)。
  9. 运行测试并看到它通过或失败(观察)。
  10. 如果失败,决定如何修复它(决策)并写一些代码(行动),直到测试通过(观察)。
  11. 根据软件设计原则、问题知识或在编写先前代码时获得的数据,决定下一步要做什么(决策)。
  12. 依此类推。

另一种有效的方法是先写代码。与上述序列的区别在于,第3步将是"写一些代码"而不是"写一个测试"。然后你观察代码本身以做出进一步决策,或者在代码之后写测试并观察它们。

有许多有效的流程。

开发流程和生产力

有趣的是,据我所知,每个有效的开发流程都遵循这个循环作为其主要指导原则。甚至像Agile这样覆盖整个团队的大规模流程也内置了这一点。事实上,Agile在某种程度上是试图让团队拥有比之前破碎模型(Waterfall,又名"Big Design Up Front")更短的观察-决策-行动循环(每几周),后者需要数月或数年才能完成一个循环。

因此,较短的循环似乎比较长的循环更好。事实上,开发人员生产力的大部分目标可能仅仅通过将ODA循环缩短到开发人员、团队或组织的最小合理时间段来实现。

通常,你可以通过专注于观察步骤来实现这些较短的循环。一旦你做到了,循环的其他两部分往往会自行加速。(如果没有,还有其他补救措施,但那是另一篇文章。)

观察中有三个关键因素需要解决:

  • 信息传递给开发人员的速度。(例如,拥有快速测试。)
  • 传递给开发人员的信息的完整性。(例如,拥有足够的测试覆盖率。)
  • 传递给开发人员的信息的准确性。(例如,拥有可靠的测试。)

这有助于我们理解近几十年来某些开发工具成功的原因。持续集成、生产监控系统、分析器、调试器、编译器中更好的错误消息、突出显示不良代码的IDE——几乎所有"有效"的东西之所以有效,是因为它使观察更快、更准确或更完整。

有一个陷阱——你必须以人们实际可以接收的方式传递信息。如果你向人们倾倒大量信息而不让他们容易找到他们关心的特定数据,数据就变得无用。如果没有人收到生产警报,那么它就无关紧要。如果开发人员从不确定接收到的信息的准确性,那么他们可能会开始忽略它。你必须成功传达信息,而不仅仅是生成它。

第一个ODA

有一个"大ODA循环"代表软件开发的整个过程——看到一个 problem,决定一个解决方案,并将其作为软件交付。在那个大循环中,有许多较小的循环(看到对一个功能的需求,决定功能应该如何工作,然后编写功能)。其中还有更小的循环(观察单个更改的需求,决定一个实现,写一些代码),依此类推。

最棘手的部分是任何这些序列中的第一个ODA循环,因为你必须在没有先前决策或行动的情况下进行观察。

对于"大"循环,似乎你开始时没有什么可观察的。还没有代码或计算机输出可看!但实际上,你至少可以从观察自己开始。你有周围的环境。你有其他人可以交谈,有一个世界可以探索。你的第一次观察通常不是代码,而是现实世界中需要解决的、以某种方式帮助人们的东西。

然后,当你进行开发时,有时你会遇到一个点,你必须决定"下一步我该做什么?“这就是了解软件设计法则可以帮助的地方,因为你可以将它们应用于你编写的代码和你观察到的问题,这让你决定工作的顺序。你可以将这些原则视为一种二手观察形式——数千人年的经验压缩成法则和规则,可以帮助你现在做出决策。只要准确,二手观察是完全有效的观察。

你甚至可以将观察过程本身视为它自己的小ODA循环:看世界,决定将注意力放在某件事上,将注意力放在那件事上,观察它,基于此决定观察其他东西,等等。

可能有无穷无尽的方式使用这个原则;以上所有内容仅代表几个例子。

-Max

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计