接口测试之requests+pytest

1. 什么接口?

        常见的接口种类:

                系统内部服务层之间的接口调用,比如后端服务应用层调用service层的接口,service层掉用DAO层的接口,这个地方的接口测试属性白盒范畴,一般开发自己做就可以了

                服务之间的接口调用,比如你有两个服务,一个是用户中心,一个是订单中心,订单中心会去调用户中心的服务,查询用户信息,这些接口我们一般是要测试的

                系统之间的接口调用,比如你商户系统会去调公共服务系统的接口

2. 怎么开展接口测试?

        流程如下4步:需求确定之后开发API文档;拿到API文档,编写接口测试用例;开发交付;实施接口测试

        关注点:接口参数输入确认与错误;接口参数缺失,接口参数边界值;接口参数类型

3. 常见的requests请求

        get、post、put和delete

import requests
requests.get(url,params=None,**kwargs)
requests.post(url,data=None,json=None,**kwargs)
requests.put(url,data=None,**kwargs)
requests.delete(url,**kwargs)

         使用post时,然后传参是raw类型,即json数据,则使用json参数;如果传参是form_data、x-www-from-urlencoded和binary类型,都是用data类型

        示例:百度搜索宫水三叶

import requests
class TestApi:
    def test_search(self):
        url = 'http://www.baidu.com'
        params = {
            'wd':'宫水三叶'
        }
        res = requests.get(url=url,params=params)
        print(res) #<Response [200]>
if __name__ == '__main__':
    TestApi().test_search()

4. 统一的requests请求及自动化关联cookie

import requests
#统一的requests请求方式
requests.request(method,url,**kwargs)
#自动关联cookie的resquest
session = requests.session()

        method表示上述提到的requests四大请求中的一个

        kwargs参数的介绍:

                常用:params=None:get请求传参

                           data=None:post或者put请求传参

                           headers=None:请求头

                           json=None:post请求传参

                           cookies=None:Cookie

                           files=None:文件上传,传输时不是直接传输文件,而是传输二进制字节流,如requests.post(url,files={'file':open('文件路径','rb)})

             不常用:auth=None:鉴权

                           timeout=None:超时处理

                           allow_redirects=True:是否允许重定向

                           proxies=None:设置代理

                           hooks=None:钩子

                           stream=None:文件下载

                           verify=None:证书验证

                           cert=None:CA证书

5. 接收响应

        发送请求就有相应,由requests对象来接收

import requests
res = requests.get(url)
print(res.text) #返回文本信息
print(res.json()) #返回json格式
print(res.content) #返回字节内容
print(res.stat_code) #返回状态码(默认)
print(res.reason) #返回状态信息
print(res.cookies) #返回cookie
print(res.encoding) #返回编码格式
print(res.headers) #返回响应头
print(res.request.请求数据) #返回请求数据

6. http请求和响应

        请求:请求方式,请求路径,请求参数,请求头

        响应:响应码,响应信息,响应内容,响应头

7. 接口自动化实现接口关联的三种方式及提取变量的两种方式?

        实现接口关联的三种方式:

                通过类变量保存中间变量实现接口关联

                通过单独的文件保存中间变量实现接口关联

                极限封装成和工具一样,只需通过表达式就可以实现接口关联

        提取变量的两种方式:

                正则表达式提取(适用于提取文本结果)

                        re.search(匹配规则,内容):提取一个值,通过下标取值

                        re.findall(匹配规则,内容):提取多个值,通过下标取值

import re
s = 'https://www.baidu.com/s?wd=%E5%AE%AB%E6%B0%B4%E4%B8%89%E5%8F%B6&rsv_spt=1&rsv_iqid=0xf9c1f4d5004488bf&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&rqlang=cn&tn=baiduhome_pg&rsv_enter=0&rsv_dl=tb&rsv_t=2d3f8MFdVICYaPChAacKXFbqtbQWljpENk54NQDbvzPRHb%2FtgB9PID%2FZXO9yZGAWo%2F58&oq=%25E5%25AE%25AB%25E6%25B0%25B4%25E4%25B8%2589%25E5%258F%25B6&rsv_pq=cd0d607200026660&rsv_btype=t&prefixsug=%25E5%25AE%25AB%25E6%25B0%25B4%25E4%25B8%2589%25E5%258F%25B6&rsp=8&inputT=15918&rsv_sug4=18202&rsv_sug=1'
res = re.search('wd=(.*?)&',s)
print(res) #<re.Match object; span=(24, 64), match='wd=%E5%AE%AB%E6%B0%B4%E4%B8%89%E5%8F%B6&'>
print(res.group(1)) #%E5%AE%AB%E6%B0%B4%E4%B8%89%E5%8F%B6

                Jsonpath提取(适用于提取json结果):返回的是一个列表

                        jsonpath表达式规则:$表示根节点

                                                           .表示子节点

                                                           ..表示递归取子节点

                当提取json数据时,可能用于unicode编码问题,显示是编码之后的内容,因此需要还原

import jsonpath
res = jsonpath.jsonpath(jsondata,表达式)
#还原
json.loads(json.dumps(res.json()).replace('\\\\','\\'))

8. 统一请求封装

        为了在不同操作之间保持cookie关联,因此封装一个统一请求方式,之后每次请求调佣该方式即可

import requests
class RequestUtil:
    session = requests.session()
    def all_send_request(self,**kwargs):
        res = RequestUtil.session.request(**kwargs)
        return res

9. pytest用例管理框架作用

        找到用例:

                模块名必须以test_开头或者_test结尾

                类名必须以Test开头,并且不能有init方法

                用例方法必须以test开头

        执行用例

        判断结果

        生成报告

10. pytest常用插件

        pytest-html:简单的html报告

        pytest-xdist:多线程执行

        pytest-ordering:控制用例的执行顺序

        pytest-rerunfailures:失败用例重跑

        pytest-base-url:设置基础路径

        allure-pytest:生成allure报告

11. pytest运行

        可以选在在命令行,即终端直接输入pytest运行,也可以创建一个main函数

#file.name=run.py
import pytest
if __name__=='__main__':
    pytest.main()

12. pytest全局配置文件pytest.ini

[pytest]
#命令行参数
#常见:--html=./reports/report.html --reruns 2
addopts = -vs -m "user_manager or smoke"
#配置执行的用例位置
testpaths = ./testcase
#配置修改默认的模块规则
python_files = test_*.py
#配置修改默认的类规则
python_classes = Test*
#配置修改默认的用例规则
python_functions = test_*
#配置基础路径
base_url=http://www.baidu.com
#标记
markers =
    smoke:冒烟测试用例
    user_manager:用例管理
#标记markers采用@装饰器的方式添加到测试用例前

 如果运行时报错,可以根据该网址进行修改:Pytest报错:UnicodeDecodeError_pytest运行报错unicodedecodeerror: 'utf-8' codec can't -CSDN博客

13. fixture插件使用

        @pytest.fixture(scope='范围',autouse='自动执行',params='参数化',ids='参数名',name='插件别名')

        scope范围:函数function、类class、模块module、会话session

        auto自动执行:当设置为True时,无需在相应地方应用该插件,设置为False时需要

import pytest
import requests
#当autouse为False时
@pytest.fixture(scope='function',autouse=False)
def cur_stat():
    print('执行前')
    yield
    print('执行后')
class TestApi:
    def test_search(self,cur_stat):
        url = 'http://www.baidu.com'
        params = {
            'wd':'宫水三叶'
        }
        res = requests.get(url=url,params=params)
        res = requests.get(url=url)
        print(res) #<Response [200]>
#当autouse为True时
@pytest.fixture(scope='function',autouse=True)
def cur_stat():
    print('执行前')
    yield
    print('执行后')
class TestApi:
    def test_search(self):
        url = 'http://www.baidu.com'
        params = {
            'wd':'宫水三叶'
        }
        res = requests.get(url=url,params=params)
        res = requests.get(url=url)
        print(res) #<Response [200]>

if __name__ == '__main__':
    TestApi().test_search()

        params和ids可以结合使用,需要注意的是,当使用时,def的 () 中需要加上request,并且 yield也需要产生参数,同时,需要早在test函数中加入插件名

import requests
import pytest
@pytest.fixture(scope='function',autouse=False,params=['宫水三叶','宫水四叶'],ids=['3','4'])
def cur_stat(request):
    print('执行前')
    yield request.param
    print('执行后')
class TestApi:
    def test_search(self,cur_stat):
        print(cur_stat)
        url = 'http://www.baidu.com'
        params = {
            'wd': cur_stat
        }
        res = requests.get(url=url,params=params)
        print(res) #<Response [200]>
if __name__ == '__main__':
    TestApi().test_search()

        name相当于python中 import requests as rs,即重命名的过程

14. fixture结合conftest.py 文件实现前后置

        可以将前后置内容,放置conftest.py文件中来维护,conftest.py文件会自动从外层到内层执行

import pytest
@pytest.fixture(scope='module',autouse=True)
def cur_stat():
    print('执行前')
    yield
    print('执行后')

15. yaml文件读取与写入

        可以把一下跨文件的数据保存在yaml文件中,这样就可以跨文件调用了

import yaml

def write_yaml(data):
    with open('./extract.yaml',encoding='utf-8',mode='a+') as f:
        yaml.dump(data,stream=f,allow_unicode=True)

def read_yaml(key):
    with open('./extract.yaml',encoding='utf-8',mode='r') as f:
        d = yaml.load(stream=f,Loader=yaml.FullLoader)
        return d[key]

def clear_yaml():
    with open('./extract.yaml',encoding='utf-8',mode='r') as f:
        f.truncate()

16. pytest的数据驱动

        通过修改数据从而去驱动测试用例的执行,从而得到不同的结果。当只有一组数据时,只会执行一次用例,多组数据则执行多次。

        pytest数据驱动装饰器

        @pytest.mark.parametrize('参数名',参数值)

import requests
import pytest
from CSDN.requestlearn.yaml_util import read_testdata
class TestApi:
    @pytest.mark.parametrize('testdata',read_testdata(path))
    def test_search(self,testdata):
        # url = 'http://www.baidu.com'
        # params = {
        #     'wd': '宫水三叶'
        # }
        url = testdata['request']['url']
        params = testdata['request']['params']
        res = requests.get(url=url,params=params)
        print(res) #<Response [200]>
if __name__ == '__main__':
    TestApi().test_search()

17. Allure测试报告生成

        配置pytest.ini文件

addopts = -vs --alluredir=./temps --clean-alluredir

        在run.py文件中进行配置

import pytest
import os
import time
if __name__ == '__main__':
    pytest.main()
    time.sleep(3)
    os.system('allure generate ./temps -o ./reports --clean')

  • 18
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值