当您要将一些新功能添加到具有几乎* NO *单元测试代码的大型(和脏)代码库时,您会怎么做?

时间:2008-10-07 15:21:32

标签: unit-testing testing refactoring

Martin Fowler说我们应该在添加新功能之前进行重构(假设原始程序结构不合理)。

所以我们都想重构这个 dirty 代码库,这是肯定的。我们也知道,如果没有单元测试代码,就很容易引入细微的错误。

但这是一个很大的代码库。添加一整套测试似乎是不切实际的。

在这种情况下你会做什么?

14 个答案:

答案 0 :(得分:14)

我的建议是尽可能少地触摸并添加你需要的东西。我发现最好单独留下,特别是如果你的时间紧迫。

如果您进行了单元测试,那将是一个不同的故事,但是当您更改代码时,它可能就像触摸蜘蛛网一样。改变一件事可能会影响其他一切。

答案 1 :(得分:11)

让我推荐Michael Feathers的书Working effectively with legacy code。它包含许多实际示例,并展示了处理遗留代码野兽的良好技术。

答案 2 :(得分:10)

将单元测试添加到您要重构的代码中。

答案 3 :(得分:9)

请参阅Rands in Repose's Trickle Theory,了解他遇到大量漏洞时遇到的类似问题。他的建议是:

  

我的建议是:START

答案 4 :(得分:5)

如果单位测试不存在或者在给定的时间范围内添加适当的覆盖率非常困难,那么您将不得不依赖于常规测试。从理论上讲,你所谈论的这个庞大而肮脏的代码库已被认为适合现在使用一段时间了。为了做出这个决定,有程序员测试,QA测试或客户进行的某种测试。你想知道它是如何完成的,做了什么,如果它足以涵盖你将做出什么改变,然后得到承诺再次完成,再加上新代码需要的任何测试,直到产品好够了。

单元测试对于程序员来说是一项很棒的服务,但它们并不是那种唯一的测试方式。

答案 5 :(得分:3)

不要将其视为或/或命题。通过添加单元测试可以增加价值 - 您无需添加整个套件即可获得添加某些测试的好处。

答案 6 :(得分:3)

我经常发现自己处于这种情况,因为这几乎是我在过去两年中一直坚持的原因。

正确的方法实际上取决于社会和组织方面,而不是技术方面。您的工作是为您的组织创造价值。如果重构会产生超过其成本的价值,那么您应该能够出售它。就我而言,关键因素包括:

  1. 相关项目的预期所有权。 如果您希望在可预见的未来成为这一特定软件的重要利益相关者,那么这是一个支持对不良代码库进行更广泛修改的论据b / c它会在您继续维护它时获得更多回报。如果您要添加偷渡式功能,请采用更轻松的方法。

  2. 正在进行更改的复杂性。 如果你对代码库进行了非常复杂的更改(在“脏”代码库中的典型情况,那么b / c这样的源通常是紧密耦合和不连贯的),更有可能需要进行一些重构。这些变化也不是成为代码忍者的结果,因为它们对于您只是推理关于您所做的更改是必要的。这也与您正在修改的代码库的“不良”有关。对于紧密耦合,不连贯的混乱,甚至最简单的单元测试几乎是不可能的。 (我从经验中说。我几乎被卡住的项目之一是大约20k行,不包括生成的代码,在12个文件中。整个应用程序是一个名为“Form1”的类。这是一个滥用部分类功能。)

  3. 组织监督。 您组织的监督的力量和严格性在这里发挥作用。如果你的小组实际上执行了一些核心的最佳实践,例如代码审查,并且不仅仅是为他们提供口头服务,那么我更倾向于不进行大量的重构。值得权衡可能更有利于尽可能少地触摸因为你有另外一双新眼睛检查以确保你所做的少数变化都没有产生不良副作用。同样,更严格的监督更有可能对“游击队”代码策略不屑一顾,即在变更请求中进行非严格调用的更改。

  4. 你的老板。如果你的老板站在你的一边,你就更有可能在你的代码库上做出长期的价值改进,特别是如果你可以证明这一点现在预算小时数增加了成本。请记住,您的经理对此软件在大局中的角色有了比您更好的视角。如果它是一个仅供十人或二十人使用的软件,它就不会要求一两个人使用的软件所需的长期维护改进。

    < / LI>

    在考虑任何类似的时间投资时,您需要回答的核心问题是“价值在哪里?”然后你需要追逐那个价值。

答案 7 :(得分:2)

首先,为您要更改的部分添加测试。其次,重构代码,直到对理智的人有意义为止。第三,进行必要的修改。

答案 8 :(得分:2)

很多都取决于你的语言。如果你使用静态类型语言,你可能会在没有单元测试的情况下离开。我做过很多工作,完全按照你所描述的那样工作。

如果这是一项大量的工作(比方说,一个男人一年或3个人,为期4个月),那么你可能想让某人撕掉代码并先分析它。

如果它是一种动态语言,它会更成问题 - 你需要一定程度的单元测试。也许您可以将单元测试添加到需要触摸的区域。

我只区分静态和动态语言,因为在静态类型语言中进行重构要容易得多 - 它们往往更容易预测。我不讨厌Ruby或其他任何东西 - 我也花了一年时间研究ROR。我只是认为他们需要不同的方法。

答案 9 :(得分:2)

福勒还建议你不要在没有测试安全的情况下进行重构。但是,你如何进行这些测试呢?而且,你走了多远?

以前推荐的书(Michael Feathers的Working Effectively with Legacy Code)是关于这个主题的权威性着作。

需要更快阅读吗?看看迈克尔早先的同名article (PDF)

答案 10 :(得分:1)

你必须从某个地方开始。您可以首先添加测试,然后在移动时构建测试套件。即使你有一些“愚蠢”的测试,除了告诉你,你只是能够测试代码的某些部分告诉你一些事情。

答案 11 :(得分:1)

如果添加一套测试是不切实际的,那么代码库就会出现严重问题。

添加新代码和希望它Just Works是不好的。

编写测试,重构基础并添加新代码。如果你无法测试它,你永远不会知道它是否正确。

答案 12 :(得分:0)

尽可能少地触摸。并祈祷。

答案 13 :(得分:0)

我同意其他人的意见,尽量少触摸。 但是,您也可以随时开始编写单元测试,以获得您将要触及的新功能和/或现有功能。没有人说你需要编写单元测试来测试100%的现有代码库。