CODING DevOps 系列第五课:微服务测试——微服务下展开体系化的微服务测试
微服务测试的痛点与挑战
这张图可以形象地展示单体服务和微服务的对比,单体应用就像左边巨大的集装箱,软件模块和应用都包括其中;而微服务就像是由一个小集装箱组成,微小的服务组成一个庞大、完整的系统。单体服务是一个大而全的应用体,而微服务由拆分成出来的很多小服务来组成一个庞大而完整的系统。
微服务是一种架构模式,是面向服务型架构 SOA 的一种变体,提倡将单一应用程序逐渐还原划分成小的服务,服务间互相协调、互相配合,为用户提供最终价值。微服务架构风格就是一些小而自治的服务协同工作形成松耦合的系统。另外,我们需要尽量避免一个统一的、集中式的服务管理机制,对具体的一个服务而言,应该根据上下文选择合适的语言工具对其进行构建。
结合下方的这张图,我们可以理解微服务构建的核心其实是中间领域的业务逻辑,围绕着这个领域业务逻辑,会有一些微服务去进行拆分构建。
微服务具有专注、自治、独立进程、独立部署和技术异构的特点,即每个服务只限定于特定的业务而专注做一件事情,每个服务承担的是单一职责,但是它也需要达到一定规模能够完整的处理特定的领域业务。很多人都会被微服务的“微”这个词所误导,认为微服务就是要拆分的越小越好。但是其实为了“微”而将同一领域的业务拆分到不同的服务,只会徒劳增加软件的复杂度和维护困难。
我们可以围绕应用的业务能力进行分组,每个小组的开发组人员开发微服务的技术可以不受限制。每个服务小组可以使用不同的技术架构和存储技术,有针对性地解决一些性能瓶颈问题。每个服务是互相独立部署互不影响的,这样的话我们可以实现独立打包、独立测试和独立附属,减少部署时间,提升研发效率。
微服务架构测试具有三个痛点:一、如何测试微服务的外部依赖是否正常;二、如何在微服务架构下验证系统的整个功能是否符合预期;三、这么多微服务的部署和测试,应如何开展。按照以上痛点我们可以看到,微服务测试是一种验证成本高、结果不稳定、反馈周期长的测试。
测试金字塔
测试金字塔其实是一种方法论,解决微服务测试的关键在于将微服务的测试按照不同的力度来分组。测试金字塔的概念由麦克科恩首先提出。测试是分层次的,我们看到图片左边,这个金字塔被分为三个层次,从下往上分别是单元测试、服务测试、界面测试,从下往上测试的运行速度是逐渐减慢的,外物依赖或者服务间的依赖从下到上会依赖更多。这个测试金字塔的另外一个重要特征是,从下往上对每一层的测试代码是逐层减少的。下方应该写一些小而快的测试,往上应该编写一些粗粒度的测试,编写更少的高层次测试。
然而实际中如果以这个金字塔图来作为指导,会过于笼统简单,所以我们会采用右边的分为四层的测试金字塔来做内部测试的指导思想。底层是单元测试,在这之上是集成测试,再往上是端到端的测试,顶层是探索测试。
作为开发人员或测试人员,应该关注金字塔的哪些部分呢?微服务开发人员应更多关注位于塔基底部的单元测试与集成测试。在这两层需要开发人员编写一定量的测试代码来保证覆盖,应该写许多小而快的单元测试覆盖绝大部分的业务场景,再写一定的粗粒度的集成测试,来测试重要系统之间外部依赖的交互是否正常。测试人员和质量保证人员应更多关注金字塔上面两层,测试人员可以依据 BDD 的规范来编写测试用例,用于校验系统功能的交互是否正常,还可以用非常规的手段进行破坏性的探索测试。
单元测试是测试金字塔的底基,它的定义没有标准答案。从编程角度来看,在函数式语言中我们可以认为一个函数是一个单元,在面向对象的语言中一个方法或者一个类可以表示一个单元。单元测试具有能够及时发现 bug、利于重构、保证代码质量的优势,我们系统中需要编写得最多的其实就是单元测试。
微服务的测试一般是对入栈适配器、业务逻辑和出栈适配器这三部分进行测试。入栈适配器测试的是 Controller API 是否正确;业务逻辑部分测试 Service 业务逻辑是否正确,而出栈适配器部分测试的是 SQL 逻辑是否正确。单元测试一般会遵循一个通用的 3A 结构:Arrange,Act,Assert,这样写出来的代码更有阅读性和表达力。
在微服务架构下我们所理解的集成测试是测试应用与外部依赖的集成。第三方外部服务依赖主要有两种类:第一种是微服务会依赖第三方系统的服务;第二种是系统内部的微服务与微服务之间,一种服务可能会依赖另一种微服务来实现自身逻辑。对应这两种情况会有不同的策略,第一种策略是准备真实的外部服务的依赖,第二种是使用测试替身隔绝外部依赖。进行集成测试的时候我们通常会使用一些,依赖第三方服务的话会采用 WireMock 或者 mountebank,而微服务之间的依赖调用会使用 Spring-Cloud-Contract 或者 Pact。
微服务之间的测试会使用契约测试,服务之间的接口文档就是一个契约。契约测试可以解决联调成本过高,接口变动把控困难,契约变化时提供一种可立即被服务端和消费端发现的方式,这三种痛点。契约测试的提供者指微服务接口的提供者,消费者指微服务接口的消费者。契约文件是微服务提供者和消费者共同定义的接口规范,包括接口的访问路径和输出数据。
CDC 的核心思想在于从消费者业务实现的角度出发,由消费者自己定义需要的测试数据格式以及交互细节,并驱动生成一份消费者契约。然后生产者根据契约来实现自己的逻辑,并在服务提供者端进行测试验证。契约文档应该被转换成一个存根。生产者会根据契约编写契约验证测试,契约验证测试通过会将契约文件转换为存根,存根会被消费者引用,契约的修改会导致任意一方测试的失败。这样的话可以保证契约被消费者和生产者共同遵守。
契约测试适用于微服务接口的消费者和提供者由不同的团队维护,或提供者接口被多个消费者消费这样的场景中。
端到端测试主要用于验证工作流程中的所有流程,以检查一切是否按照预期工作,确保系统以统一的方式工作,从而满足业务需求。端到端测试的难点在于安装和配置相关依赖,测试数据的自动准备二号服务的自动部署。
微服务测试蓝图
做微服务测试需要做 TDD,也就是测试在先,编码在后的开发实践。有别于以往的先编码、后测试的开发过程,而是在编程之前,先写测试脚本或设计测试用例。TDD 可以增加开发人员代码质量的信心,有利于代码设计和重构,以及快速迭代和持续交付。
微服务测试推进主要分为四步:第一步是工具,依照微服务测试层次,阶段选择合适的测试框架与工具;第二步是依据测试金字塔制定规范,贯穿生命周期始终,明确开发、测试人员的职责;第三步是自动化,贯穿 CI、CD 流程,与 DevOps 的融合;第四步是测试平台搭建,以容器化技术搭建测试平台,以 namespace 隔离不同测试环境。
CODING DevOps 系列第五课:微服务测试——微服务下展开体系化的微服务测试的更多相关文章
- CODING DevOps 系列第三课:云计算、云原生模式下 DevOps 的建设
本文首先会和大家分享当前整个应用生命周期的演变历程,然后讲解云计算模式下 DevOps 建设包含的过程.流程规范和标准,最后讲解云原生时代到来会带来哪些改变,以及标准化的建设会有哪些改变和突破. 应用 ...
- CODING DevOps 系列第四课:DevOps 中的质量内建实践
什么是质量内建 随着时间的推移,我们项目的开发效率会逐渐降低,直到几年之后整个项目可能就无法维护,只能推倒重来.具体的表现首先就是随着时间推移,我们会发现整个需求列表里面能做的需求越来越少,因为每当我 ...
- CODING DevOps 系列第一课:基于开源工具链打造持续交付平台
当下软件发展趋势 当今 IT 行业发展中比较流行的几个技术,首先是微服务化,将原有的一个系统拆分成多个,意味着有多个系统需要构建.测试.部署和运维. 第二个是敏捷开发模式,需求粒度更细化,要求一个可独 ...
- CODING DevOps 微服务项目实战系列第一课,明天等你
CODING DevOps 微服务项目实战系列第一课<DevOps 微服务项目实战:DevOps 初体验>将由 CODING DevOps 开发工程师 王宽老师 向大家介绍 DevOps ...
- CODING DevOps 微服务项目实战系列第二课来啦!
近年来,工程项目的结构越来越复杂,需要接入合适的持续集成流水线形式,才能满足更多变的需求,那么如何优雅地使用 CI 能力提升生产效率呢?CODING DevOps 微服务项目实战系列第二课 <D ...
- CODING DevOps 微服务项目实战系列最后一课,周四开讲!
随着软件工程越来越复杂化,如何在 Kubernetes 集群进行灰度发布成为了生产部署的"必修课",而如何实现安全可控.自动化的灰度发布也成为了持续部署重点关注的问题.CODING ...
- CODING DevOps 代码质量实战系列最后一课,周四发车
随着 ToB(企业服务)的兴起和 ToC(消费互联网)产品进入成熟期,线上故障带来的损失越来越大,代码质量越来越重要,而「质量内建」正是 DevOps 核心理念之一. <DevOps 代码质量实 ...
- CODING DevOps 代码质量实战系列第一课:代码规范与 Git Flow
讲师介绍 杨周 CODING DevOps 架构师 CODING 布道师 连续创业者.DIY/Linux 玩家.知乎小 V,曾在创新工场.百度担任后端开发.十余年一线研发和带队经验,经历了 ToB.T ...
- CODING DevOps 代码质量实战系列第二课: PHP 版
讲师介绍 杨周 CODING DevOps 架构师 CODING 布道师 连续创业者.DIY/Linux 玩家.知乎小 V,曾在创新工场.百度担任后端开发.十余年一线研发和带队经验,经历了 ToB.T ...
随机推荐
- Android_四大组件之BroadcastReceiver
一.概述 BroadcastReceiver是广播接收器,接收来自 系统或应用发出的广播信息 并进行相应的逻辑处理. 自定义BroadcastReceiver只需继承android.content.B ...
- @Spring Boot程序员,我们一起给程序开个后门吧:让你在保留现场,服务不重启的情况下,执行我们的调试代码
前言 这篇其实是对一年前的一篇文章的补坑. @Java Web 程序员,我们一起给程序开个后门吧:让你在保留现场,服务不重启的情况下,执行我们的调试代码 当时,就是在spring mvc应用里定义一个 ...
- 【Java8新特性】关于并行流与串行流,你必须掌握这些!!
写在前面 提到Java8,我们不得不说的就是Lambda表达式和Stream API.而在Java8中,对于并行流和串行流同样做了大量的优化.对于并行流和串行流的知识,也是在面试过程中,经常被问到的知 ...
- 设计MyTime类 代码参考
#include <iostream> #include <cstdio> using namespace std; class MyTime { private: int h ...
- Rocket - debug - TLDebugModuleInner - Abstract Command Decoding & Generation
https://mp.weixin.qq.com/s/0zKSTktxgzo5uCUphqaWSQ 介绍抽象命令的解码和生成. 1. accessRegisterCommandReg accessRe ...
- ActiveMQ 笔记(六)ActiveMQ的消息存储和持久化
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.持久化机制 1.Activemq持久化 1.1 什么是持久化: 持久化就是高可用的机制,即使服务器宕 ...
- Java实现 蓝桥杯VIP 算法训练 非递归(暴力)
试题 算法训练 非递归 问题描述 当x>1时,Hermite多项式的定义见第二版教材125页.用户输入x和n,试编写"非递归"函数,输出对应的Hermite多项式的值.其中x ...
- Java实现 LeetCode 547 朋友圈(并查集?)
547. 朋友圈 班上有 N 名学生.其中有些人是朋友,有些则不是.他们的友谊具有是传递性.如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友.所谓的朋友圈,是指 ...
- Java实现蓝桥杯VIP 算法训练 阶乘末尾
试题 算法训练 阶乘末尾 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给定n和len,输出n!末尾len位. 输入格式 一行两个正整数n和len. 输出格式 一行一个字符串,表示 ...
- 【Jquery】根据元素个数给予宽度
方法一: $(document).ready(function(){ $(".xn_mc_solu_2_ul").css("width", $(".x ...