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


当前回答

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

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

我将引用他的总结幻灯片:

单元测试-测试应用程序中最小的可测试软件,以确定它们是否按预期运行。集成测试-验证组件之间的通信路径和交互,以检测接口缺陷。组件测试-将所使用软件的范围限制在被测试系统的一部分,通过内部代码接口,并使用双重测试隔离代码在其他部件的测试下。契约测试-验证外部服务边界处的交互,断言它符合消费者期望的契约服务端到端测试-验证系统是否满足外部需求并实现其目标,测试整个系统,从端到端。

其他回答

这很简单。

单元测试:这是由具有编码知识的开发人员实际完成的测试。该测试在编码阶段完成,是白盒测试的一部分。当一个软件开始开发时,它被开发成一段代码或代码片段,称为一个单元。对这些单元的单独测试称为开发人员进行的单元测试,以找出某些人为错误,如缺少语句覆盖等。。功能测试:该测试在测试(QA)阶段完成,是黑盒测试的一部分。先前编写的测试用例的实际执行。这个测试实际上是由测试人员完成的,他们找到站点中任何功能的实际结果,并将这个结果与预期结果进行比较。如果他们发现任何差异,那么这就是一个错误。验收测试:即UAT。这实际上是由测试人员以及开发人员、管理团队、作者、作家以及所有参与该项目的人员完成的。确保项目最终准备好交付,无bug。集成测试:代码单元(在第1点中解释)彼此集成以完成项目。这些代码单元可以用不同的编码技术编写,也可以是不同的版本,因此开发人员进行测试,以确保所有代码单元都与其他代码单元兼容,不存在任何集成问题。

根据你看的地方,你会得到稍微不同的答案。我读了很多关于这个主题的书,这是我的总结;同样,这些都有点模糊,其他人可能不同意。

单元测试

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

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

任何类型的依赖性如果很慢/很难理解/初始化/操作,都应该使用适当的技术来清除/嘲笑/什么,这样你就可以专注于代码单元在做什么,而不是它的依赖性在做什么。

简而言之,单元测试尽可能简单、易于调试、可靠(由于外部因素减少)、执行速度快,并有助于证明程序的最小构建块在组装之前能够按预期运行。需要注意的是,尽管你可以证明它们在单独工作时是完美的,但代码单元在组合时可能会爆炸,这会导致我们。。。

集成测试

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

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

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

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

功能测试

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

验收测试

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

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

优点是测试用简单的英语描述,并确保整个软件功能完整。缺点是你已经在测试金字塔上移动了另一个层次。验收测试涉及堆积如山的代码,因此追踪失败可能很棘手。

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

结论

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

重要的是,你知道这些术语对你的同事意味着什么。例如,不同的小组对他们所说的“完全端到端”测试的含义定义略有不同。

我最近在他们的测试中遇到了谷歌的命名系统,我很喜欢它——他们只使用“小”、“中”和“大”来绕过这些争论。为了决定测试属于哪一类,他们会考虑几个因素——运行时间、访问网络、数据库、文件系统、外部系统等等。

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

我想你当前工作场所的小型、中型和大型之间的区别可能与谷歌有所不同。

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

一些(相对而言)反对过度嘲讽和纯单元测试的近期想法:

https://www.simple-talk.com/dotnet/.net-framework/are-unit-tests-overused/http://googletesting.blogspot.com/2013/05/testing-on-toilet-dont-overuse-mocks.htmlhttp://codebetter.com/iancooper/2011/10/06/avoid-testing-implementation-details-test-behaviours/http://cdunn2001.blogspot.com/2014/04/the-evil-unit-test.htmlhttp://www.jacopretorius.net/2012/01/test-behavior-not-implementation.html为什么大多数单元测试都是浪费

我将用一个实际的例子来解释这一点,而不是理论上的东西:

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

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

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

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