zoukankan      html  css  js  c++  java
  • Mock技术的使用

    Mock是什么

    • 在软件测试过程中,对一些不容易构造、获取的对象,用一个虚拟的对象来替代它,以达到相同的效果,这个虚拟的对象就是Mock。
    • 在前后端分离项目中,当后端工程师还没有完成接口开发的时候,前端开发工程师利用Mock技术,自己用mock技术先调用一个虚拟的接口,模拟接口返回的数据,来完成前端页面的开发。
    • 接口测试和前端开发有一个共同点,就是都需要用到后端工程师提供的接口。所以,当我们做接口测试的时候,如果后端某些接口还不成熟、所依赖的接口不稳定或者所依赖的接口为第三方接口、构造依赖的接口数据太复杂等问题时,我们可以用mock的方式先虚拟这些接口返回来代替,提高工作效率。

    Mock的介绍

    • 实现mock的技术很多,这些技术中,可以分为两类,mock数据和mock服务
      • mock数据:即mock一个对象,写入一些预期的值,通过它进行自己想要的测试。常见有:EasyMock、Mockito、WireMock、JMockit,主要适用单元测试。
      • mock服务:即mock一个sever,构造一个依赖的服务并给予他预期的服务返回值,适用范围广,更加适合集成测试,如:moco框架。
    • Moco是类似一个Mock的工具框架,一个简单搭建模拟服务器的程序库/工具,下载就是一个JAR包,有如下特点
      • 只需要简单的配置request、response等即可满足要求
      • 支持http、https、socket协议,可以说是非常的灵活性
      • 支持在request中设置Headers,Cookies,StatusCode等
      • 对GET、POST、PUT、DELETE等请求方式都支持
      • 无需环境配置,有Java环境即可
      • 修改配置后,立刻生效。只需要维护接口,也就是契约即可
      • 支持多种数据格式,如JSON、Text、XML、File等
      • 可与其他工具集成,如Junit、Maven等,

     Mock环境的搭建步骤

    [
      {
        "description": "demo",
        "request": {
          "uri": "/demo1"
        },
        "response": {
          "text": "Hello,demo1"
        }
      }
    ]
    • 接着,在有Java环境的机器上通过指定json文件启动mock服务,启动命令:java -jar moco-runner-1.1.0-standalone.jar http -p 8888 -c test.json
    • 最后,请求接口查看返回数据,访问地址:http://ip:8888/demo1

    Mock模拟不同的请求接口

    1、约定GET请求方式接口并指定参数

    [
      {
        "description": "GET请求,并定义了请求参数,使用queries",
        "request": {
          "uri": "/request-get",
          "method": "GET",
          "queries": {
            "key1": "abc",
            "key2": "123"
          }
        },
        "response": {
          "headers": {
            "Content-Type": "text/plain;charset=utf-8"
          },
          "text": "Hello,这是第一个mock的Get请求接口!!!"
        }
      }
    ]
    def mock_get() -> None:
        """
        description: mock模拟get请求,需要使用已经定义的请求参数
        :return: None
        """
        # 构建请求url,请求参数
        url = f"{MOCK_HOST}/request-get"
        param = {
            "key1": "abc",
            "key2": "123"
        }
        response = requests.get(url=url, params=param)
        print(response.text)

    输出结果:Hello,这是第一个mock的Get请求接口!!!

    2、约定POST请求方式接口并指定参数(表单格式:forms)

    [
        {
            "description": "POST请求,并定义请求参数form格式,使用forms",
            "request": {
              "uri": "/request-post",
              "method": "POST",
              "forms": {
                "key1": "ABC"
              }
            },
            "response": {
              "headers": {
                "Content-Type": "text/plain;charset=utf-8"
              },
              "text": "Hello,这是第一个mock的Post请求接口!!!"
            }
        }
    ]
    def mock_post_forms() -> None:
        """
        description: mock模拟post请求,使用自定义请求参数(表单格式)
        :return: None
        """
        # 构建请求url,请求参数
        url = f"{MOCK_HOST}/request-post"
        forms = {
            "key1": "ABC"
        }
        response = requests.post(url=url, data=forms)
        print(response.text)

    输出结果:Hello,这是第一个mock的Post请求接口!!!

    3、约定POST请求方式接口并指定参数(JSON格式:json)

    [
        {
            "description": "POST请求,并定义请求参数json格式,使用json",
            "request": {
              "uri": "/request-post-json",
              "method": "POST",
              "json": {
                "key1": "aaa"
              }
            },
            "response": {
              "headers": {
                "Content-Type": "application/json;charset=utf-8"
              },
              "status": 200,
              "json": {
                "key1": "aaa,post json!"
              }
            }
          }
    ]
    def mock_post_json() -> None:
        """
        description: mock模拟post请求,使用自定义请求参数(json格式)
        :return: None
        """
        # 构建请求url,请求参数
        url = f"{MOCK_HOST}/request-post-json"
        json = {
            "key1": "aaa"
        }
        response = requests.post(url=url, json=json)
        response.encoding = 'unicode_escape'
        print(response.json())

    输出结果:{'key1': 'aaa,post json!'}

    4、约定重定向接口

    [
        {
            "description": "模拟重定向接口",
            "request": {
              "method": "GET",
              "uri": "/redirect"
            },
            "redirectTo": "https://www.baidu.com/"
        }
    ]

    访问地址:http://ip:8888/redirect,会重定向到“https://www.baidu.com”

    5、约定URI的“uri-startsWith”开始匹配

    [
        {
            "description": "约定uri-startsWith匹配",
            "request": {
                "uri": {
                    "startsWith": "/sq"
                }
            },
            "response": {
                "text": "Hello,uri-startWith!!!"
            }
        }
    ]

    访问地址:http://ip:8888/sqxxx,都可以访问该请求

    6、约定URI的“uri-endWith”结束匹配

    [
        {
            "description": "约定uri-endsWith匹配",
            "request": {
                "uri": {
                    "endsWith": "sq"
                }
            },
            "response": {
                "text": "Hello,uri-endWith!!!"
            }
        }
    ]

    访问地址:http://ip:8888/xxxsq,都可以访问该请求

    7、约定URI的“uri-contain”包含匹配

    [
        {
            "description": "约定uri-contain匹配",
            "request": {
                "uri": {
                    "contain": "sq"
                }
            },
            "response": {
                "text": "Hello,uri-contain!!!"
            }
        }
    ]

    访问地址:http://ip:8888/xxsqxxx,都可以访问该请求

    8.约定URI的返回状态码

     [
        {
            "description": "约定响应状态码",
            "request": {
                "uri": "/return_code"
            },
            "response": {
                "status": 200
            }
        }
    ]

    访问地址:http://ip:8888/return_code,接口返回相应的状态码

    Python请求Mock模拟的接口示例

    • mock定义了请求的参数和返回值,如果请求的参不是预定的值,就无法请求成功
    [
        {
            "description": "支付接口",
            "request": {
                "headers": {
                    "Content-Type": "application/json"
                },
                "json": {
                    "auth_code": "28763443825664394",
                    "buyer_id": "2088202954065786",
                    "out_trade_no": "20150320010101001",
                    "seller_id": "2088102146225135",
                    "subject": "Iphone6",
                    "total_amount": "88.88"
                },
                "method": "POST",
                "uri": "/trade/purchase"
            },
            "response": {
                "headers": {
                    "Content-Type": "application/json"
                },
                "json": {
                    "code": "40004",
                    "msg": "Business Failed",
                    "out_trade_no": "6823789339978248",
                    "sub_code": "ACQ.TRADE_HAS_SUCCESS",
                    "sub_msg": "交易已被支付",
                    "trade_no": "2013112011001004330000121536"
                }
            }
        }
    ]
    def mock_post_pay() -> None:
        """
        description: mock模拟支付接口
        :return: None
        """
        # 构建请求url,请求参数
        url = f"{MOCK_HOST}/trade/purchase"
        json = {
            "out_trade_no": "20150320010101001",
            "auth_code": "28763443825664394",
            "buyer_id": "2088202954065786",
            "seller_id": "2088102146225135",
            "subject": "Iphone6",
            "total_amount": "88.88"
        }
        response = requests.post(url=url, json=json)
        print(response.json())

    输出结果:

    {
      "code": "40004",
      "msg": "Business Failed",
      "out_trade_no": "6823789339978248",
      "sub_code": "ACQ.TRADE_HAS_SUCCESS",
      "sub_msg": "交易已被支付",
      "trade_no": "2013112011001004330000121536"
    }

  • 相关阅读:
    Maximum Depth of Binary Tree
    Single Number
    Merge Two Sorted Lists
    Remove Nth Node From End of List
    Remove Element
    Remove Duplicates from Sorted List
    Add Two Numbers
    编译视频直播点播平台EasyDSS数据排序使用Go 语言 slice 类型排序的实现介绍
    RTMP协议视频直播点播平台EasyDSS在Linux系统中以服务启动报错can’t evaluate field RootPath in type*struct排查
    【解决方案】5G时代RTMP推流服务器/互联网直播点播平台EasyDSS实现360°全景摄像机VR直播
  • 原文地址:https://www.cnblogs.com/jason2018524/p/13525886.html
Copyright © 2011-2022 走看看