我知道所谓的单元测试和集成测试的教科书定义。我好奇的是什么时候该写单元测试了……我将写它们来覆盖尽可能多的类集。

例如,如果我有一个Word类,我将为Word类编写一些单元测试。然后,我开始编写我的Sentence类,当它需要与Word类交互时,我经常会编写单元测试,这样它们就可以同时测试Sentence和Word……至少在他们相互作用的地方。

这些测试本质上变成集成测试了吗?因为它们现在测试这两个类的集成,还是仅仅是一个跨越两个类的单元测试?

一般来说,由于这条不确定的界线,我很少实际编写集成测试……或者我是否使用成品来查看所有部件是否正常工作,即实际的集成测试,即使它们是手动的,并且很少在每个单独的功能范围之外重复?

我是否误解了集成测试,或者集成测试和单元测试之间真的只有很小的区别?


当前回答

这些测试本质上变成集成测试了吗?因为它们现在测试的是这两个类的集成?或者它只是一个跨越2个类的单元测试?

我认为是和是。跨越2个类的单元测试变成了集成测试。

您可以通过使用mock实现(MockWord类)测试Sentence类来避免这种情况,当系统的这些部分足够大,可以由不同的开发人员实现时,这一点非常重要。在这种情况下,Word是单独的单元测试,句子是在MockWord的帮助下进行单元测试,然后句子是用Word进行集成测试。

以下是真实差异的例子 1) 1,000,000个元素的数组很容易进行单元测试,工作良好。 2) BubbleSort很容易在10个元素的模拟数组上进行单元测试,而且工作得很好 3)集成测试表明有些东西不是很好。

如果这些部分是由一个人开发的,在单元测试BubbleSoft时很可能会发现问题,因为开发人员已经有了真实的数组,他不需要模拟实现。

其他回答

我的10位:D

我总是被告知单元测试是对单个组件的测试——应该充分地进行测试。现在,这往往有很多层次,因为大多数组件是由较小的部件组成的。对我来说,单元是系统的功能部分。所以它必须提供一些有价值的东西(例如,不是字符串解析的方法,而是HtmlSanitizer)。

集成测试是下一步,它采用一个或多个组件,并确保它们按照应有的方式一起工作。然后,你是在担心组件如何单独工作的复杂,但当你输入html到你的htmledcontrol,它以某种神奇的方式知道它是否有效。

这是一条真正可移动的线。我宁愿更专注于让该死的代码完全停止工作^_^

单元测试是针对工作单元或代码块进行测试。通常由单个开发人员执行。

集成测试是指当开发人员将其代码提交到源代码控制存储库时,最好在集成服务器上执行的测试。集成测试可以由Cruise Control等实用程序执行。

因此,您可以执行单元测试来验证您构建的工作单元是否正常工作,然后集成测试验证您添加到存储库中的任何内容都没有破坏其他内容。

当我编写单元测试时,我通过模拟依赖项将被测试代码的范围限制在我当前正在编写的类中。如果我正在编写一个Sentence类,而Sentence依赖于Word,那么我将使用一个模拟Word。通过模拟Word,我可以只关注它的界面,并在与Word界面交互时测试我的Sentence类的各种行为。这样我只测试了Sentence的行为和实现,而没有同时测试Word的实现。

一旦我编写了单元测试,以确保Sentence在基于Word的界面与Word交互时行为正确,然后我编写集成测试,以确保我对交互的假设是正确的。为此,我提供了实际的对象,并编写了一个测试,练习一个最终将同时使用Sentence和Word的功能。

我也这么做——我把它们都称为单元测试,但在某些时候,我有一个“单元测试”,它涵盖了太多内容,我经常把它重命名为“..IntegrationTest”——只是名字改变了,其他的都没有改变。

我认为从“原子测试”(测试一个微小的类或方法)到单元测试(类级别)和集成测试——然后是功能测试(通常从上到下覆盖了更多的东西)——有一个延续——似乎没有一个干净的分界线。

如果您的测试设置了数据,可能还加载了数据库/文件等,那么它可能更像是一个集成测试(我发现集成测试使用更少的模拟和更多的真实类,但这并不意味着您不能模拟出系统的某些部分)。

我把那些白盒测试类的测试称为单元测试。类需要的任何依赖项都被替换为伪依赖项(mock)。

集成测试是同时测试多个类及其交互的测试。在这些情况下,只有一些依赖关系是伪造的。

我不会调用Controller的集成测试,除非它们的依赖项之一是真实的(即不是伪造的)(例如IFormsAuthentication)。

Separating the two types of tests is useful for testing the system at different levels. Also, integration tests tend to be long lived, and unit tests are supposed to be quick. The execution speed distinction means they're executed differently. In our dev processes, unit tests are run at check-in (which is fine cos they're super quick), and integration tests are run once/twice per day. I try and run integration tests as often as possible, but usually hitting the database/writing to files/making rpc's/etc slows.

这引出了另一个重要的问题,单元测试应该避免碰到IO(例如磁盘、网络、db)。否则他们会慢很多。设计这些IO依赖需要一些努力——我不能承认我一直忠实于“单元测试必须是快速的”规则,但如果你是,在一个更大的系统上的好处很快就会显现出来。