一、Pytest接口自动化简单框架搭建
1.1 接口关键字封装
api_key.py中ApiKey()类
包含方法:get、post、get_text(jsonpath提取关联数据)
1.2 优化1:Allure报告进行优化之测试步骤
# 工具类/关键字驱动类/基类
# 通过添加对应的测试步骤:@allure.step("步骤内容注释")
class ApiKey:
@allure.step("发送get请求")
def get(self, url, params=None, **kwargs):
"""
发送get请求
:param url:请求的URL
:param params: 需要拼装在URL当中的参数
:param kwargs: 其它参数,具体参考requests.post()
:return: 响应数据
"""
# print("-----------发送get请求-----------")
return requests.get(url=url, params=params, **kwargs)
@allure.step("发送post请求")
def post(self, url, data=None, json=None, **kwargs):
"""
发送POST请求
:param url: 请求的URL
:param data: 请求的数据
:param json: 请求数据如果是json可直接使用该参数
:param kwargs: 其它参数,具体参考requests.post()
:return: 响应数据
"""
# print("-----------发送post请求-----------")
return requests.post(url=url, data=data, json=json, **kwargs)
# 版本1:
@allure.step("获取响应数据")
def get_text(self, response, key):
"""
基于jsonpath获取数据的关键字:用于提取所需要的内容
:param response: 响应报文,默认为json格式
:param key: jsonpath的表达式
:return:
"""
print("-----------获取响应数据-----------")
# 判断对应的变量是不是字符串格式
if isinstance(response,str):
"""如果是字符串,就转成JSON 格式的字符串转换为 Python 对象。"""
response = json.loads(response)
value_list = jsonpath.jsonpath(response, key)
return value_list[0]
1.3 优化2:Allure报告进行优化之接口关联
import requests
import jsonpath
import allure
@allure.title("测试用例标题")
def test_case_name():
with allure.step("第一步:XXXXX接口"):
# 具体的接口请求代码
with allure.step("第二步:XXXXX接口"):
# 具体的接口请求代码
1.4 接口关联改进
fixture+conftest实现项目级的token多文件关联
@pytest.fixture(scope="session")
def token_fix():
"""
token全项目都需要使用并且进行接口关联,整个项目这个fix只运行一次
:return: 工具类ak ; 用户的token
"""
# 初始化工具类
ak = ApiKey()
# 完成登录操作并返回token
url = "http://shop-xo.hctestedu.com/index.php?s=/api/user/login"
public_data = {"application": "app", "application_client_type": "weixin"}
data = {"accounts": "hami", "pwd": "123456", "type": "username"}
res = ak.post(url=url, params=public_data, data=data)
# ----------------------------------------
# 获取响应数据
result = res.json()
# ----------------------------------------
# 获取token数据
token = ak.get_text(result, "$.data.token")
return ak, token
1.5 全局常量定义
config.py包含用户名、密码、url、公共参数等
"""
常量的统一管理文件,为了方便代码的维护,迅速进行识别
规范:目录、文件名、目录名全大写
"""
# 项目链接
# 正式地址:
# PROJECT_URL = "http://shop-xo.hctestedu.com/index.php?"
# 测试环境
PROJECT_URL = "http://127.0.0.1/index.php?"
# 当前用户的用户
# 用户名
USERNAME = "hami"
# 密码
PASSWORD = "123456"
# 登录类型
LOGINTYPE = "username"
# 公共参数 # 快速转成大写:crtl+shift+u(win)/ Cmd + Shift + U (macOS)
PARAMS = {
"application": "app",
"application_client_type": "weixin",
}
二. Pytest框架中的Logging应用
pytest.ini
[pytest]
log_cli=true
log_level=NOTSET
log_format = %(asctime)s %(levelname)s %(message)s %(lineno)d
log_date_format = %Y-%m-%d %H:%M:%S
log_file = ./log.log
log_file_level = info
log_file_format = %(asctime)s %(levelname)s %(message)s %(lineno)d
log_file_date_format = %Y-%m-%d %H:%M:%S
conftest.py
@pytest.hookimpl(hookwrapper=True, tryfirst=True)
def pytest_runtest_makereport(item, call):
out = yield
res = out.get_result()
if res.when == "call":
logging.info(f"用例ID:{res.nodeid}")
logging.info(f"测试结果:{res.outcome}")
logging.info(f"故障表示:{res.longrepr}")
logging.info(f"异常:{call.excinfo}")
logging.info(f"用例耗时:{res.duration}")
logging.info("**************************************")
Logger.py
class Logger:
def __init__(self, name, log_file, level=logging.DEBUG):
self.logger = logging.getLogger(name)
self.logger.setLevel(level)
# 创建日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 创建文件处理器
file_handler = RotatingFileHandler(log_file, maxBytes=1048576, backupCount=3)
file_handler.setFormatter(formatter) # 设置格式
self.logger.addHandler(file_handler) # 添加到对应的处理器中
# 创建控制台处理器
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)
self.logger.addHandler(console_handler)