一、requests简介

requests用来发送http请求以及接受http响应的python第三方库,主要用于接口自动化测试。

  • 安装:pip install requests

二、requests库常用的方法

  • requests.get()         url是接口地址,params用于传参
  • requests.post()       url是接口地址,data用于传参,json也用于传参
  • data和json传参的区别只要是通过请求头Content-Type来区分。
  • 请求:请求方式、请求路径、请求头、请求正文。
  • Content-Type
•     
• multipart/form-data 文件上传
• application/x-www-form-urlencoded  表单提交
• application/json 
• application/xml
• application/javascript
• application/binary
• text/html
    • data和json传参以及Content-Type的关系如下: 
        
    • data传参: 
          
    • 报文是dict类型,那么默认是Content-Type:applocation/x-www-form-urlencoded
    • 报文是str类型,那么默认是Content-Type:text/plain
    • json传参:报文可以是dict类型,默认是Context-Type:application/json
    • 所以: 
          
    • data:可以传纯键值对的dict(非嵌套的),也可以传str格式。
    • json:可以传任何形式的dict(包括嵌套的dict)
    • json与dict转换: 
          
    • json.loads()  把json字符串转化成dict格式
    • json.dumps() 把dict格式转化成json字符串
    • requests.put()
    • requests.delete()
    • requests.request()可以发送所有类型的请求:get、post、put、delete
    不管是get还是post还是put和delete,底层都是调用的requests.request()方法。
    而requests.request()调的是session.request()方法。主要参数:
    method,                                 请求方式
    url,                                         请求路径
    params=None,                      get方式传参
    data=None,                           post方式传参
    json=None,                           post方式传参
    headers=None,                     请求头
    cookies=None,                      请求cookie
    files=None,                            文件上传

    三、requests模块返回的response对象详解

    • response.json()       获得返回的字典格式的数据
    • response.text          获得返回的字符串格式的数据
    • response.content     获得返回的bytes格式的数据
    • response.status_code 状态码
    • response.reason          状态信息
    • response.cookies         cookies信息
    • response.headers         响应头
    • response.request.xxx    返回请求的数据,如:请求头、请求参数..

    四、请求必须带请求头的接口,以及需要cookie鉴权和session鉴权的接口

    90%以上的基于web的接口都有cookie鉴权。

    两种解决方式:

    1.使用cookie关联

    2.使用session关联

            requests.session().request()       使用同一个会话发起请求。

    import json
    import re
    
    import requests
    
    
    class TestRequest:
        # 全局变量,类变量
        access_token = ""
        csrf_token = ""
        php_cookie = ""
        sess = requests.session()
    
        # get请求:获取统一鉴权码token接口
        def test_get_token(self):
            url = "https://api.weixin.qq.com/cgi-bin/token"
            data = {
                "grant_type": "client_credential",
                "appid": "wx7ff6c1d5ba45d17e",
                "secret": "4b5fe134130b7c292d6a6c22f38b56d0"
            }
            res = requests.request(method="get", url=url, params=data)
            print(res.json())
            TestRequest.access_token = res.json()['access_token']
    
        # post请求:编辑标签接口
        def test_edit_flag(self):
            url = "https://api.weixin.qq.com/cgi-bin/tags/update?access_token=" + TestRequest.access_token
            data = {"tag": {"id": 101, "name": "广东人"}}
            str_date = json.dumps(data)
            res = requests.request(method="post", url=url, data=str_date)
            print(res.json())
    
        # 文件上传
        def test_file_upload(self):
            url = "https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=" + TestRequest.access_token
            data = {
                "media": open(r"E:\developer\idea\workspace\autotest_pytest\image.png", "rb")
            }
            res = requests.request(method="post", url=url, files=data)
            print(res.json())
    
        # 访问首页接口
        def test_start(self):
            url = "http://47.107.116.139/phpwind/"
            # res = requests.request(method="get", url=url)
            # 通过sess请求,就不用cookies
            res = TestRequest.sess.request(method="get", url=url)
            # print(res.text)
            # 正则提取提取鉴权码
            # re.search("正则表达式",res.text)
            obj = re.search('name="csrf_token" value="(.*?)"', res.text)
            # 取匹配到的第1个值
            print(obj.group(1))
            TestRequest.csrf_token = obj.group(1)
    
            # # 提取cookies
            # TestRequest.php_cookie = res.cookies
    
        def test_login(self):
            url = "http://47.107.116.139/phpwind/index.php?m=u&c=login&a=dorun"
            data = {
                "username": "xxx",
                "password": "xxx",
                "csrf_token": TestRequest.csrf_token,  # 鉴权码,从首页获取
                "backurl": "http://47.107.116.139/phpwind/",
                "invite": ""
            }
            headers = {
                "Accept": "application/json,text/javascript,/; q=0.01",
                "X-Requested-With": "XMLHttpRequest"
            }
            # res = requests.request(method="post", url=url, data=data, headers=headers, cookies=TestRequest.php_cookie)
            # 使用session请求
            res = TestRequest.sess.request(method="post", url=url, data=data, headers=headers)
            print(res.json())
    
    
    if __name__ == '__main__':
        TestRequest.test_get_token()
        TestRequest.test_edit_flag()
        TestRequest.test_file_upload()
        TestRequest.test_start()
        TestRequest.test_login()

    四、接口自动化测试框架关于接口关联的封装

    策略:去掉全局变量,用YAML文件代替保存。

    yaml_util.py 操作yaml文件的工具模块。

    # 对yaml操作的工具
    
    # 读取
    import os
    
    import yaml
    
    
    def read_yaml(key):
        with open(os.getcwd() + "/extract.yaml", mode="r", encoding="utf-8") as f:
            # FullLoader 全局加载
            value = yaml.load(stream=f, Loader=yaml.FullLoader)
            return value[key]
    
    
    # 写入
    def write_yaml(data):
        # 以追加的模式打开,编码格式为utf-8
        with open(os.getcwd() + "/extract.yaml", mode="a", encoding="utf-8") as f:
            yaml.dump(data, stream=f, allow_unicode=True)
    
    
    # 清空
    def clean_yaml():
        # 以追加的模式打开,编码格式为utf-8
        with open(os.getcwd() + "/extract.yaml", mode="w", encoding="utf-8") as f:
            f.truncate()