文章目录
一、框架封装
最终我们要达到功能测试不需要写代码,也能执行接口自动化。
更完善的封装见 下一篇文章
1、统一请求封装和路径处理
把所有请求统一到一个方法中,目的:利于后期维护以及加入日志和异常处理。
但没办法实现 cookies 关联
2、接口关联封装
有可能在 url 、参数、请求头里面传值,进行统一封装:双{{}}的解析
二、简单封装代码实现
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(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(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(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(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_yaml
class 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 = str
return 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、json
# 比如把 access_token: "{{access_token}}" 中的{{access_token}} 替换成 真实的值
for 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, headers = headers,**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_yaml
class TestTag:
@pytest.mark.user
def 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.user
def 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.user
def 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.user
def test_get_tag(self):
params = {
"access_token": "{{access_token}}"
}
RequestsUtil().send_request(method='get', url="get_tag", params=params)
@pytest.mark.user
def 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()