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"
    }

  • 相关阅读:
    Jungle Roads POJ 1251
    Light OJ 1234 Harmonic Number
    同余定理
    HDU---1052---田忌赛马
    田忌赛马---空手道俱乐部
    poj---1182---食物链
    Convenient Location(最短路之弗洛伊德)
    js动画实现透明度动画
    js动画实现侧边栏分享
    AngularJS 指令(使浏览器认识自己定义的标签)
  • 原文地址:https://www.cnblogs.com/jason2018524/p/13525886.html
Copyright © 2011-2022 走看看