美文网首页
python接口自动化知识点

python接口自动化知识点

作者: YJ的笔记 | 来源:发表于2023-09-19 11:30 被阅读0次

    一、接口自动化介绍

    1.简介

    [接口自动化]是提高测试效率和质量的重要手段之一。

    2.为什么要做接口自动化

    相对于UI自动化而言,接口自动化具有更大的价值。
    为了优化转化路径或者提升用户体验,APP/web界面的按钮控件和布局几乎每个版本都会发生一次变化,导致自动化的代码频繁变更,没有起到减少工作量的效果。
    而接口一旦研发完成,后期重构/大幅度修改的频率则比较低.因而做接口自动化性价比还是很高的,对于迭代版本旧有功能的回归,beta测试,线上回归都能起到事半功倍的作用。

    3.接口自动化两大类

    1、为模拟测试数据而开展的接口自动化
    这种接口自动化大多是单次执行,目的很明确是为了功能测试创造测试数据,节约人工造数据的时间和人工成本,提高功能测试人员的测试效率。
    2、在功能测试之前提前发现错误而开展的接口自动化
    这种接口自动化的工作流程跟功能测试一样,需要设计接口测试用例,然后执行接口测试用例。
    说白了就是对单接口进行功能校验,包括接口参数的必填性、长度字符类型限制、入参枚举值等是否正确、响应数据是否正确等进行校验。

    4.插件自动安装

    1、在项目根目录创建文件:requirements.txt
    2、在文件中写入需要安装的插件名

    requirements.txt 内容
    pytest
    requests
    pytest-html
    pytest-xdist
    pytest-ordering
    pytest-rerunfailures
    pytest-base-url
    allure-pytest
    

    二、Requests简介

    1.Requests是基于urllib,使用Apache2 许可证开发HTTP库。其在python内置模块的基础上进行了高度封装,使得Requests能够轻松完成浏览器相关的任何操作。
    2.接口测试流程

    发起请求: 通过HTTP库向目标站点发起请求,等待目标站点服务器响应。
    
    获取响应: 若服务器正常响应,会返回一个Response,该Response即为获取得页面内容,Response可以是HTML、JSON、字符串、二进制数据等数据类型。
    
    解析内容:利用正则表达式、网页解析库对HTML进行解析;将json数据转为JSON对象进行解析;保存我们需要得二进制数据(图片、视频)。
    
    内容断言:根据解析内容断言期望结果。
    

    3.Requests总览


    image.png

    requests
    requests请求 功能
    requests.get( ) 从服务器获取数据
    requests.post( ) 向服务器提交数据
    requests.put( ) 从客户端向服务器传送的数据取代指定的文档的内容
    requests.delete( ) 请求服务器删除指定页面
    requests.head( ) 请求页面头部信息
    requests.options( ) 获取服务器支持的HTTP请求方法
    requests.patch( ) 向HTML提交局部修改请求,对应于HTTP的PATCH
    requests.connect( ) 把请求连接转换到透明的TCP/IP通道
    requests.trace( ) 回环测试请求,查看请求是否被修改
    requests.session( ).get( ) 构造会话对象
    requesets请求参数 含义
    url 请求的网址
    allow_redirects 设置是否重新定向
    auth 设置HTTP身份验证
    cert 指定证书文件或密钥的字符串
    cookies 要发送至指定网址的Cookie字典
    headers 要发送到指定网址的HTTP标头字典
    proxies URL代理的协议字典
    stream 指定响应后是否进行流式传输
    timeout 设置等待客户端连接的时间
    verify 用于验证服务器TLS证书布尔值或字符串指示

    """get请求"""
    import requests
    
    url = 'https://tse4-mm.cn.bing.net/th/id/OIP-C.w3cHPxIHKpLZodnlBoIZXgHaMx?w=182&h=314&c=7&o=5&dpr=1.45&pid=1.7'
    response = requests.get(url)
    print(res.status_code)
    
    """添加请求头:header"""
    headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'}
    response = requests.get('https://www.zhihu.com/explore',headers=headers)
    print(response.status_code)
    
    """带请求参数"""
    params = {'wd':'python'}
    response = requests.get('https://www.baidu.com/',params=params)
    print(response.status_code)
    
    """代理设置"""
    proxies = {'http':'http://127.0.0.1:9743',
              'https':'https://127.0.0.1:9742',}
    response = requests.get('https://www.taobao.com',proxies=proxies)
    print(rsponse.status_code)
    
    """SSL证书验证"""
    response = requests.get('https://www.12306.cn',verify=False)
    print(response.status_code)
    
    """超时设置"""
    from requests.exceptions import ReadTimeout
    try:
        response = requests.get("http://httpbin.org/get", timeout = 0.5)
        print(response.status_code)
    except ReadTimeout:
        print('timeout')
    
    """认证设置"""
    from requests.auth import HTTPBasicAuth
    response = requests.get("http://120.27.34.24:9001/",auth=HTTPBasicAuth("user","123"))
    print(response.status_code)
    
    """post请求"""
    
    import requests
    import json
    
    host = 'http://httpbin.org/'
    endpoint = 'post'
    url = ''.join([host,endpoint])
    
    """带数据的post"""
    data = {'key1':'value1','key2':'value2'}
    response = requests.post(url,data=data)
    print(response.status_code)
    print(response.text)
    
    """带headers的post"""
    headers = {'User-Agent':'test request headers'}
    response = requests.post(url,headers=headers)
    print(response.status_code)
    print(response.text)
    
    """带json的post"""
    data = {
        'sites':[
            {'name':'test','url':'www.test.com'},
            {'name':'google','url':'www.google.com'},
            {'name':'weibo','url':'www.weibo.com'}
        ]
    }
    response = requests.post(url,json=data)
    print(response.status_code)
    print(response.text)
    
    """带参数的post"""
    params = {'key1':'params1','key2':'params'}
    response = requests.post(url,params=params)
    print(response.status_code)
    print(response.text)
    
    """文件上传"""
    files = {'file':open('fisrtgetfile.txt','rb')}
    response = requests.post(url,files=files)
    print(response.status_code)
    print(response.text)
    
    """put请求"""
    import requests 
    import json
    
    url = 'http://127.0.0.1:8080'
    header = {'Content-Type':'application/json'}
    param = {'myObjectField':'hello'}
    payload = json.dumps(param)
    
    response = requests.put(url,data=payload,headers=headers)
    
    """head请求"""
    import requests
    
    response = requests.head('https://pixabay.com/zh/')
    print(response.status_code)
    
    """delete请求"""
    import requests
    
    url = 'https://api.github.com/user/emails'
    email = '2475757652@qq.com'
    
    response = requests.delete(url,json=email,auth=('username','password'))
    print(response.status_code)
    
    """options请求"""
    import requests
    import json
    
    url = 'https://www.baidu.com/s'
    response = requests.options(url)
    print(response.status_code)
    

    response
    response属性 功能
    response.text 获取文本内容
    response.content 获取二进制数据
    response.status_code 获取状态码
    response.headers 获取响应头
    response.cookies 获取cookies信息
    response.cookies.get_dict 以字典形式获取cookies信息
    response.cookies.items 以列表形式获取cookies信息
    response.url 获取请求的URL
    response.historty 获取跳转前的URL
    response.json 获取json数据

    import requests 
    
    url = 'https://baike.baidu.com/item/%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB/5162711'
    response = requests.get(url)
    
    print(response.status_code)
    print(response.text)
    print(response.json)
    print(response.content)
    print(response.headers)
    print(response.cookies)
    print(response.cookies.items)
    print(response.url)
    print(response.history)
    print(response.cookies.get_dict)
    
    """下载图片"""
    import requests
    import matplotlib.pyplot as plt
    
    url = 'https://cn.bing.com/images/search?view=detailV2&ccid=qr8JYj0b&id=6CEE679B0BCE19C94FB9C7595986720942C92261&thid=OIP.qr8JYj0bcms3xayruiZmnAHaJQ&mediaurl=https%3a%2f%2ftse1-mm.cn.bing.net%2fth%2fid%2fR-C.aabf09623d1b726b37c5acabba26669c%3frik%3dYSLJQglyhllZxw%26riu%3dhttp%253a%252f%252fp1.ifengimg.com%252f2019_02%252f95A41E54C3C8EB3B3B148A30CE716314B0AED504_w1024_h1280.jpg%26ehk%3d2EhKcVkSnCvT6uBfgisn%252fdwtghMXFWjGa5WgqEbBSPc%253d%26risl%3d%26pid%3dImgRaw&exph=1280&expw=1024&q=%e7%9f%b3%e5%8e%9f%e9%87%8c%e7%be%8e&simid=607996751665040666&FORM=IRPRST&ck=399D74E04F8507D6711ADC8F53A714D7&selectedIndex=0&ajaxhist=0&ajaxserp=0'
    response = requests.get(url)
    img = response.content
    
    with open('shiyuanlimei.jpg','wb') as f:
        f.write(img)
    

    三、Yaml知识点

    1.Yaml简介
    YAML 是一种可读性非常高,与程序语言数据结构非常接近。同时具备丰富的表达能力和可扩展性,并且易于使用的数据标记语言。
    其实YAML文件也是一种配置文件,但是相较于ini,conf配置文件来说,更加的简洁,操作简单,还能存放不同类型的数据;而像ini存储的值就都是字符串类型,读取之后还要手动转换
    2.YAML的基本语法规则
    大小写敏感
    使用缩进表示层级关系
    缩进时不允许使用Tab键,只允许使用空格。(可以将你的ide的tab按键输出替换成4个空格)
    缩进的空格数目不重要,只要相同层级的元素左侧对齐即可

    表示注释

    3.YAML支持的数据结构
    对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
    数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
    纯量(scalars):单个的、不可再分的值
    4.YAML,对象数据类型
    对象的一组键值对,使用冒号结构表示。

    animal: dogs

    转换成Python数据结构,如下:

    {'animal': 'dogs'}

    将所有键值对赋值。

    hash: { name: Steve, foo: bar }

    转换成Python数据结构,如下:

    {'hash': {'name': 'Steve', 'foo': 'bar'}}

    将列表赋值

    lists : [1,2,3]

    转换成Python数据结构,如下:

    {'lists': [1, 2, 3]}

    将元组赋值

    tuples : (1,2,3)

    转换成Python数据结构,如下:

    {'tuples': '(1,2,3)'}

    总结
    当赋值列表、键值对时,转换成Python数据结构是可以直接当列表、字典使用的;
    当赋值元组时,转换后也是字符串
    最终输出的都是字典类型,可以通过key获取对应的值
    以 - 开头的行表示构成一个数组

    四、python+requests+pytest+yaml+allure接口自动化框架

    一.common层

    logger_util.py文件
    1.使用了python中的loguru库来进行日志记录,从loguru库中引入logger对象,使用logger.add()方法配置日志记录器.
    2.把日志写入到名为logs_{time:YYYY-MM-DD-HH-mm-ss.sss}.log的文件中
    3.{time:YYYY-MM-DD-HH-mm-ss.sss}将在日志文件名中被替换为当前时间.
    4.rotation=10MB是日志文件当大小达到10MB时自动轮转
    5.compression=zip是会使用zip进行压缩
    6.定义了info(),debug(),warning(),error(),critical()函数,分别用来记录信息,调试,警告,错误,严重错误级别的日子,使用logger对象的相应方法将信息记录到日志文件中
    request_util.py文件
    这段代码定义了一个名为RequestUntil的类,并包含一个名为send_request的方法。类中定义了一个静态变量session来保存持久化的session对象。
    send_request方法包装了requests库的request方法,它接收三个参数:http请求方法(例如:GET,POST,PUT等),url和关键字参数。(关键字参数是根据请求不同而不同的各种参数)
    首先,该方法使用loguru库中的info()方法来记录发送请求的参数。然后,使用requests库的request方法来发送HTTP请求,返回响应对象并将其保存在res变量中。
    接下来,使用loguru库中的debug()方法来记录响应对象的状态码和内容。最后返回响应对象。
    Yaml_util.py文件
    这段代码是一个关于读写YAML文件的工具方法集合。首先,它从Python的os库中导入了getcwd和path的方法,同时它从yaml库中导入了load和dump方法。

    1.get_object_path方法使用os库返回当前工作目录路径。如果当前工作目录中包含字符串“common”,它将返回“common”之前的所有内容作为项目的根目录目录。
    2.read_yaml方法使用yaml库的load()方法来读取yaml文件(extract.yaml)的内容,并返回包含yaml内容的Python字典。
    3.write_yaml方法使用yaml库的dump()方法将数据写入到yaml文件(extract.yaml)中。流模式被传递到yaml dump()方法中,以确保数据可以整个传输。
    4.clear_yaml方法清空yaml文件(extract.yaml)中的内容,它在打开文件后将文件截断为0。
    5.read_testcase方法接收一个路径参数,然后从指定路径读取yaml文件的内容,返回包含yaml内容的Python字典。这个方法主要用于读取测试用例文件

    二.data层

    test_get_token.yaml文件
    这是一个YAML格式的测试用例文件,测试用例名为“获取接口统一鉴权码token接口”。以下是该测试用例的详细信息:

    • name: 测试用例名称,即“获取接口统一鉴权码token接口”
    • request: 请求信息
      • method: 请求方法,即“get”
      • url: 请求URL,即“https://api.weixin.qq.com/cgi-bin/token
      • params: GET请求的查询字符串参数,包括两个键值对:
        • grant_type: “client_credential”
        • appid: “**********”

    三.testcase层

    test_API.py文件
    执行接口请求区域

    四.框架的介绍:

    1.common层构建基础类库:为了提高测试用例的可维护性性和复用性,其中包括日志输出,接口统一发送请求,yaml文件的读取,
    写入,清除的方法
    2.data层:存放测试用例yaml数据
    3.logs层:存放日志
    4.reports层:存放生成的allure报告
    5.temps层:存放生成的临时报告
    6.testcase层:测试用例
    7.pytest.ini:配置文件
    8.requirements.txt:依赖包
    9.run.py:自动化框架运行脚本的文件,然后会在reports生成allure报告
    框架的使用说明:
    1.环境配置:需要在pycharm终端里安装requirements.txt依赖包,输入pip install -requirements.txt部署环境
    2.编写测试用例数据是用yaml文件进行传参,其中包含测试所有API的参数,这个文件可以包括
    接口名称(name),请求(request),请求方法(menthod),请求路径(URL),请求参数(params)
    举例:

    3.测试用例以test_XXX命名,XXX是测试用例的名字,其中包括allure标记的装饰器,数据驱动,断言,
    @allure.story(),allure.dynamic.title()是allure标记的装饰器
    @pytest.mark.parametrize("caseinfo", read_testcase("./data/test_get_token.yaml"))
    这行代码使用了pytest框架提供的 @pytest.mark.parametrize()装饰器,具体含义是read_testcase()yaml文件
    读取的函数从路径"./data/test_get_token.yaml"文件中读取到测试用例数据集作为参数,将其命名为caseinfo,并
    传递给被装饰器的测试函数.
    test_get_token()的测试函数,该函数使用了参数化方式运行多组测试用例,每组测试用例都是一个字典函数,包含了请求参数
    和预期结果信息,用yaml数据格式进行value:key方式进行传参.
    断言用是pytest自带的断言方式assert

    举例:
    @pytest.mark.parametrize("caseinfo", read_testcase("./data/test_get_token.yaml"))
    @allure.story("获取token接口")
    def test_get_token(self, caseinfo):
    allure.dynamic.title("获取token")
    method = caseinfo["request"]["method"]
    url = caseinfo["request"]["url"]
    params = caseinfo["request"]["params"]
    res = RequestUntil().send_request(method=method, url=url, params=params)
    print(res.json()["access_token"])
    write_yaml(res.json()["access_token"])
    assert res.status_code== 200
    assert "access_token" in res.text
    4.执行测试
    点击run.py文件.执行脚本,然后会在reports包里生成一份allure报告,点击idex.html,点击浏览器就可以查看
    本地allure报告

    相关文章

      网友评论

          本文标题:python接口自动化知识点

          本文链接:https://www.haomeiwen.com/subject/prmnvdtx.html