11 接口自动化-框架封装之统一请求封装和接口关联封装
文章目录
- 一、框架封装
- 1、统一请求封装和路径处理
- 2、接口关联封装
- 二、简单封装代码实现
- config.yml - 放入一些配置数据
- yaml_util.py - 处理 yaml 数据
- requests_util.py - 将请求封装在同一个方法中
- test_tag.py - 测试用例执行
- conftest.py - 会话之前清除数据
一、框架封装
1、统一请求封装和路径处理
把所有请求统一到一个方法中,目的:利于后期维护以及加入日志和异常处理。
但没办法实现 cookies 关联
最终我们要达到功能测试不需要写代码,也能执行接口自动化。
2、接口关联封装
有可能在 url 、参数、请求头里面传值,进行统一封装
二、简单封装代码实现
config.yml - 放入一些配置数据
url:base: https://api.weixin.qq.comget_token: /cgi-bin/tokencreate_tag: /cgi-bin/tags/createupdate_tag: /cgi-bin/tags/updateget_tag: /cgi-bin/tags/getupload_file: /cgi-bin/media/uploadimg
yaml_util.py - 处理 yaml 数据
import os
import yaml# 获取项目根路径
def get_object_path():return os.getcwd().split('common')[0]# 读取 config.yml 文件
def read_config_yaml(first_node,second_node):with open(os.path.join(get_object_path(), 'config.yml'), 'r', encoding='utf-8') as f:yaml_config = yaml.load(f, Loader=yaml.FullLoader)return yaml_config[first_node][second_node]# 读取 extract.yml 文件
def read_extract_yaml(first_node):with open(os.path.join(get_object_path(), 'extract.yml'), 'r', encoding='utf-8') as f:yaml_config = yaml.load(f, Loader=yaml.FullLoader)return yaml_config[first_node]# 写入 extract.yml 文件
def write_extract_yaml(data):with open(os.path.join(get_object_path(), 'extract.yml'), 'a', encoding='utf-8') as f:yaml.dump(data, f,allow_unicode=True)# 清空 extract.yml 文件
def clear_extract_yaml():with open(os.path.join(get_object_path(), 'extract.yml'), 'w', encoding='utf-8') as f:f.truncate()
requests_util.py - 将请求封装在同一个方法中
import json
import requests
from common.yaml_util import read_config_yaml, read_extract_yamlclass RequestsUtil:# 创建 session 会话对象session = requests.Session()# 统一替换的方法,data 可以是 url(string),也可以是参数(字典,字典中包含列表),也可以是请求头(字典)def replace_value(self,data):# 不管是什么类型统一转换成字符串格式if data and isinstance(data, dict): # 如果 data 不为空且 data类型是一个字典str = json.dumps(data)else:str = data# 替换值for a in range(1, str.count('{{')+1):if '{{' in str and '}}' in str:start_index = str.index('{{')end_index = str.index('}}')old_value = str[start_index:end_index+2]new_value = read_extract_yaml(old_value[2:-2])str = str.replace(old_value, new_value)print(str)# 还原数据类型if data and isinstance(data, dict): # 如果 data 不为空且 data类型是一个字典data = json.loads(str)else:data = strreturn data# 统一发送请求的方法:def send_request(self, method, url, headers=None, **kwargs):# 处理 method 统一为小写lower_method = str(method).lower()# 处理基础路径base_url = read_config_yaml("url", "base")second_url = self.replace_value(read_config_yaml("url", url))# 处理请求头if headers:headers = self.replace_value(headers)# 最核心的地方:请求数据如何去替换,可能是 params、data、jsonfor k, v in kwargs.items():if k in ['params', 'data', 'json']:kwargs[k] = self.replace_value(v)# 发送请求res = RequestsUtil.session.request(method=lower_method,url=base_url + second_url, **kwargs)print(res.text)return res
test_tag.py - 测试用例执行
import random
import time
import pytest
from common.requests_util import RequestsUtil
from common.yaml_util import write_extract_yamlclass TestTag:@pytest.mark.userdef test_get_token(self):params = {"grant_type": "client_credential",# 注意写自己的 appid 和 secret,下面的数据是假数据"appid": "wxcb292044d4fdfd11","secret": "69be902b0619de6bf75af4b0b9992645"}res = RequestsUtil().send_request(method='get',url='get_token',params=params)# 把中间变量写入 extract.yml 文件--注意提前去创建 extract.yml 文件extract_data = {"access_token":res.json()['access_token']}write_extract_yaml(extract_data)@pytest.mark.userdef test_create_tag(self):name = str(random.randrange(100000,999999))data = {"tag": {"name": name}}params = {"access_token": "{{access_token}}"}RequestsUtil().send_request(method='post', url="create_tag", json=data,params=params)@pytest.mark.userdef test_update_tag(self):name = time.strftime("_%Y%m%d_%H%M%S")data = {"tag": {"id": 101,"name": "hc" + name}}params = {"access_token": "{{access_token}}"}RequestsUtil().send_request(method='post', url="update_tag", json=data, params=params)@pytest.mark.userdef test_get_tag(self):params = {"access_token": "{{access_token}}"}RequestsUtil().send_request(method='get', url="get_tag", params=params)@pytest.mark.userdef test_upload_file(self):data = {"media":open(r"F:\Pycharm\TestAPI\screenshots\logo.png","rb")}params = {"access_token": "{{access_token}}"}RequestsUtil().send_request(method='post', url="upload_file", files=data,params=params)
conftest.py - 会话之前清除数据
import pytest
from common.yaml_util import clear_extract_yaml@pytest.fixture(scope="session",autouse=True)
def clear_extract():""" 每次会话之前清除 extract.yml 数据 """clear_extract_yaml()