单元,功能,验收和集成测试之间有什么区别?[关闭]


799

单元测试,功能测试,验收测试和集成测试(以及我没有提到的任何其他类型的测试)之间有什么区别?



1
我认为您忘记了负载测试!
谈话很便宜,请告诉我代码

Answers:


1350

根据您的外观,您会得到略有不同的答案。我已经读了很多关于这个主题的文章,这是我的精炼。再次,这些有点毛茸茸,其他人可能会不同意。

单元测试

测试功能的最小单元,通常是方法/功能(例如,给定具有特定状态的类,在该类上调用x方法应导致y发生)。单元测试应该集中于一个特定的功能(例如,当堆栈为空时调用pop方法应该抛出InvalidOperationException)。它涉及的所有内容都应该在内存中完成;这意味着测试代码被测代码不应:

  • 召集(非平凡的)合作者
  • 访问网络
  • 命中数据库
  • 使用文件系统
  • 旋转线程
  • 等等

应该使用适当的技术对任何缓慢/难以理解/初始化/操作的依赖项进行打桩/模拟/处理,以使您可以专注于代码单元在做什么,而不是代码在做什么。

简而言之,单元测试尽可能简单,易于调试,可靠(由于减少了外部因素),执行速度快,并有助于证明程序的最小构造块在组合在一起之前就可以发挥预期的作用。需要注意的是,尽管您可以证明它们在隔离状态下可以完美地工作,但是合并后的代码单元可能会爆炸,从而使我们陷入困境。

整合测试

集成测试通过组合代码单元并测试所产生的组合能否正常运行而建立在单元测试的基础上。这可以是一个系统的内部功能,也可以是将多个系统组合在一起以执行有用的操作。同样,将集成测试与单元测试区分开的另一件事是环境。集成测试可以并且将使用线程,访问数据库或执行所需的任何操作以确保所有代码不同的环境更改都能正常工作。

如果您已经构建了一些序列化代码并且在不接触磁盘的情况下对其内部进行了单元测试,那么您如何知道在加载并保存到磁盘时它会起作用?也许您忘记了刷新和处理文件流。也许您的文件权限不正确,并且您已经测试了在内存流中使用的内在函数。唯一可以确定的方法是使用最接近生产环境的“真实”测试。

主要优点是,他们会发现单元测试无法发现的错误,例如接线错误(例如,类A的实例意外接收到B的空实例)和环境错误(在单CPU机器上运行良好,但是同事的4核计算机无法通过测试)。主要缺点是集成测试涉及更多代码,可靠性更低,故障更难诊断,测试更难维护。

另外,集成测试并不一定证明完整的功能有效。用户可能不在乎我的程序的内部细节,但是我确实在乎!

功能测试

功能测试通过将给定输入的结果与规范进行比较来检查特定功能的正确性。功能测试与中间结果或副作用无关,仅与结果有关(它们并不关心在执行x之后,对象y处于状态z)。它们被编写为测试规范的一部分,例如“调用参数Square2的函数Square(x)返回4”。

验收测试

验收测试似乎分为两种类型:

标准验收测试涉及在整个系统上执行测试(例如,通过Web浏览器使用您的网页),以查看应用程序的功能是否满足规范。例如,“单击缩放图标应将文档视图放大25%”。没有真正的结果连续性,只有通过或失败的结果。

这样做的好处是,测试使用简单的英语进行描述,并确保软件作为一个整体是完整的。缺点是您将测试金字塔上移了另一个层次。验收测试涉及大量的代码,因此跟踪失败可能很棘手。

同样,在敏捷软件开发中,用户接受测试涉及创建测试以反映开发过程中由软件客户创建的/为软件客户创建的用户故事。如果测试通过,则意味着软件应满足客户的要求,并且故事可以被认为是完整的。验收测试套件基本上是用领域特定语言编写的可执行规范,该规范以系统用户使用的语言描述测试。

结论

它们是互补的。有时专注于一种类型或完全避开它们是有利的。对我而言,主要区别在于某些测试从程序员的角度看待事物,而另一些则以客户/最终用户为关注重点。


19
+1。@Mark Simpson功能和验收测试可以归纳为“系统测试”吗?端到端测试适合什么地方?(我的口味有太多不同的词汇)
Torsten Engelbrecht

3
@Franz我在讲的是您可以通过隔离代码单元并对其进行测试来降低风险的能力和便捷性。没错,我使用的语言有点松散,因为测试无法证明代码没有错误。
马克·辛普森

15
尽管投票赞成,但这是完全错误的。单元测试甚至不测试“琐碎”的合作者。任何注入的依赖项都必须被嘲笑。功能测试不测试“行为”;他们只测试“功能”,即“ f(A)返回B”。如果副作用很重要,那就是“行为”。如果这些包括系统调用,则它们也像“行为系统测试”一样,也是“系统”测试。(请参阅下面的testerab @。)“验收”测试是“行为系统测试”的子集,涵盖整个堆栈。“集成”向上测试,模拟实际使用情况;它测试所有依赖项可以在实践中集成。
cdunn2001 2014年

7
@ cdunn2001:不用担心,建设性的批评总是很好的:)您的评论教会了我一些我不知道的东西,并且使我的术语有所整理。我一直热衷于向热衷于测试的开发人员学习新知识。我记得我第一次发现MiškoHevery的博客-就像一个宝库:)
Mark Simpson

11
@MarkSimpson虽然您的回答非常好,但我想了解有关功能测试的更多详细信息。对我而言,我的意思是很难区分功能测试和单元测试。希望您有时间这样做,继续努力!
Andrei Sandulescu 2014年

90

重要的是您知道这些术语对您的同事意味着什么。例如,不同的群体在说“全面的端到端”测试时,对含义的定义会稍有不同。

我最近在他们的测试中遇到了Google的命名系统,我更喜欢它-他们仅使用Small,Medium和Large绕过了论点。为了确定测试适合的类别,他们会考虑一些因素-运行多长时间,是否访问网络,数据库,文件系统,外部系统等。

http://googletesting.blogspot.com/2010/12/test-sizes.html

我以为您当前工作场所的“小”,“中”和“大”之间的差异可能会与Google有所不同。

但是,这不仅与范围有关,而且与目的有关。Mark关于测试的不同观点的观点非常重要,例如程序员与客户/最终用户。


6
+1表示Google测试的命名方式,因为它有助于您了解各种组织/人员为何对测试有不同的定义。
马克·辛普森

这也是一篇非常不错的文章,探讨了为什么要使用不同级别的测试以及从中获得什么:kentcdodds.com/blog/unit-vs-integration-vs-e2e-tests
testerab

63

http://martinfowler.com/articles/microservice-testing/

Martin Fowler的博客文章谈到了测试代码的策略(尤其是在微服务体系结构中),但是大多数策略都适用于任何应用程序。

我从他的摘要幻灯片中引用:

  • 单元测试-练习应用程序中最小的可测试软件,以确定它们是否按预期运行。
  • 集成测试-验证组件之间的通信路径和交互以检测接口缺陷。
  • 组件测试-将使用的软件的范围限制为被测系统的一部分,通过内部代码接口操纵系统,并使用测试双精度来将被测代码与其他组件隔离。
  • 合同测试-验证外部服务边界是否符合使用服务所期望的合同,以验证其相互作用。
  • 端到端测试-验证系统满足外部需求并实现其目标,从头到尾测试整个系统。

顺便说一句,这是一篇很棒的文章。但是我不完全了解合同测试的目的。根据组件和集成测试,它们不是多余的吗?
wheleph

在某些语言(Fowler先生使用的语言)中,您可以实现一个使用类的标准定义时未公开的接口,例如void IMyInterface.MyMethod()。从逻辑上来说,后者将有自己的测试。尽管那时您正朝BDD前进。具有讽刺意味的是,福勒先生也曾有过一席之地。
Skarsnik

2
这不是Fowler的文章,只是张贴在那儿。合同测试是在客户开始使用您的服务之后进行的测试,然后编写测试以检查您是否没有为该特定客户破坏某些东西,即更改服务api。
拉法尔Łużyński

@wheleph单元测试,集成测试和组件测试最能说明开发人员可以严格控制的软件内部。前三个问题是指更改您的来源以解决问题。-合同测试触及了功能方面的承诺,但面对缺陷您可能无法直接进行更改。这需要添加支持代码来解决这些可能的问题,而不仅仅是修复缺陷。-因此,即使合同规范告诉您它具有某种结构,您也可以使用Web服务来返回格式错误的json。
Yemi Bedu

31

单元测试 -顾名思义,此方法在对象级别进行测试。测试各个软件组件是否有任何错误。此测试需要程序的知识,并且会创建测试代码以检查软件是否按预期运行。

功能测试 -在不了解系统内部工作的情况下执行。测试人员将通过提供不同的输入并测试生成的输出来尝试按照以下要求使用该系统。此测试也称为封闭盒测试或黑盒测试。

验收测试 -这是在软件移交给客户之前进行的最后一次测试。这样做是为了确保开发的软件满足所有客户要求。有两种类型的验收测试-一种由开发团队的成员执行,称为内部验收测试(Alpha测试),另一种由客户或最终用户执行,称为(测试版)

集成测试 -已经经过单元测试的各个模块相互集成。通常,遵循以下两种方法:

1)自上而下
2)自下而上


自上而下和自下而上是什么意思?集成测试是否与端到端测试相同?
tamj0rd2

18

这很简单。

  1. 单元测试:这是具有编码知识的开发人员实际进行的测试。此测试在编码阶段完成,是白盒测试的一部分。当软件要开发时,它会被开发为一段代码或一段代码,称为一个单元。这些单元的单独测试称为开发人员进行的单元测试,以发现某些人为错误,例如语句覆盖范围的缺失等。

  2. 功能测试:此测试在测试(QA)阶段完成,是黑盒测试的一部分。先前编写的测试用例的实际执行。该测试实际上是由测试人员完成的,他们会找到站点中任何功能的实际结果,并将此结果与预期结果进行比较。如果他们发现任何差异,那就是一个错误。

  3. 验收测试:称为UAT。这实际上是由测试人员以及开发人员,管理团队,作者,作家以及参与此项目的所有人员完成的。为了确保项目最终准备就绪,可以免费提供错误。

  4. 集成测试:代码单元(在第1点中说明)相互集成以完成项目。这些代码单元可以用不同的编码技术编写,也可以使用不同的版本,因此,此测试由开发人员完成,以确保所有代码单元彼此兼容,并且不存在任何集成问题。


1
@OlegTsyba答案在回答问题四年后才来。
bentesha

1
我们永远不要以“这很简单”开始回答,尤其是在这是一个复杂的话题时。
milosmns

6

我是测试代码的新手。单元测试似乎主要是在浪费时间。我以为自己在进行单元测试,但是在进行集成测试,然后阅读有关单元测试的信息,这似乎很愚蠢,也许对经验很少的人来说呢?我有可能会遗漏一些要点。
PixMach 2015年

如果对单元进行了广义定义,那么您就可以正确进行单元测试了。我反对测试实现细节。私人课程不应进行“单元测试”。但是,如果您有多个公共类,则可能会在测试另一个时尝试模拟一个。那是真正的辩论。是单位(一)整个资料库?(b)图书馆内的每个公开课?还是(c)每个类中的每个公共方法?我更喜欢将给定的库作为集成组件进行测试,但是要模拟或伪造外部依赖项(除非它们快速可靠)。所以我想我和你在一起。
cdunn2001'3

1
@PixMach:实际上是相反的方式。如果您(或其他人)将来不得不更改该代码,则没有(好的)单元测试会浪费您很多时间。如果您有使用和不使用单元测试来维护代码的经验,那么您就会知道两者之间的区别。想法是,如果单元测试失败,则应该确切地知道必须修复代码的哪一部分。未能通过大规模接受/集成测试通常只会告诉您:它不起作用。然后,您必须开始旧学校调试...
Goodsquirrel '16

@Goodsquirrel,这取决于您所谓的“单位”。那就是问题所在。不良测试将在重构期间被删除。良好的测试仍然会有所帮助。糟糕的测试不会增加任何价值,并会造成妨碍。好的测试是自我记录的,并受到高度赞赏。让我们具体一点。我有一个私有方法,如果另一个值是True,则返回一个值,否则返回默认值。(旧版代码。)应该测试该方法吗?我拒绝。另一个私有方法返回第n个斐波那契数。应该测试吗?我说是。
cdunn2001 '16

1
最小的公开代码。很大的区别。
cdunn2001 '18

5

我将通过一个实际的例子向您说明这一点,而没有理论上的东西:

开发人员编写代码。尚未实现GUI。在此级别上的测试将验证功能是否正常工作以及数据类型是否正确。测试的这一阶段称为单元测试。

开发GUI并将应用程序分配给测试人员后,他与客户一起验证业务需求并执行不同的方案。这称为功能测试。在这里,我们将客户需求与应用程序流进行映射。

集成测试:假设我们的应用程序具有两个模块:人力资源和财务。人力资源模块已交付并经过测试。现在已开发出Finance,并且可以进行测试。相互依赖的功能现在也可用,因此在此阶段,您将测试两者之间的通信点,并验证它们是否按要求工作。

回归测试是另一个重要的阶段,在进行任何新开发或错误修复后即完成。其目的是验证以前的工作功能。


1
“开发人员编写了代码。尚未实现GUI。在此级别进行的测试可验证功能是否正常工作以及数据类型是否正确。此测试阶段称为单元测试”。GUI实际上只是一个“插件”。您已经可以将E2E测试写入API输出。(或您生成的任何响应对象)
user3790897,18年

4

单元测试:已知应用程序中单个模块或独立组件的测试是单元测试,该单元测试将由开发人员完成。

集成测试:组合所有模块并测试应用程序,以验证模块之间的通信和数据流是否正常工作,该测试也由开发人员执行。

funcional测试检查的应用程序的各个功能是平均为功能测试

验收测试此测试由最终用户或客户完成,无论构建应用程序是否符合客户要求,并且客户规范被称为验收测试。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.