测试? 什么是集成测试 - 与单元测试相比有何不同?

40
我开始在我的项目中使用单元测试,并编写测试方法/函数级别的测试。
我理解这一点,这很有道理。
但是,什么是集成测试?从我所读的内容来看,它将测试范围提升到测试应用程序更大的特性。这意味着我需要编写一个新的测试套件来测试更大的功能,例如(在电子商务网站上)结账功能、用户登录功能和购物篮功能。因此,我需要编写3个集成测试吗?
如果不正确,有人能解释一下是什么意思吗?
另外,集成测试是否涉及 UI(在 Web 应用程序上下文中),并且会使用像 Selenium 这样的自动化工具?还是集成测试仍然处于代码级别,但将代码的不同类和区域联系在一起?
5个回答

46
考虑以下这个方法:PerformPayment(double amount, PaymentService service)
单元测试是指您创建一个service参数的模拟对象时进行的测试。
集成测试是指您使用实际的外部服务进行测试,以便测试该服务是否对您的输入数据做出正确响应的测试。

所以这些是在UI层完成的吗?比如使用Selenium,还是有另外一个测试套件编写,类似于单元测试套件,但范围更广? - Marty Wallace
2
不一定。考虑PaymentService使用外部资源,比如数据库或第三方API。它可能需要几秒钟才能访问(在糟糕的情况下),或者可能只是一个长时间运行的过程。它对于单元测试来说太慢了(因此模拟它),但您仍然希望测试它以确保其正常运行。这就是集成测试的作用。它们不是您重复运行的测试,通常在发布之前或您的CI运行它们。 - firelore

12

单元测试是测试所测试代码位于实际类中的测试。该类的其他依赖项被模拟或忽略,因为重点是测试类内部的代码。

集成测试是涉及磁盘访问、应用程序服务和/或来自目标应用程序的框架的测试。集成测试从另一个外部服务中隔离运行。

我举个例子。您有一个 Spring 应用程序,并进行了大量的单元测试,以确保业务逻辑正常工作。很好。但是,您需要进行什么样的测试才能保证:

  • 您的应用程序服务能够启动
  • 您的数据库实体正确映射
  • 您所有必要的注释都按预期工作
  • 您的 Filter 正常工作
  • 您的 API 接受某种数据
  • 您的主要功能在基本场景下真正工作
  • 您的数据库查询按预期工作
  • 等等...

这不能通过单元测试完成,但是您作为开发人员也需要确保所有事情都正常工作。这就是集成测试的目标。

理想情况是集成测试独立于应用程序在生产环境中使用的其他外部系统运行。您可以使用 Wiremock 进行 Rest 调用,像 H2 这样的内存数据库,模拟从一些调用外部系统的特定类中的 bean 等来实现这一点。

有趣的是,Maven 有一个专门用于集成测试的插件:maven failsafe plugin,它执行名称以IT结尾的测试类(默认情况下)。例如:UserIT.java

关于“集成测试”含义的混淆

有些人将“集成测试”理解为涉及到当前系统使用的其他外部系统的“集成”测试。这种类型的测试只能在您拥有所有系统以便为您提供支持的环境中进行。没有虚假的内容,也没有被模拟的内容。

这可能只是一个命名问题,但我们缺乏测试(我理解为集成测试),这些测试需要满足上述需求。相反,我们从单元测试(仅测试类)跳转到“集成”测试(整个实际系统)。那么,在中间是什么,如果不是集成测试呢?
关于这种混淆,您可以在Martin Fowler的文章中阅读更多内容。他将“集成测试”术语分为两个含义:广义和狭义的集成测试:
- 狭义集成测试 - 仅测试与其他服务交互的代码部分 - 使用这些服务的测试替身,可以在进程内或远程操作 - 因此由许多范围狭窄的测试组成,通常范围不超过单元测试,并且通常使用与单元测试相同的测试框架运行
- 广义集成测试 - 需要所有服务的实时版本,需要大量的测试环境和网络访问 - 通过所有服务的代码路径进行测试,而不仅仅是负责交互的代码
您可以在这篇文章中获取更多细节。

3
那篇Martin Fowler的文章很好。他使用“系统/端到端测试”和“窄集成测试”这些术语,而不是模糊不清的“集成测试”。 - Andrew Keeton

2

单元测试是指在类或代码片段中测试您的业务逻辑。例如,如果您正在测试方法的特定部分是否应该调用存储库,则您的单元测试将检查接口方法是否正确地调用了存储库的次数,否则它会失败测试。

另一方面,集成测试则是测试实际服务或存储库(数据库)行为是否正确。它检查根据您传入的数据是否检索到了预期结果。这与您的单元测试相结合,以便您知道应检索哪些数据以及它对该数据执行的操作。


0
据我所见,Selenium 测试应该放在另一个测试套件中。即使编写正确,这些测试也是最脆弱的测试。在这里,您可以使用 Specflow 或其他一些基于示例的框架。也许您可以将这些测试称为验收测试。这些测试既适用于开发人员,也适用于业务专家。 集成或模块测试通常不使用 UI。集成测试涉及一些共同工作的类。这些测试比 Selenium 测试低级别一些,维护起来稍微容易一些。这些测试只适用于开发人员。

0

以下是一些良好的单元测试应满足的约束条件。同时,满足这些约束条件也需要编写良好的可测试代码。

  1. 没有I/O - 磁盘或网络
  2. 只有一个断言(如果有多个,则应该是彼此之间的次要变化)
  3. 不会涵盖比所断言的更多的生产代码

这些约束通常不适用于集成测试。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接