为了确保服务按预期工作,必须编写测试来验证服务是否可以正确地与基础设施服务和其他服务进行交互。一种方法是启动所有服务并通过其API进行测试,而这是所谓的端到端测试,缓慢、脆弱而且昂贵,它位于金字塔顶端,有其价值,但应该最大限度减少端到端测试的数量。
更有效的策略是编写集成测试,我们可以使用一些策略:
阶段:
设置:通过创建数据库结构设置数据库,并将其初始化为已知状态。也可能开始执行一些必要的数据库事务
执行:执行数据库操作。
验证:对数据库的状态和从数据库中检索的对象进行断言。
拆解:可选阶段,可以撤销对数据库所作的更改。
关于如何配置在持久化集成测试中的使用的数据库,可以使用Docker方案解决。
良好的集成测试策略是使用消费者驱动的契约测试。契约用于验证两端的适配器类。
与测试REST交互的方式类似,不同的是每个契约都指定了一个领域事件。
消费者端测试验证命令消息代理类是否发送了结构正确的命令消息,并正确处理回复消息。提供者测试由Spring Cloud Contract代码生成。每种测试方法对应一份契约。它将契约的输入消息作为命令消息发送,并验证回复消息是否与契约输出消息匹配。
这是指单独测试服务。
验收测试是针对软件组件的面向业务的测试。它们从组件客户端而非内部实现角度描述所需的外部可见行为。这些测试源自用户故事或用例。
使用Java编写验收测试有挑战性,更好的方法是使用Gherkin,用类似英语场景定义验收测试。可自动将场景转换为可运行的代码。情景具有given-when-then结构。
使用Cucumber执行Gherkin的测试规范
Cucumber是Gherkin的测试自动化框架。你可以编写一个步骤定义类,类包含一组方法,方法定义了每个given-when-then步骤的具体含义。
组件测试必须为多个服务配置桩,还需要设置数据库和消息传递基础设施。
进程内组件测试
使用常驻内存的桩和模拟代替其依赖性运行服务。编写更简单,速度更快,但不测试服务的可部署性。
进程外组件测试
将服务打包为生产环境就绪的格式(如Docker容器镜像),并作为单独的进程运行。进程外组件测试使用真实的基础设施服务,如数据库、消息代理,但对应用程序服务的任何依赖项使用桩。
好处是提高测试覆盖率,测试内容更接近部署的内容;缺点是编写起来更复杂,执行更慢。
如何为进程外组件测试编写桩服务
可使用Spring Cloud Contract,编写契约,但只能由组件测试使用,包含契约的jar文件必须部署在maven库,处理涉及动态生成的值的交互也有挑战性,更简单的方法是在测试内部配置桩,如使用配置好DSL的WireMock作为HTTP桩服务。
服务的组件测试可使用Cucumber测试框架来执行用Gherkin验收测试DSL编写的测试场景。
端到端测试位于测试金字塔顶端。开发这类测试缓慢、脆弱且耗时。应尽量控制端到端测试数量。
编写用户旅程测试,模拟用户在应用程序中的旅程,并验证相对较大的应用程序功能片段的高级行为。如可编写完成所有若个测试的单个测试,而不是单独测试这些步骤。这可以显著减少编写测试数量并缩短测试执行时间。
端到端测试与组件测试实现类似,使用Gherkin编写并使用Cucumber执行。