创建易于维护的测试

时间:2012-08-22 01:34:44

标签: unit-testing testing mocking bdd

在关于为我们的项目实施单元测试的提议中,我的经理认为创建单元测试可能会更昂贵,因为您将维护两组代码。他的论点是,只要需求/功能发生变化,单元测试就可以过时,因此开发人员应该更新测试以通过自动构建。他说这对开发人员来说可能不方便,因为他们的编码时间可能会减少,并且花在修复测试上。

我想实现单元测试的原因是在将代码转向验证团队进行功能测试之前,最大限度地减少错误发生,特别是关键问题。我还相信,通过提供更好的质量系统,可以恢复创建单元测试的成本。

现在,他对我的挑战是创建易于维护的易于修改的测试,或者如果可能的话,测试不会轻易破坏。我正在使用像JUnit这样的xUnit测试框架和像mockito和powermock这样的模拟框架来帮助测试。

我正在寻找有关如何编写易于维护测试或如何避免脆弱测试的技巧和技巧。是否有其他工具可以在创建此类测试时派上用场。我正在用Java和C ++编写代码。感谢。

5 个答案:

答案 0 :(得分:4)

我认为你面临的文化差异 - 你的经理担心测试提供的潜在时间。众所周知,TDD / BDD过程在前期更加昂贵 - 但随着时间的推移,你开始获得奖励,因为“改变这一个孤立的东西......” - 不再引起痛苦/尴尬/ 代价高昂错误。

我的建议是,你做一些研究并整理一份文件,试图将这个过程卖给你的经理,根据你业务中发生的事情提出一个商业案例,这个案例可能/本来可以用一个坚实的方法来解决测试套件。

TDD中有一本书比我见过的任何网站,文章等都要好。对于想要练习TDD / BDD / OOP的人,我强烈建议阅读: http://www.growing-object-oriented-software.com/(我没有通过链接来获得任何收益! - 但它是我办公桌上的一个极好的补充!)。

答案 1 :(得分:2)

根据我的经验,几乎不可能真正说服“单位测试怀疑论者”。

我的建议:开始添加测试并增加对产品中最重要且经常变化的部分的选择范围。在你自己的时间做这件事,可能还有“帮凶”,并为你的工作安排时间。

之后,展示这些测试所捕获的回归错误的怀疑论者示例,以及您花费的时间实际上是值得的。如果您成功这样做,管理层将看到为单元测试投入资源的价值。

根据技术挑战,我同意其他答案,即练习是完美的,但有一些指导方针可以帮助您:

  • 每次测试只测试一件事。如果你有100个断言相同条件的测试,当这个条件改变时,你将不得不更新100个测试。
  • 如果你的“被测试的课程”很庞大,其中有很多逻辑,就很难对它进行测试。尝试将您的类重构为小的,连贯的逻辑单元。当其中一个单位发生变化时,破损测试的数量将相对较少。
  • 测试您的公共接口,而不是实现细节。这将允许开发人员修复错误,提高性能和重构,对测试的影响最小。

Google的“单元测试指南”的第一页上有很多more guidelines,您可以阅读The Art Of Unit Testing,了解有关编写良好单元测试的详细信息。

祝你好运!

答案 2 :(得分:1)

您是否编写单元测试不应该与您的管理层有关。通常重要的是功能快速实现且没有错误。如何实现它取决于你,开发人员;单元测试只是一种方法。它最适合松散耦合的代码,您可以轻松地模拟依赖项。

但是编写好的单元测试不仅仅是决定编写它们,还是你使用的工具,它主要是关于只有通过练习才能获得的经验。没有简单的配方可以让你编写好的单元测试,因为没有代码。如果你只是强迫没有经验的人来编写单元测试,那么生产力肯定会下降,并且没有明显的好处。最终,您应该编写单元测试,因为您认为它可以帮助您,而不是因为其他人认为它应该对您有所帮助。

答案 3 :(得分:0)

答案是单元测试应该测试实现而不是功能。因此,如果开发人员重构代码,那么单元测试不会改变任何东西,因为他们没有测试内部结构,只测试结果。

当然,如果你彻底改变界面或行为,当然测试会改变,但是你会想要测试新的代码,所以你仍然在编写测试。

长话短说,有很多研究表明,一个好的测试套件从长远来看可以节省大量时间。

答案 4 :(得分:0)

如果系统测试发生变化,统一 test-datafactories 可能会降低维护成本。

offten具有类似的测试设置,只有很小的变化。

当我开始进行单元测试时,我使用了copy& paste来从现有的测试中创建一个新的测试。

每个测试都有很长的测试设置。

在测试系统发生变化后,我不得不更新许多测试。

今天我使用test-datafactories,其中只分配了与标准的差异。

例如

  void customerUnder18ShouldNotbeGrantedAccess() {
      // Arrange
      Customer customer = TestdataFactory.CreateStandardCustomer();
      customer.setAge(16);

      // Act...
      // Assert ..
  }

Here是更有用的提示。