0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

三种Mock测试方案的应用与实践总结

Testin云测 来源:毕小烦 2024-04-28 17:50 次阅读

Mock 这个词对于测试人员来说并不陌生,当我们要测试的接口 A 依赖接口 B ,可 B 无法满足我们的测试需求时,需要 Mock 一下接口 B,来测试 A。当前端和服务端并行开发时,如果服务端接口还没有开发好,前端同学也会 Mock 一下。

那 Mock 到底是什么?

维基百科:

在面向对象程序设计中,模拟对象(英语:mock object,也译作模仿对象)是以可控的方式模拟真实对象行为的假的对象。程序员通常创造模拟对象来测试其他对象的行为,很类似汽车设计者使用碰撞测试假人来模拟车辆碰撞中人的动态行为。

注意这里的关键信息,以可控的方式,模拟真实对象行为,假的对象。

为什么要模拟呢?

一定是因为没有办法或者不需要用真实的服务,比如:

真实的对象还没开发好,但你又急需测试;

真实的对象是第三方的(比如各种开放平台),没有提供联调环境,或是不便联调,或是搭建很麻烦;

真实的对象无法覆盖你要的测试场景(比如网络错误),而使用 Mock,你想要什么就可以模拟什么;

真实的对象速度很慢,而模拟的非常快;

等等。

这些情况下,模拟对象是一个非常好的解决方案,它可以让你的测试不被阻断,还能模拟出你想要的各种场景。

但模拟,不是真实,模拟是按照我们设定的剧本在走,是我们自己控制的,而真实的情况可能存在各种不确定性,所以不能完全相信 Mock。另外,Mock 是把真实对象模拟了一遍,如果真实对象改了,模拟对象也得跟着改,数量一多,维护起来也是十分的麻烦。

怎么 Mock ?

本文介绍我们团队在实际的项目中遇到的 3 种 Mock 场景,以及我们的设计方案。

案例1. Mock HTTP:通过域名映射实现 Mock

项目背景

我们要测试一个 HTTP 接口,这个接口在服务内部的处理会因地区不同而存在差异,虽然对外提供的业务接口只有 1 个,但在服务内部,如果判断是 A 地区就会去调用 A 地区的接口,B 地区会去调用 B 地区的接口,不同地区通过域名区分。

比如,要测的是登录接口 test.com/login,到了内部处理时就会因不同的地区去调用不同接口:

A 地区会调用:test.a.com/login

B 地区会调用:test.b.com/login

C 地区会调用:test.c.com/login

......

如下所示:

9a00678a-050f-11ef-a297-92fbcf53809c.jpg

为了便于测试,我们需要 Mock 各个地区的接口,应该怎么做呢?

设计方案

方案如下:

9a24424a-050f-11ef-a297-92fbcf53809c.jpg

在「中台」所在的服务器上,将调用 A 地区接口的域名通过 hosts 中的配置映射到 Mock 平台的 IP。配置好以后,「中台」调用 A 地区的接口时,请求都会转发到 Mock 服务器上,然后我们就可以在 Mock 服务器上对具体的接口进行配置,定制返回信息;

需要 Mock 多个地区时,将对应域名加到 hosts 里映射即可。当然也可以 Mock 一个固定的域名,如 test.mock.com,然后每个地区的域名进行配置化(配置中心)。当我们要 Mock 某个地区时,只需将该地区的配置的域名改为 test.mock.com 即可,这样就不用去修改 hosts 文件了。

这种方案的优点是:

没有代码侵入,域名可通过 hosts 进行配置,将不同的域名映射到 Mock 服务器;

配置简单,没有什么门槛;

缺点是:

依赖的数据需要我们自己来配置,这需要额外投入精力去研究被依赖服务的接口信息,还要维护 Mock 数据;

Mock 控制粒度比较粗。在无任何代码侵入的前提下,比如在测试 A 地区的接口时,需将被调用的所有接口都进行 Mock,而不能只 Mock 其中几个接口。

仅支持 Mock HTTP 请求。

案例2. Mock RPC:基于 AOP 实现 Mock

项目背景

这个项目对另外一个项目有强依赖,并且我们对这个 Mock 方案的要求是,除了能满足我们自己的常规测试外,还要能提供给外部客户进行快速对接、联调,要能支持 HTTP 和 RPC(Dubbo)。

设计方案

为了满足这个需求,我们开发了Mock SDK

SDK 中包含几个拦截器:

AbstractAspect类:是一个抽象切面拦截器,是其它拦截器的父类,提供了一些抽象方法让子类实现,以及一些通用的方法。

ControllerAspect类:HTTP 接口拦截器,负责获取接口的 URL、获取全部请求头、获取全部请求参数、获取全部请求体数据。

FacadeAspect类:Dubbo 接口拦截器,负责获取方法名及其参数。

AnnotationsAspect类:注解切面拦截器,当 Java 类不在 client 下,但是需要 Mock 对应的方法时,可以在该方法前加上注解@Mock。

使用时只需:

在pom文件中引入 Mock SDK;

spring-scan-bean配置 Mock 的工具类,加载到 spring 上下文容器中;

设置 Mock 开关配置。开启 Mock 模式时,默认会对所有controller中的接口、client中的 Dubbo 方法以及所有加了 Mock 注解的方法进行拦截。

方案如下:

9a45c460-050f-11ef-a297-92fbcf53809c.jpg

这种方案的优点是:

支持 Mock HTTP,提供给客户联调测试时可在controller层进行 Mock,但不推荐这么做,客户自己 Mock HTTP 接口会更灵活;

支持 Mock RPC,我们自己测试时可在client层进行 Mock;

Mock 粒度更细:支持按接口粒度进行 Mock,还支持单个 Java 方法添加注解来实现 Mock;

Mock 节点灵活:controller层、client层、或加了 Mock 注解的 Java 方法均可。

缺点是:

性能问题:在 Mock 开启模式下,每次请求都会去判断是否存在 Mock 对象,接口性能会有一定程度受影响。

Dubbo 接口目前只在client层做的切面,所以在 Mock 平台配置返回值时,出参字段没办法从接口文档中直接获取,因为client层的出参字段与接口文档的参数字段不完全一致。

存在代码侵入。就算在 Mock 配置为关闭的情况下,仍会生成一个无逻辑的切面。

案例3. Mock Python:基于数据存储中间件实现 Mock

项目背景

该项目也是需要对接多个区域,不同区域的接口存在很大差异,而且被测服务的末端是 Python 服务。另外一个重要的点是:该项目的测试数据非常有限且不可重复利用。

其实用「方案1」去 Mock 接口也是可以的,但:

需要花很多时间去预研 Mock 数据;

被依赖服务的接口加解密方式、调用链路差异很大;

配置成本过高:比如一个登录功能,有些区域可能需要调 5 个接口,有些可能要 7 个接口才能实现;为了实现一个业务功能,往往需要配几十个接口的 Mock。

因此在权衡了时间、资源、风险利弊之后,我们采取了新的 Mock 方案 —— 基于数据存储中间件的 Mock,我们用的是 Redis。

设计方案

基于数据存储中间件的 Mock 方案其实是在被测服务中加入 Mock 逻辑,当启用 Mock 时,直接从 Redis 获取数据,而不去请求真实的数据,这就实现了 Mock 的目的。

9a6b02c0-050f-11ef-a297-92fbcf53809c.jpg

Mock 方法:

配置 Mock 开关,便于开启和关闭;

在 Redis 中配置 Mock 对应的Key/Value;

优点:

无需额外搭建 Mock 平台,研发投入成本低;

无需关注各区域接口差异,Mock 的数据格式统一;

配置和维护成本低,也可编写脚本实现批量 Mock。

缺点:

业务代码验证不全,Python 服务的业务代码是验证不到的。所以,Mock 测试之后,还要用仅存的真实数据去验证一遍。

存在代码侵入。为实现 Mock 功能,存在非业务性逻辑。

总结

上述这 3 个案例就是我们在实际项目中遇到并实践过的 Mock 方案,当然还有其他的方案,这需要结合项目的实际情况综合评估风险、资源、利弊后再做选择。本文只是提供了一些思路,希望对大家有所启发。

审核编辑:黄飞

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • HTTP
    +关注

    关注

    0

    文章

    468

    浏览量

    30479
  • 数据存储
    +关注

    关注

    5

    文章

    928

    浏览量

    50689
  • 服务端
    +关注

    关注

    0

    文章

    66

    浏览量

    6910

原文标题:我们用到的3种Mock测试方案

文章出处:【微信号:TestinChina,微信公众号:Testin云测】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    步进电机的三种驱动方式

    步进电机的三种驱动方式
    发表于 01-12 17:03

    三种SMA接口pcb封装

    `三种SMA接口pcb封装`
    发表于 01-25 16:04

    三种调整处理器系统功耗的方法分享

    Teledyne e2v为系统设计师提供的定制方案处理器功耗的背景知识三种调整处理器系统功耗的方法
    发表于 01-01 06:04

    FOC中的三种电流采样方式,你知道怎么选择吗?

    电阻,这三种采样方式都有其优点和缺点,方案的不同,对应的电流处理方式也就不同,系统最终运行的效果可能也会有差异,所以这三种方案也有其适用的场合。那么这篇文章会结合这
    发表于 03-19 13:46

    分享三种硬件方案助力网络系统安全

    分享三种硬件方案助力网络系统安全
    发表于 05-19 06:34

    主流的三种RF方案及其优缺点对比分析

    主流的三种RF方案及其优缺点对比分析RF IC的主要性能是什么?
    发表于 05-25 06:34

    常见的三种无线接入方式是什么?

    蓝牙无线组网的优点是什么?常见的三种无线接入方式是什么?蓝牙无线组网原理与上网方案分享
    发表于 05-26 06:33

    STM32的三种复位类型

    最近在项目的时候需要判别STM32的复位类型,网上这部分资料也有许多大神进行总结。但是感觉不是特别深入,因此,小编参考参考了STM32的参考手册进行详细总结了一下。1、STM32的三种复位类型分别为
    发表于 08-02 06:32

    STM32有三种启动模式

    01STM32的三种启动模式STM32有三种启动模式:FLASH启动、SRAM启动和系统存储器启动,通常三种启动方式由外部引脚boot0和boot1的电平决定。每个系列boot0和boot1电平对应
    发表于 08-18 07:52

    算法的三种结构介绍

    嵌入式学习日记2018.11.62018.11.16理论学习阶段计算机科学导论(原书第二版)第8章 算法学到的新知识1算法的三种结构:顺序、判断(选择)和重复(循环)2常用的算法:求和、乘积、找最小
    发表于 11-08 07:12

    STM32的三种boot模式介绍

    、示例验证总结参考资料任务摘要请说明STM32的三种Boot模式的差异,并在之前第11-12周“C语言各种变量的存储地址”作业代码基础上,研究至少两boot模式下,代码下载(烧录)运行后所在的地址位置,与理论对比验证。一、认识
    发表于 12-10 07:46

    STM32的三种Boot模式的差异

    如有错误,欢迎指正,谢谢!目录一、STM32的三种Boot模式的差异二、创建基于MDK创建纯汇编语言的STM32工程模板、汇编基本语法的学习四、编程练习一、STM32的三种Boot模式的差异参考自
    发表于 12-20 07:54

    shell中的三种引用符号是什么

    、shell中的三种引用符号1.转义符2.单引号3.命令替换符、变量表达式总结一、变量1.特殊符号特殊符号~:用户主目录、:反引号,放置的命令可先执行的指令,与$(指令)功能相同#:注释$:取用变量值或者运算值前导符&:将命令
    发表于 12-22 07:01

    记录三种DMA模式

    串口模式实现有三种1.普通模式:在主函数中接收函数2.中断模式:产生的不影响主程序运行3. DMA模式:与主函数互不影响,独立运行本文记录三种DMA模式。
    发表于 02-28 07:54

    深度剖析基于Python中的Mock

    我发现自己在学习mock的过程中遇到的主要困难是不清楚mock能做什么,而不是mock对象到底有哪些函数。因此写这篇文章的主要目的是为了说明mock能做什么。
    的头像 发表于 01-30 15:26 4458次阅读
    深度剖析基于Python中的<b class='flag-5'>Mock</b>