在JUnit中设置测试的成本 - 使用模拟对象与遗留代码中的存储库测试

时间:2018-06-08 08:24:57

标签: java unit-testing junit mocking mockito

我在一个已存在多年的项目上工作。使用所有测试构建项目所需的时间几乎是耸人听闻的(不是很好)。这主要是由于许多模块以及大量的单元测试,它们使用存储库来设置测试数据,而不是模拟所需的行为。使用存储库的单元测试会花费大量时间进行测试设置,并且运行速度非常慢。由于系统非常庞大,这会增加很多时间。

我们使用Mockito来模拟存储库来编写所有新的单元测试(除非我们实际上显然测试了存储库)。我们还尝试重写所有现有的单元测试,以便在我们有时间和机会时使用存储库的模拟而不是实际的存储库。完全取消在我们的测试中使用repo会对运行测试所花费的时间产生巨大的效果。

许多遗留代码通过使用构建器和测试实用程序来设置其测试数据,而构建器和测试实用程序又使用存储库。由于域非常复杂,这通常涉及设置相当数量的对象以及它们如何相互关联。因此,仅使用模拟对象重写一类测试(比如~15次测试)可能非常耗时。和其他地方一样,时间不是无限的资源。

如果我们要为类添加一些新功能,那么编写一个新的存储库测试(除了现有的15)要比通过使用确切地确定如何设置测试数据要容易得多不同的模拟对象。

我试图找到一些关于测试设置如何以及在多大程度上影响运行测试的实际时间的信息,但我找不到任何有用的信息。我唯一的事实"是我在运行测试类时所做的观察。回购测试的测试设置可能需要大约10秒,而模拟测试类的测试设置在不到一秒的时间内开始。

注意:我知道我可以使用JUnit秒表对单个或一组测试进行基准测试,但我的问题更关注的是最佳实践,而不是我运行测试需要多长时间。

我有两个问题:

  1. 假设我遇到一个已经有15个单元测试的测试类,其中没有一个模拟任何行为。我写了一个测试并在课堂上做了一个小修复。我没有时间将整个测试类重写为模拟对象。我是否应该添加一个新测试而不模仿任何行为并遵循现有(和坏)模式?我是否有15次非模拟测试和1次模拟测试,或者我是否有16次非模拟测试真的很重要吗?

  2. 在我的15个单元测试的测试类中,有些测试比其他测试更容易重构。仅使用模拟对象重新编写五个测试是否值得?是否违反最佳做法或以任何其他方式进行测试,其中某些测试使用模拟而某些测试不是很好?

2 个答案:

答案 0 :(得分:1)

你的问题确实很主观,但我会尝试提出一些你可以探索的选择。这一切都取决于你愿意花多少钱。

  

我是否应该在不模仿任何行为的情况下添加新测试并遵循现有(和不良)模式?我是否有15次非模拟测试和1次模拟测试,或者我是否有16次非模拟测试真的很重要吗?

它不仅仅是一个新的测试。如果您仍然以糟糕/缓慢的方式写作,那么您只是在增加技术债务。您自己要列出编写新单元测试的最佳实践。

  

在我的15个单元测试的测试类中,一些测试更容易   重构比其他人。重写只有五个是否值得   测试使用模拟对象?

绝对。为什么不?您可以通过遵循更新的代码风格来说明您所获得的改进。

  

是否违反最佳做法或以任何其他方式不合适   测试类,其中一些测试使用模拟而一些测试不合适?   一个最佳实践是在任何地方都有一致的代码。对于最佳实践而言,旧式存储库和较新的存储库与模拟的混合并不是很好。但是如果您编写的代码没有完全覆盖单元测试,那么我会更加担心,无论风格如何。

在一天结束时,您决定并考虑所有权衡,例如您可以通过较新的模拟存储库实现的构建时间改进,构建的频率是多少,以及可以这可以通过硬件改进和其他因素来实现。

答案 1 :(得分:1)

正如@ShanuGupta所写,对你的问题没有一般性答案。

但这是我的想法:

正确性之后可读性是第二个最理想的代码值,尤其是测试代码(因为它是可执行规范

另一方面,没有规则单位不能有多个Test类。因此,我要分开旧的"测试方法不使用"模拟"将它们放在不同的测试类中进行测试。

相关问题