代码之家  ›  专栏  ›  技术社区  ›  abyx

如何测试/更改未测试和不稳定的代码?

  •  9
  • abyx  · 技术社区  · 16 年前


    在进行更改之前,我想编写测试,但是每个类都创建了很多依赖项和其他反模式,这使得测试非常困难。

    你会这样做吗?或者,您是否会花费大量时间编写难以编写的测试,这些测试将在重构完成后大部分被删除?

    4 回复  |  直到 9 年前
        1
  •  6
  •   Mike Stone    16 年前

    首先 here's a great article with tips on unit testing . 其次,我发现了一个避免在旧代码中进行大量更改的好方法,就是只需对其进行一点重构,直到您可以对其进行测试。一种简单的方法是保护私有成员,然后覆盖受保护字段。

    例如,假设您有一个类,该类在构造函数期间从数据库加载一些内容。在这种情况下,您不能只重写受保护的方法,而是可以将DB逻辑提取到受保护的字段,然后在测试中重写它。

    public class MyClass {
        public MyClass() {
            // undesirable DB logic
        }
    }
    

    变成

    public class MyClass {
        public MyClass() {
            loadFromDB();
        }
    
        protected void loadFromDB() {
            // undesirable DB logic
        }
    }
    

    然后你的测试看起来像这样:

    public class MyClassTest {
        public void testSomething() {
            MyClass myClass = new MyClassWrapper();
            // test it
        }
    
        private static class MyClassWrapper extends MyClass {
            @Override
            protected void loadFromDB() {
                // some mock logic
            }
        }
    }
    

    但是,如果您正在编写框架,我建议您不要使用此解决方案,除非您真的不介意将成员暴露给框架的用户。

    这有点像黑客,但我发现它很有用。

        2
  •  3
  •   Mike Stone    16 年前

    我不同意你关于测试不应该破坏构建的说法。测试应该表明应用程序没有为测试的功能引入新的bug(而发现的bug则表明缺少测试)。

    如果测试没有破坏构建,那么您很容易就会遇到这样的情况:新代码破坏了构建,并且它在一段时间内是未知的,即使测试覆盖了它。失败的测试应该是一个危险信号,表明测试或代码必须修复。

    此外,允许测试不破坏构建将导致失败率缓慢上升,直至不再有可靠的回归测试集。

    如果测试经常中断存在问题,则可能表明测试的编写方式过于脆弱(依赖于可能更改的资源,例如数据库没有正确使用DB单元,或者应该模拟的外部web服务),或者,这可能表明团队中有一些开发人员没有给予测试适当的关注。

        3
  •  0
  •   Valters Vingolds jpkroehling    16 年前

    我不知道为什么你会说一旦重构完成,单元测试就会被删除。实际上,单元测试套件应该在主构建之后运行(您可以创建一个单独的“测试”构建,它只在主产品构建之后运行单元测试)。然后,您将立即看到一个部件中的更改是否破坏了其他子系统中的测试。请注意,它与在构建过程中运行测试有点不同(正如一些人可能提倡的那样)-一些有限的测试在构建过程中是有用的,但通常仅仅因为某些单元测试失败而“崩溃”构建是徒劳的。

    如果您正在编写Java(很有可能),请查看 http://www.easymock.org/ -可能有助于减少用于测试目的的耦合。

        4
  •  0
  •   Ced-le-pingouin    16 年前

    我已经阅读过如何有效地处理遗留代码,我同意这对于处理“不稳定”的代码非常有用。

    我应该提到的是,我没有从这本书的编辑或作者那里收到任何钱;),但我发现它非常有趣,因为在遗留代码领域缺乏资源(特别是在我的语言法语中,但这是另一回事)。