当前位置:   article > 正文

深入接口测试之Mock技术_mock接口

mock接口

01为什么要用Mock

服务端与客户端约定了接口,但服务端还没有完成开发时,客户端一般由如下处理方式:

1、在程序中写模拟数据

  • 程序中增加垃圾代码,后期还要删除,可能对代码造成影响
  • 模拟异步请求不方便
  • 服务端接口开发完成后,需要重新书写网络请求部分的代码
  • JS、iOS、Android 多前端需要分别模拟数据,重复工作量

2、使用 Nginx、http-server 等 WebServer

  • 只支持 GET 请求
  • 无法针对请求进行校验或特定处理

3、自己写简单的程序模拟返回数据

  • 开发期间 API 还处于频繁变动时期,持续调整成本较高

以上方法均不方便做单元测试对于需要演示的场景,没有后端业务服务器支撑,无法演示,客户端改造成本高所以要引入Mock技术

02Mock使用场景

在使用Mock的过程中,发现Mock是有一些通用性的,对于一些应用场景,是非常适合使用Mock的:

1)真实对象具有不可确定的行为(产生不可预测的结果,如股票的行情)

2)真实对象很难被创建(比如具体的web容器)

3)真实对象的某些行为很难触发(比如网络错误)

4)真实情况令程序的运行速度很慢

5)真实对象有用户界面

6)测试需要询问真实对象它是如何被调用的(比如测试可能需要验证某个回调函数是否被调用了)

7)真实对象实际上并不存在(当需要和其他开发小组,或者新的硬件系统打交道的时候,这是一个普遍的问题)当然,也有一些不得不Mock的场景:

8)一些比较难构造的Object:这类Object通常有很多依赖,在单元试中构造出这样类通常花费的成本太大;

9)执行操作的时间较长Object:有一些Object的操作费时,而被测对象依赖于这一个操作的执行结果,例如大文件写操作,数据的更新等等,出于测试的需求,通常将这类操作进行Mock;

10)异常逻辑:一些异常的逻辑往往在正常测试中是很难触发的,通过Mock可以人为的控制触发异常逻辑;

11)在一些压力测试的场景下,也不得不使用Mock,例如在分布式系统测试中,通常需要测试一些单点(如namenode,jobtracker)在压力场景下的工作是否正常。而通常测试集群在正常逻辑下无法提供足够的压力(主要原因是受限于机器数量),这时候就需要应用Mock去满足;

12)在mock点的选择过程中,以下的一些点会是一些不错的选择 网络交互:如果两个被测模块之间是通过网络进行交互的,那么对于网络交互进行Mock通常是比较合适的,如RPC;

13)外部资源:比如文件系统、数据源,如果被测对象对此类外部资源依赖性非常强,而其行为的不可预测性很可能导致测试的随机失败,此类的外部资源也适合进行Mock;

14)UI:因为UI很多时候都是用户行为触发事件,系统本身只是对这些触发事件进行相应,对这类UI做Mock,往往能够实现很好的收益,很多基于关键字驱动的框架都是基于UI进行Mock;

15)第三方API:当接口属于使用者,通过Mock该接口来确定测试使用者与接口的交互。当然如何做Mock一定是与被系统的特性精密关联的,一些强制性的约束和规范是不合适的。

  1. ​现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
  2. 如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
  3. 可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
  4. 分享他们的经验,还会分享很多直播讲座和技术沙龙
  5. 可以免费学习!划重点!开源的!!!
  6. qq群号:485187702【暗号:csdn11

03、Mock工具的选择

Mock测试工具分为单元测试级别的Mock工具和接口测试级别的Mock工具。

一、单元测试级别的Mock工具

目前,这个级别的Mock工具有easymock、jMock、Mockito、Unitils Mock、PowerMock、JMockit等等。

就目前来讲,是mockit+PowerMock、JMockit这两种工具使用人数较多。JMockit的功能最为完善,mockit+PowerMock的用户体验相对较好一点。

二、接口测试级别的Mock工具

接口级别的Mock工具完成的主要功能是对一个用户的请求,模拟server返回一个接口的响应数据。

目前,这类的主流mock工具主要有以下几种

1)Wiremock

  1. 特点:
  2. - 支持Http响应头,匹配URL,head和body内容模式
  3. - 请求验证
  4. - 可以作为一个独立的进程或者WAR app在单元测试中运行
  5. - 可以通过Java API,Json文件和JSON over HTTP配置
  6. - 有记录/回放功能
  7. - Fault injection
  8. - 可以作为请求检查和替换的浏览器代理
  9. - 有状态的行为模拟
  10. - 可配置响应延迟

2)Mockserver

  1. 特点:
  2. - 能够mock HTTP或者HTTPS 的server或者服务
  3. - 当一个请求匹配 expectation时能够返回一个mock response
  4. - 当一个请求匹配 expectation时能够forward 一个请求
  5. - 当一个请求匹配 expectation时能够执行一个回调
  6. (callback),允许动态地创建response
  7. - 支持Request验证

3)Moco

4)Mock.js

5)RAP

这些了解即可;

04搭建Mock平台

这里使用wiremock环境搭建Mock平台,具体方法如下:

WireMock 的独立安装版本其实就是一个Jar包,可以从Maven仓库中下载或者也可以在Java Maven项目中通过 pom.xml的依赖添加:

  1. <dependency>
  2. <groupId>com.github.tomakehurst</groupId>
  3. <artifactId>wiremock-jre8-
  4. standalone</artifactId>
  5. <version>2.26.3</version>
  6. <scope>test</scope>
  7. </dependency>

除了Standalone 版本, 也可以直接在 Java代码中引用,对应Maven依赖:

  1. <dependency>
  2. <groupId>com.github.tomakehurst</groupId>
  3. <artifactId>wiremock-jre8</artifactId>
  4. <version>2.26.3</version>
  5. <scope>test</scope>
  6. </dependency>

WireMock 命令行用法

WireMock 的独立版本是一个 Jar 包,所以运行 Wiremock 自然是需要 Java 基础环境,命令如下:

java -jar wiremock-standalone-2.26.3.jar

命令行支持的一些主要参数及其作用说明如下:

  • --port 设置 Mock 服务的 http 端口,默认启动在 8080 端口
  • 如果设置为0,则自动确定端口
  • --https-port 设置 https 的端口
  • --verbose 在终端显示详细的日志信息
  • --root-dir 设置 mappings 和 __files 目录的工作路径
  • --enable-browser-proxying 以浏览器代理的方式运行

单来说,WireMoc 会在本地启动一个侦听指定端口的web服务,这里指定的端口可以用 --port 指定http协议 或 --httpsport指定https协议端口。启动后我们发到指定端口的请求,就会由WireMock来完成响应,达到接口Mock的目的,命令行启动后如图:

启动后,我们在本地运行目录下会看到 WireMock会自动生成__files 和 mappings两个目录。这两个目录中存放的就是Mock模拟的接口匹配内容了。

  • __files 存放接口响应中会用到的一些文件资源
  • mappings 存放接口响应匹配规则

具体的匹配方法我们后面再介绍,这里先介绍下WireMock本身自带的Admin接口。

Wiremock Admin 接口

WireMock 本身支持管理接口,启动后根据启动的端口,访问http://localhost:8080/__admin/docs/ ,可以看到如下两个链接:

  1. OpenAPI 3.0 spec
  2. Swagger UI

可以用 Swagger UI接口定义格式查看支持的管理接口

http://localhost:8080/__admin/swagger-ui/

05WireMock基本用法

1)在mappings下创建一个*.json文件

  1. {
  2. "request": {
  3. "method": "GET",
  4. "url": "/api/mocktest"
  5. },
  6. "response": {
  7. "status": 200,
  8. "bodyFileName": "response.json",
  9. "headers": {
  10. "Content-Type": "application/json",
  11. "Cache-Control": "max-age=86400"
  12. }
  13. }
  14. }

bodyFileName还可以是html、xml等类型的文档。

2)在__files下创建响应文件

上例中response.json 就是需要我们在__files里面建立的响应文件。其内容为:

  1. {
  2. "test":"wiremock"
  3. }

在浏览器或者使用curl命令,调用

http://localhost:8080/api/mocktest ,就能返回test.json的内容了。

当然,你也可以不用创建这个文件,直接在request中将

bodyFileName改成直接body写出这个json也可以:

  1. {
  2. "request": {
  3. "method": "GET",
  4. "url": "/api/mocktest"
  5. },
  6. "response": {
  7. "status": 200,
  8. "body": "{\"test\":\"wiremock\"}",
  9. "headers": {
  10. "Content-Type": "application/json",
  11. "Cache-Control": "max-age=86400"
  12. }
  13. }
  14. }

06Wiremock支持的HTTP方法

1)POST

  1. http://localhost:8080/api/products
  2. {"request": {
  3. "method": "POST",
  4. "url": "/api/products",
  5. "bodyPatterns": [{
  6. "equalToJson": "{ \"name\": \"new
  7. product\", \"creator\": \"tester\", \"createTime\":
  8. \"2015-09-07\" }",
  9. "ignoreArrayOrder" : true,
  10. "ignoreExtraElements" : true
  11. }]
  12. },
  13. "response": {
  14. "status": 201,
  15. "body": "Add successfully.",
  16. "headers": {
  17. "x-token":
  18. "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  19. }
  20. }
  21. }

bodyPatterns 请求正文的匹配模式,包括equalToJson 匹配JSON数据, ignoreArrayOrder 是否区分JSON数组元素顺序,ignoreExtraElements 是否忽略额外的元素

2)PUT

  1. http://localhost:8080/api/products/1
  2. {
  3. "request": {
  4. "method": "PUT",
  5. "url": "/api/products/1",
  6. "bodyPatterns": [{
  7. "equalToJson": "{ \"id\": 1, \"name\":
  8. \"new product\", \"creator\": \"tester\",
  9. \"createTime\": \"2015-09-07\" }",
  10. "ignoreArrayOrder" : true,
  11. "ignoreExtraElements" : true
  12. }]
  13. },
  14. "response": {
  15. "status": 200,
  16. "body": "Update successfully.",
  17. "headers": {
  18. "x-token": "
  19. xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  20. }
  21. }
  22. }

3) DELETE

  1. http://localhost:8080/api/products/1
  2. {
  3. "request": {
  4. "method": "DELETE",
  5. "url": "/api/products/1"
  6. },
  7. "response": {
  8. "status": 204,
  9. "headers": {
  10. "x-token": "
  11. xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  12. }
  13. }
  14. }

4)URL Matching

  1. http://localhost:8080/api/products/12/3…)
  2. {
  3. "request": {
  4. "method": "GET",
  5. "urlPattern": "/api/products/[0-9]+"
  6. },
  7. "response": {
  8. "status": 200
  9. }
  10. }

5)Query参数匹配

  1. http://localhost:8080/api/products?
  2. search=china
  3. {
  4. "request": {
  5. "method": "GET",
  6. "urlPath": "/api/products",
  7. "queryParameters": {
  8. "search": {
  9. "contains": "chin"
  10. }
  11. }
  12. },
  13. "response": {
  14. "status": 200,
  15. "headers": {
  16. "Content-Type": "application/json"
  17. },
  18. "body": "{ \"id\": 7, \"name\": \"shan
  19. zai\", \"from\":\"China\" },{ \"id\": 7, \"name\":
  20. \"shan zai\", \"from\":\"China(RPC)\" }"
  21. }
  22. }

6)模拟错误

  1. {
  2. "request": {
  3. "url": "/unknown.html",
  4. "method": "GET"
  5. },
  6. "response": {
  7. "status": 404,
  8. "headers": {
  9. "Content-Type": "text/html; charset=utf-
  10. 8"
  11. }
  12. }
  13. }

7)设置响应延时

  1. {
  2. "request": {
  3. "method": "GET",
  4. "url": "/delayed"
  5. },
  6. "response": {
  7. "status": 200,
  8. "bodyFileName": "response.json",
  9. "headers": {
  10. "Content-Type": "application/json",
  11. "Cache-Control": "max-age=86400"
  12. },
  13. "fixedDelayMilliseconds": 2000
  14. }
  15. }

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走! 希望能帮助到你!【100%无套路免费领取】

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/477186
推荐阅读
相关标签
  

闽ICP备14008679号