红色,绿色,重构 - 为什么重构?

mik*_*kew 13 testing tdd refactoring unit-testing

我正在尝试学习TDD和单元测试概念,我已经看到了口头禅:"红色,绿色,重构".我很好奇你为什么要在测试通过后重构你的代码?

这对我来说没有意义,因为如果测试通过,那你为什么要搞乱代码呢?我也看到TDD咒语就像"只编写足够的代码来使测试通过".

我能提出的唯一原因是,如果要使测试通过绿色,你只是粗略地编写任何旧代码.你只是破解了一个通过测试的解决方案.显然代码很乱,所以你可以清理它.

编辑:

我在另一个stackoverflow帖子上找到了这个链接,我认为这证实了我提出的唯一原因,即"通过"测试的原始代码可以非常简单,甚至是硬编码:http://blog.extracheese.org/2009/ 11/how_i_started_tdd.html

Pét*_*rök 28

通常,代码的第一个工作版本 - 即使不是一团糟 - 仍然可以改进.所以你改进它,使它更清晰,更易读,删除重复,找到更好的变量/方法名称等.这是重构.而且由于你有测试,你可以安全地重构,因为测试将显示你是否无意中破坏了某些东西.

请注意,通常您不是从头开始编写代码,而是修改/扩展现有代码以添加/更改功能.并且现有代码可能无法准备好无缝地适应新功能.因此,新功能的首次实现可能看起来很笨拙或不方便,或者您可能会发现很难进一步扩展.因此,您可以改进设计,以最简单,最干净的方式整合所有现有功能,同时仍然通过所有测试.

你的问题是对旧时代的改变"如果它有效,就不要修复它".但是,正如Martin Fowler在Refactoring中解释的那样,代码可以通过许多不同的方式被打破.即使它通过了所有测试,也很难理解,因此难以扩展和维护.此外,如果它看起来很草率,未来的程序员将更加小心地保持它整洁,因此它会更快地恶化,并最终降级为完全无法维护的混乱.为了防止这种情况,我们重构以尽可能保持代码干净整洁.如果我们(或我们的前任)已经让它变得混乱,重构是一项巨大的努力,对管理层和利益相关者没有明显的直接好处; 因此,他们很难说服在实践中支持大规模的重构.因此,在每次代码更改后,我们都会以小的,甚至是微不足道的步骤进行重构.

  • 哈哈:TDD stackoverflow回答?重构重构重构....绿色蜱! (7认同)

Mar*_*tus 6

很难看出 OP 的怀疑是如何不合理的。TDD 的工作流程植根于避免过早的设计决策,通过强加高昂的成本(如果不是排除的话)可能会迅速演变为不明智的 YAGNI safari 的“靠山”编码。[1]

这种推迟过早设计的机制是“最小可能的测试”/“最小可能的代码”工作流程,旨在避免在通常需要解决甚至遇到之前“修复”感知缺陷或需求的诱惑,即,可能会(应该?)在某些未来的测试用例中解决直接映射到验收标准的缺点,该标准反过来捕获特定的业务目标。

此外,TDD 中的测试应该 a) 帮助澄清设计要求,b) 表面问题的设计 [2],以及 c) 作为项目资产,捕获和记录应用于特定故事的工作,因此替代自我为正确组合的测试进行定向重构工作不仅排除了测试可能提供的任何洞察力,而且还拒绝了管理人员和项目规划人员有关实施特定功能的真实成本的信息。 [3]

因此,我建议一个新的测试用例,专门为在设计中引入额外的需求而构建,是解决除了对当前被测代码的风格变化和“重构”阶段之外的任何感知缺陷的正确方法出于好意,与这种理念背道而驰,实际上是在邀请进行 TDD 应该阻止的那种过早的 YAGNI 设计之旅。我相信罗伯特·马丁对 3 条规则的版本与这种解释是一致的。[4 - 公然诉诸权威]


[1] 之前引用的http://blog.extracheese.org/2009/11/how_i_started_tdd.html优雅地展示了将设计决策推迟到最后一刻的价值。(虽然斐波那契数列可能是一个有点人为的例子)。

[2] 见https://blog.thecodewhisperer.com/permalink/how-a-smell-in-the-tests-points-to-a-risk-in-the-design

[3] 在 backlog 中添加“技术”或“尖峰”故事(气味与否)将是确保遵循正式流程并记录开发工作并证明其合理性的适当方法......如果你不能说服产品负责人添加它,那么你不应该在它上面浪费时间。

[4] http://www.butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd


Jav*_*ier 5

我看过口头禅:"红色,绿色,重构."

这不是一个"口头禅",这是一个例行公事.

我也看到TDD咒语就像"只编写足够的代码来使测试通过".

这是一个指导方针.

现在你的问题:

我能提出的唯一原因是,如果要使测试通过绿色,你只是粗略地编写任何旧代码.你只是破解了一个通过测试的解决方案.显然代码很乱,所以你可以清理它.

你快到了.关键在于TDD的"设计"部分.您不仅要编码,还在设计解决方案.这意味着确切的API可能不会一成不变,并且您的测试可能无法反映最终设计(因为它还没有完成).虽然编码"只够通过测试",但您会遇到一些可能改变主意并指导设计的问题.只有在你有一些工作代码后,你才能改进它.

此外,重构步骤涉及整个代码,而不仅仅是您刚刚编写的代码以通过最后一次测试.随着编码的进步,代码的所有部分之间的交互越来越复杂,重构它的最佳时间就是它的工作.

正是因为这个非常早期的重构步骤,您不必担心第一次迭代的质量.它只是一个有助于设计的概念证明.

  • 当然这是一个口头禅.一个例行公事和一个实践. (2认同)