在敏捷和精益开发实践的早期阶段,开发团队、运维和 QA 之间出现了非常明显的鸿沟。开发的速度不断提升,但测试过程及方法没有相应改变,整体上降低了软件交付速度,阻碍了企业实现持续交付。传统的测试方法严重依赖于手工流程和频繁更新的 GUI 测试,对于我们的新生命周期时间表来说,这些方法过于繁琐和不足,导致很多问题:
1. 问题滞后:上前线才发现大量 Bug,导致上线严重延期
2. 影响范围变大:一个错误发现的越晚,其影响范围就会不断变大,其他开发人员会使用错误的代码继续开发
3. 修复成本上升:还有时间过长,开发人员对代码熟悉成都会下降,另外因为影响范围可能变大,修复成本会逐渐上升。
4. 二次污染:当你修复一个 Bug 的时候,很可能会带来另一个 Bug,进入修复 Bug,测试,修复 Bug 的不良循环中。
作为事后思考的测试时代正在消亡,持续测试已经成为新的标准。持续测试背后的思想非常简单:就是尽早失败(Fail Fast and Fail Faster),尽最大可能缩短反馈周期。 实施一个系统的改进方法,不仅包括自动化,还包括所有其他的工具和过程,这些工具和过程将有助于在软件发布和生产之前降低风险。
持续集成(CI)、连续交付(CD)和连续测试(CT)是许多开发团队采用敏捷策略的三种方法。虽然每个服务都有一个稍微不同的目标,但如果结合起来,它们可以显著地帮助团队实现速度和质量,这是任何开发团队最重要的两个目标。
持续测试是作为软件交付管道的一部分执行自动化测试的过程,以尽快获得与软件发布候选相关的业务风险的反馈。确保每个迭代(Sprint)结束时都有高质量的应用程序。可以说持续测试是敏捷开发和 Devops 的必要条件。
持续测试的5个关键点:
1. 持续测试主要目标是评估业务风险范围。
2. 持续测试建立了一个质量体系,帮助团队在快速开发过程中保护用户体验,避免软件失败。
3. 持续测试要求能够随需创建一个稳定的测试环境用于快速反馈。
4. 连续测试需要无缝集成到软件交付流水线和 DevOps 工具链中。
5. 持续测试应该为交付流水线的每个阶段提供适当的反馈(质量关卡)。
过多关于持续测试的定义请参考:https://www.tricentis.com/what-is-continuous-testing/
为了实现持续测试,自动化率需要超过85%。为了实现这一点,需要做一些改变:
将测试与业务风险相结合,以优化测试执行,实现自动化的质量检验关,并为发布决策提供关键的洞察力。
最小化手工测试,并将其转换为基于会话的探索性测试。
在可行的情况下,将测试工作转移到 API 层。
使用测试数据管理和服务虚拟化,以便能够连续执行实际的端到端测试——没有假阳性和超时。
将功能测试集成到 CI/CD 中,这是交付流水线中无缝集成。
微服务的一个标准就是可以独立发布,下图是 Netflix 内部微服务结构, 每个团队独立发布自己的微服务。
因此在微服务架构下,你的服务可能由不同的团队提供和维护,在这种情况下,接口的开发,测试和维护可能会带来一些问题
1. 服务端调整架构或接口调整而对消费者不透明,导致接口调用失败。
2. 微服务测试环境搭建困难,存在大量直接依赖和间接依赖,测试时需要准备所有依赖的服务,测试一个服务,你不得不部署其他微服务,也许还有耦合的数据库、消息队列等。
3. 很难进行 Debug,反馈周期变长。
4. 微服务版本及接口独立维护,出现接口不兼容现象,导致微服务升级失败。
消费者驱动的契约测试(Consumer-Driven Contracts,简称 CDC),是指从消费者业务实现的角度出发,驱动出契约,再基于契约,对提供者验证的一种测试方式。如果你目前使用 SpringCloud 作为微服务基础环境,那么集成 SpringCloud Contracts 也是比较好的选择。
使用 SpringCloud Contracts 之前:
使用 SpringCloud Contracts 之后:
如图所示,我们只需要关注直接依赖,看起来和 Mock 测试相似,它的不同之处在于消费者来驱动测试,从而提高透明性,服务提供方流程简单描述如下:
1. 服务消费方提出需求(契约 Contract)
2. 服务提供方根据契约完成功能开发以及功能单元测试
3. 服务提供方自测发现不满足契约时不能进行升级和发布(Fail Fast and Fail Faster)
4. 服务提供方根据契约自动生成测试桩(STUB),用于消费方进行依赖测试
5. 消费方测试时根据直接依赖情况,下载直接依赖的服务STUB,并启动 STUB 服务模拟测试依赖的服务,不需要下载传递依赖
6. 服务提供方不得单方修改接口服务,需要根据消费方契约的修改而变更,保证服务提供方变更的透明性
7. 服务提供方作为消费方时重复1-6步。
这里引入了一个重要的概念,就是 契约,Contract 。这是什么呢?很简单,就是 Provider 和 Consumer 事先要约定好一个接口的规范,之后双方提供服务接口和消费服务接口都要按照这个契约来。来看一个契约描述,契约采用 Groovy 的 DSL 描述,所以一目了然,就是通过url:/ api / customers来取得一个 Json 格式的客户列表,返回两个客户信息。
根据契约实现服务后,我们根据 Spring Cloud Contract 的一个 Maven 插件( spring-cloud-starter-contract-verifier
),执行 Mvn Install 后会自动生成服务 Jar 包和测试桩 Stub,如下图
消费方同时需要依赖一个 Spring Cloud 组件: spring-cloud-starter-contract-stub-runner ,通过这个依赖,我们就可以快速启动服务提供方提供的 Stub 来模拟启动一个契约服务了。
其中使用了 Spring Cloud Contract 组件中的注解:
@AutoConfigureStubRunner(ids = {"com.importsource.springcloud:spring-cloud-contract-provider:+:8080"}, workOffline = true)
我们通过@AutoConfigureStubRunner 来自动配置注入一个 StubRunner。Lds 来指定直接依赖的服务,并指定服务端口号。这样我们根本不需要启动真正的服务提供者,而是在本地启动了 Stub 就模拟测试了一次服务调用。
本文首先向你介绍了持续测试的背景概念以及如何来做持续测试, 同时介绍了消费者驱动(CDC)测试的场景,以及消费者驱动契约的一个实现 Spring Cloud Contract,我们通过定义契约进行微服务框架下的持续测试,稳定可靠的加速 CI/CD 持续交付。另外契约测试的工具除了 Spring Cloud Contract 外,还有其他的一些工具可供你选择,比如:Janus,Pact,Pacto 等。
很多企业已经经历了相当长的一段时间来进行持续的测试。然而,当我们展望未来时,很明显,即使是持续测试也是不够的。我们正在快速接近一个新时代,持续测试将无法跟上不断缩短的交付周期、技术复杂性增长以及变化的速度。
在一个软件将实时处理难以想象的数据点的时代里,例如,无论是从物联网,还是“自动驾驶”。除了持续测试外,我们还需要“数字测试”(Digital Testing)来实现进一步的加速,并满足未来由物联网、机器人技术和量子计算所驱动的质量需求。人工智能,模仿智能人类行为的机器学习和预测分析,可以帮助我们到达那里。
通过日志分析,实现 Kubernetes Helm Release 的自动回滚
DevSecOps - DevOps 与 安全理念的碰撞
DevOps 在2018年的五个趋势
微服务构建持久 API 的7大规则
▽ 点击“ 阅读原文” ,进入 JFrog 官网