你什么时候达到单位测试过度杀伤?

时间:2010-01-23 08:08:17

标签: unit-testing

我目前正在开展一个项目,在那里我使用NUnit进行单元测试,使用Moq进行模拟,使用MSpec编写规范并使用WebAii测试UI。

虽然我在享受整体体验并充分了解测试的内容和方法,但我还是想知道这四种工具是否有点落伍。

单元测试是否有点荒谬?有可能过头了吗?在你看来,什么是合理的测试和什么 - 只是不必要的细节?

修改
要明确的是,我所写的测试数量并不是因为它是我正在使用的工具的广度。四个似乎很多,但如果其他人使用这种阵容效果良好,我想听听它。

5 个答案:

答案 0 :(得分:29)

可以一次使用多个测试框架吗?

一些开源软件项目确实使用了多个测试框架。一个常见的设置是使用单元测试框架和模拟框架,如果项目的开发人员不想自己进行模拟。

那么你何时到达单位测试矫枉过正

您可以快速完成单元测试“overkill”,您可能已经达到了它。一般来说,有几种方法可以过度测试,这会破坏TDDBDDADD以及您使用的任何驱动方法的目的。这是其中之一:

当您开始编写其他类型的测试时,就会达到单元测试过度杀伤,就好像它们是单元测试一样。这应该通过使用模拟框架(测试仅隔离到一个类的交互)和规范框架(测试功能和指定的需求)来修复。许多开发人员之间存在混淆,他们认为以同样的方式处理所有不同类型的测试是个好主意,这会导致一些脏混合

尽管TDD专注于单元测试,但您仍然会发现自己正在编写功能,集成和性能测试。但是你必须提醒自己,范围与单元测试有很大差异这就是为什么有许多测试工具可用,因为有不同类型的测试。使用许多测试框架没有任何问题,并且大多数测试框架彼此兼容。

因此,在编写单元测试时,在编写测试时需要考虑couple of sweet spots

unit test                 dirty hybrids               integration test
---------                 -------------               ----------------
* isolated                                            * using many classes 
* well defined                  |                     * tests a larger feature
* repeatable                    |                     * tests a data set
                                |
    |                           |                              |
    |                           |                              |
    v                           v                              v

    O  <-----------------------------------------------------> O 

    ^                           ^                              ^
    |                           |                              |

sweet spot              world full of pain                sweet spot

单元测试很容易编写,你想写很多。但是如果你编写一个具有太多依赖关系的测试,一旦需求开始改变,你将会得到很多工作。当代码在具有太多依赖关系的单元测试中断时,您必须检查许多类的代码而不是一个且只有一个类。这意味着您必须检查其所有依赖关系,以查看问题所在,这在TDD意义上违背了单元测试的目的。在一个大型项目中,这将是非常耗时的。

这个故事的寓意是,不要将单元测试与集成测试混淆。因为简单地说:他们是不同的。这并不是说其他​​类型的测试很糟糕,但是应该将它们视为规范或健全性检查。仅仅因为测试中断,它们可能不是代码错误的指示。例如:

  • 如果集成测试中断,则可能存在某些要求的问题,您需要修改要求,删除,替换或修改测试。
  • 如果性能测试中断,取决于它的实现方式,该测试的随机性可能会让您认为它在该实例上运行缓慢。

唯一要记住的是以易于区分和发现的方式组织测试。

您是否需要一直编写测试?

有时可以省略测试用例,因为通过手动smoke testing进行验证更容易,而且不需要花费很多时间。在这种意义上,手动烟雾测试是您启动应用程序以自行测试功能或未编码您的东西的其他人的操作。也就是说,如果您要编写的自动化测试是所有以下内容:

  • 方式过于复杂和错综复杂
  • 将花费大量的工作时间来撰写
  • 没有现成且易于使用的测试框架来处理它
  • 不会给予很多回报,例如回归几乎没有机会
  • 可以手动完成,而且比编写自动化测试要少得多。

...然后编写它并将其作为手动测试用例进行测试。如果测试用例需要几天的时间来编写,那么手动测试只需要一分钟的时间就不值得。

答案 1 :(得分:4)

如果你一遍又一遍地测试相同的输入,那你就太过分了。

只要每个新的测试用例测试不同的东西,你就可以了。

当然,你会很快找到错误。还有一些难以察觉的罕见和有线案例。你必须问自己,如果这个bug出现在生产中会有多贵,并将其与你在生产之前找到它的价格进行比较。

我经常测试边界。如果我写了一个fibunacci函数,我会测试它的整数值-1,0,1,10和Maxvalue。测试20或509不会测试任何尚未涵盖的内容。

答案 2 :(得分:3)

如果你浪费了更多的时间进行测试,而不是编码,那么你可能会过度使用它。但那是我个人的看法。您可能会感兴趣的是,将测试驱动开发看作是开始测试的一种很好的方法,确保您将编写您需要的代码,并且您将编写它应该工作的代码({ {3}})

祝你好运!

答案 3 :(得分:2)

没有超越的东西!当然,你不想这样做。给出方法

public void tripleInt(int i);

你不想测试无限数量的整数。这不切实际。你可能想测试积极的,消极的,Integer.Max等。

答案 4 :(得分:0)

编写高度精细的单元测试有时候会过度。

单元测试的重点是:

  1. 测试给定单元A的代表性输入集(如果一个单元测试包含单元A的较大单元B,则可能认为作为单元B的代表的输入集将不会导致单位A)的代表性输入集。
  2. 确定代码中断的最大精度。
  3. 但是如果你有一个更大的单元包含几个小单元,那么对于较大的单元,你有一组输入,这导致代表性的输入组也适用于较小的单元,并具有如下特征:如果较大的单元中断,很容易确定断点的确切位置,没有理由为每个较小的单位编写单元测试。