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

What's the difference between unit, functional, acceptance, and integration tests?

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


根据你看的地方,你会得到稍微不同的答案。我读过很多关于这个主题的文章,这是我的精辟之处;同样,这些文章有点模糊,其他人可能不同意。好的。

单元测试好的。

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

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

任何一种缓慢/难以理解/初始化/操作的依赖关系都应该使用适当的技术进行存根/模拟/验证,这样您就可以专注于代码单元在做什么,而不是依赖关系在做什么。好的。

简言之,单元测试尽可能简单,易于调试,可靠(由于减少了外部因素),执行速度快,有助于证明程序的最小构建块在组合在一起之前按预期运行。需要注意的是,尽管您可以证明它们在隔离状态下工作得很好,但是组合在一起时,代码单元可能会爆炸,这会使我们……好的。

集成测试好的。

集成测试是在单元测试的基础上进行的,通过组合代码单元和测试所得到的组合是否正常工作。这可以是一个系统的内部,也可以将多个系统组合在一起以完成一些有用的事情。此外,将集成测试与单元测试区分开来的另一件事是环境。集成测试可以并且将使用线程、访问数据库或执行任何需要的操作,以确保所有代码和不同的环境更改都能正常工作。好的。

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

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

此外,集成测试不一定证明一个完整的特性是有效的。用户可能不关心我程序的内部细节,但我关心!好的。

功能测试好的。

功能测试通过将给定输入的结果与规范进行比较来检查特定特性的正确性。功能测试不关心中间结果或副作用,只关心结果(在做了x之后,对象y的状态是z,它们不关心)。它们是为测试规范的一部分而编写的,例如"用2的参数调用函数square(x)返回4"。好的。

验收试验好的。

验收测试似乎分为两类:好的。

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

其优点是测试用简单的英语描述,并确保整个软件功能完整。缺点是你已经把测试金字塔的另一个层次提升了。验收测试触及了大量的代码,因此跟踪失败可能很棘手。好的。

此外,在敏捷软件开发中,用户验收测试包括创建测试,以反映软件客户在开发过程中创建的用户故事。如果测试通过,这意味着软件应该满足客户的要求,并且故事可以被认为是完整的。验收测试套件基本上是用特定于域的语言编写的可执行规范,它用系统用户使用的语言描述测试。好的。

结论好的。

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


重要的是你知道这些术语对你的同事意味着什么。例如,不同的组对于他们所说的"完整的端到端"测试的含义将有稍微不同的定义。

我最近在谷歌的测试中遇到了命名系统,我很喜欢它——他们只使用小、中、大来绕过争论。为了确定一个测试适合哪个类别,他们考虑了几个因素——运行需要多长时间,它访问网络、数据库、文件系统、外部系统等等。

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

我可以想象,对于你现在的工作场所来说,小、中、大的区别可能与谷歌的不同。

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


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

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

我将引用他的摘要幻灯片:

  • Unit tests - exercise the smallest pieces of testable software in the application to determine whether they behave as expected.
  • Integration tests - verify the communication paths and interactions between components to detect interface defects.
  • Component tests - limit the scope of the exercised software to a portion of the system under test, manipulating the system through
    internal code interfaces and using test doubles to isolate the code
    under test from other components.
  • Contract tests - verify interactions at the boundary of an external service asserting that it meets the contract expected by a consuming
    service.
  • End-To-End tests - verify that a system meets external requirements and achieves its goals, testing the entire system, from
    end to end.


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

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

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

集成测试-已经接受单元测试的各个模块彼此集成。一般来说,这两种方法是:

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


这很简单。

  • 单元测试:这是由具有编码知识的开发人员实际完成的测试。此测试在编码阶段完成,它是白盒测试的一部分。当一个软件需要开发时,它被开发成一段或多段代码,称为一个单元。对这些单元的个别测试称为由开发人员进行的单元测试,以找出诸如语句覆盖丢失等人为错误。

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

  • 验收测试:称为UAT。这实际上是由测试人员,开发人员,管理团队,作者,作者以及所有参与这个项目的人完成的。以确保项目最终准备好无缺陷交付。

  • 集成测试:代码单元(在第1点中解释)相互集成以完成项目。这些代码单元可以用不同的编码技术编写,也可以是不同版本的,因此开发人员要进行此测试,以确保代码的所有单元都与其他单元兼容,并且不存在任何集成问题。


  • 一些(相对的)反对过度模仿和纯单元测试的最新想法:

    • https://www.simple-talk.com/dotnet/.net framework/是否过度使用了单元测试/
    • http://googletesting.blogspot.com/2013/05/testing-on-toilet-dont-overuse-mocks.html
    • http://codebetter.com/iancooper/2011/10/06/avoint-testing-implementation-details-test-behaviors/
    • http://cdunn2001.blogspot.com/2014/04/the-evil-unit-test.html
    • http://www.jacopretorius.net/2012/01/test-behavior-not-implementation.html
    • 为什么大多数单元测试都是浪费


    我将用一个实际的例子来解释这一点,没有理论方面的内容:

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

    当开发了一个GUI,并且将应用程序分配给一个测试人员时,他将与客户机一起验证业务需求,并执行不同的场景。这叫做功能测试。这里我们将客户机需求与应用程序流进行映射。

    集成测试:假设我们的应用程序有两个模块:人力资源和财务。HR模块先前已交付并测试过。现在,金融业已经发展起来,可以进行测试。现在还可以使用相互依赖的特性,因此在这个阶段,您将测试两个特性之间的通信点,并验证它们是否按照需求中的要求工作。

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


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

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

    功能测试检查应用程序的单个功能意味着功能测试

    验收测试:无论构建应用程序是否符合客户要求,以及客户规范,最终用户或客户都要进行此测试。这就是验收测试。