测试 - >代码 - >重构,我们什么时候开始重构?

时间:2009-08-30 22:33:55

标签: refactoring tdd

TDD圈子是:

"Write failing Test" -> "Write Code to fit a Test" -> "Refactor"

在“编码”步骤中,我们假设编写代码尽可能简单,只是为了修复失败的测试。在真正需要之前,我们不应该编写复杂的代码。

下一步是Refactor。我们应该重构只是编写的代码吗?我认为没有真正的意义,因为我们应该对代码感到满意,因为测试正在通过。

可能某些事情会强制重构活动,例如代码编写是由失败的测试引起的。这里有一些可能的因素:

  1. 下一个要编写的测试需要对系统进行一些更改(重构)
  2. 表现不好。我们需要在不破坏功能的情况下改进它
  3. 代码审查显示编写的代码很难理解。
  4. 您认为开始重构的其他原因是什么?

    此外,这个方案是否正确:

    "Write failing Test" -> "Code" -> "Refactor" -> "Write failing Test"
    

    或者可能应该被视为

    "Write failing Test" -> "Code/Refactor" -> "Write failing Test"
    +
    "External factor (like bad performance)" -> "Refactor".
    

6 个答案:

答案 0 :(得分:9)

你可以写一些非常难看的代码,同时让测试通过;重构现在不是因为它不起作用,但它不是很容易维护。这是重点。

在编写代码以适应多个测试之后,您可以开始更大幅度地看一下这些代码片段之间是否存在重叠,您可以在哪些部分进行重复分析?

答案 1 :(得分:5)

TDD是一个很好的工具,可以帮助您保持正常/完成任务。问题:

  

“写入失败测试” - > “代码/重构” - > “写失败的测试”

你建议,是否可以很容易地成为:

  

“写入失败测试” - > “重构” - > “代码” - > “写失败的测试”

或者

  

“写入失败测试” - > “重构” - > “重构” - > “重构” - > “代码” - > “写失败的测试”

这是你想要避免的。通过在实现开始时进行重构,您沉迷于投机开发,而不是实现编码会话的目标。可以轻松地切断切线并构建您不一定需要的东西。如果您正在使用该功能并通过测试,则可以更轻松地确定何时是停止重构的正确时间。而且你可以随时停止,因为你的测试正在通过。

此外,当您的测试不是绿色时,您不想重构。

其他几个小点:

  1. 我认为大多数文献对重构的定义略有不同。这不是“对系统的某些更改”或性能增强,而是具体的更改不会改变行为但会改进设计。如果您接受该定义,那么性能改进并不真正符合要求:它们是需要自己的验收测试的正常开发任务。我通常会尝试将这些作为面向最终用户的故事构建,这样做的好处是明确的。有道理吗?

  2. 我认为你是正确的,TDD实践没有专门解决代码审查期间发现的设计问题。 (对于其他解决方案,请参见反思和结对编程。)这些往往是更大的,跨层次的问题,建立为“代码债务”,并且需要花一些时间定期清理它。这可能是一个单独的项目,但我个人总是喜欢将此作为另一个“真实”故事的一部分。上次我这样做,我们发现我们遇到了问题,但最后等了几个星期,直到我们有一个相关的故事来处理它。我们首先遵循TDD实施新功能的做法 - 即使我们知道这是错误的。但后来我们真正理解了发生了什么以及为什么它变得混乱,然后在重构阶段花费的时间比平时长。工作得很好。

答案 2 :(得分:1)

嗯......我通常认为这些“外部”重构与TDD周期本身是分开的。在使用TDD完成特征XYZ之后,应该有一组健康的测试,以防止通过重构引入错误(假设代码覆盖是最佳的,等等)。性能瓶颈和难以理解的代码通常会在事后发生,因此我认为在那时进行重构是理想的。您可以提高性能,使代码更易于理解,并在使用测试时执行其他任何需要执行的操作,以确保您不会将错误引入系统。

所以为了回答你的问题,我不相信外部重构符合TDD模式,虽然标识符(如果你愿意,代码闻起来)绝对是你在开发代码时要跟踪的项目。

答案 3 :(得分:1)

除了由于需要提高性能而引发的重构之外,我通常会注意到在编写代码时将测试传递给我可以共享代码的地方或者更好,更优雅的方式来完成某些事情。此时,您完成代码以通过测试,确保所有测试都通过,然后返回并进行重构。这可能会或可能不会涉及您编写的确切代码,很可能会涉及,但它可能是您在编写新代码时注意到的。

有时候我会注意到可以重构的东西,但是决定我现在正在做的事情更重要。那时我会注意到稍后重构的问题。最终,重构将变得比下一个特征更重要,它将在红色/绿色/重构循环的重构阶段完成。在这种情况下,它可能与我刚刚开展的工作无关。

答案 4 :(得分:1)

在主要版本发布之前的一周或两周内,重构是不是很糟糕?

答案 5 :(得分:0)

三条规则:

  1. 当你第一次做某事时,就完成它。

  2. 当你第二次做类似事情的时候,不得不重复一遍,但不管怎么说都要做同样的事情。

  3. 当你第三次做某事时,开始重构。

  4. 添加功能时:

    1. 重构有助于您了解其他人的代码。如果你必须处理其他人的脏代码,请先尝试重构它。清洁代码更容易掌握。你不仅要为自己而且要为那些在你之后使用它的人改进它。

    2. 重构可以更轻松地添加新功能。更改清洁代码要容易得多。

    3. 修复错误时:

      1. 代码中的错误与现实生活中的错误一样:它们生活在代码中最黑暗,最脏的地方。清理你的代码,错误实际上会发现自己。

      2. 管理员欣赏主动重构,因为它可以在以后消除对特殊重构任务的需求。快乐的老板让快乐的程序员快乐!

      3. 在代码审核期间:

        1. 代码审核可能是在公众可​​以使用代码之前整理代码的最后机会。

        2. 与作者成对进行此类评论最佳。通过这种方式,您可以快速解决简单问题,并确定修复更困难问题的时间。