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

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

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

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

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


当前回答

我认为,当您开始考虑集成测试时,您更多地是在谈论物理层之间的交叉,而不是逻辑层之间的交叉。

例如,如果您的测试只关心生成内容,那么它就是一个单元测试:如果您的测试只关心写入磁盘,那么它仍然是一个单元测试,但是一旦您同时测试了I/O和文件的内容,那么您就有了一个集成测试。当您在服务中测试函数的输出时,这是单元测试,但一旦您进行服务调用并查看函数结果是否相同,那么这就是集成测试。

从技术上讲,你不能只对一个类进行单元测试。如果您的类是由其他几个类组成的呢?这会自动地使它成为一个集成测试吗?我不这么想。

其他回答

我在采访中经常被问到这个问题。到目前为止,我一直在吹嘘我的专业知识,并对组件测试和验收测试侃侃而谈。

多年来,我只了解集成和单元测试。作为一个单独的开发人员,我可以编写单元测试来磨练我的技能,但我并不总是这么做。

单元测试

这是一个关键的区别。单元测试易于实现和执行,理想情况下不需要依赖。这就是嘲笑的意义所在。不模仿所有内容通常更容易,特别是在覆盖您所编写的其他函数的情况下。也许更简单,但这不是单元测试的思想。

我要重申,单元测试意味着易于运行且规模小。它们的失败可以让我们立即了解bug是在哪里引入的。

下面是测试的等级,从底部的廉价和丰富到顶部的缓慢、昂贵和很少:

还有几个层可以概念化,但为了清晰起见,省略了这些层。

集成测试

通过集成测试,您可以考虑引入严重的外部依赖项,例如虚拟机、虚拟网络和设备。可能您可以使用实际的调制解调器、路由器和防火墙,只要这些花费是合理的。

这些不会在本地运行,而是在构建服务器上运行。本地Jenkins和基于云的CI提供商的组合满足了这一需求。

其他测试术语

这是我在工业界工作了几年的体会。我们可以讨论组件测试,并得到一个定义,但如果这个定义没有被广泛使用,那么它就失去了价值。

验收测试就是我们所说的业务单元或客户需求。这些将引导一切的方向,并位于金字塔的顶端(想象一个美元符号)。

端到端测试是集成测试的同义词,但我在网上注意到它被放在上面。我想它可能与验收测试和集成测试更相关,后者往往更详细,涉众的兴趣更少(尽管部门内部有巨大的兴趣)。

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

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

单元测试是一种测试方法,用于验证源代码的各个单元是否正常工作。

集成测试是软件测试的一个阶段,在这个阶段中,各个软件模块被组合起来并作为一个组进行测试。

Wikipedia将单元定义为应用程序中最小的可测试部分,在Java/ c#中是一个方法。但是在你的单词和句子类的例子中,我可能只会为句子写测试,因为我可能会发现使用一个模拟单词类来测试句子类是多余的。所以句子是我的单位,单词是这个单位的实现细节。

在我看来,答案是“为什么这很重要?”

是不是因为您只做单元测试而不做集成测试?反之亦然?当然不是,你应该尝试两者兼得。

是因为单元测试需要快速、隔离、可重复、自我验证和及时,而集成测试不需要吗?当然不是,所有的测试都应该是这样。

这是因为您在单元测试中使用模拟,而在集成测试中不使用它们吗?当然不是。这意味着,如果我有一个有用的集成测试,我不允许为某些部分添加模拟,担心我将不得不将我的测试重命名为“单元测试”或将其交给另一个程序员来处理。

是不是因为单元测试测试一个单元,而集成测试测试许多单元?当然不是。这有什么实际意义呢?关于测试范围的理论讨论在实践中无论如何都是行不通的,因为术语“单元”完全依赖于上下文。在类级别上,单元可能是一个方法。在程序集级别上,单元可能是类,而在服务级别上,单元可能是组件。 甚至类也会使用其他类,那么哪个是单位呢?

这无关紧要。

测试很重要,F.I.R.S.T也很重要,对定义吹毛求疵是浪费时间,只会让测试新手感到困惑。

我认为,当您开始考虑集成测试时,您更多地是在谈论物理层之间的交叉,而不是逻辑层之间的交叉。

例如,如果您的测试只关心生成内容,那么它就是一个单元测试:如果您的测试只关心写入磁盘,那么它仍然是一个单元测试,但是一旦您同时测试了I/O和文件的内容,那么您就有了一个集成测试。当您在服务中测试函数的输出时,这是单元测试,但一旦您进行服务调用并查看函数结果是否相同,那么这就是集成测试。

从技术上讲,你不能只对一个类进行单元测试。如果您的类是由其他几个类组成的呢?这会自动地使它成为一个集成测试吗?我不这么想。