文章目录
一、框架
1、api/:接口对象层(代码:python package)
- ① __ init__.py 无内容
- ②ihrm_login_api.py
2、common/:通用工具方法、函数(代码:python package)
- ① __ init__.py 无内容
- ②read_json_file.py
- ③assert_tools.py
- ④logging_use.py
3、data/:测试数据文件(文件:dir)
- login_data.json
4、report/:测试报告(文件:dir)
5、scripts/:测试脚本层(代码:python package)
- ① __ init__.py 无内容
- ② test_ihrm_login_params.py
6、config.py: 项目中的 配置信息。(全局变量)
7、pytest.ini: pytest 配置
二、参数化步骤
- 将 测试数据,按 [{},{},{}] 格式 组织到 json文件中。
- 读取 json文件,将数据转换为 [(),(),()]
- 在通用测试方法上一行,添加 @pytest.mark.parameterize()
- 给 parameterize() 传参。参1:字符串类型,内容为 json文件中一组数据的 key。参2:[(),(),()]格式数据。
- 给 通用测试方法添加形参,与 parameterize() 参1 字符串的内容一致。
- 修改 通用测试方法 内部实现,使用形参。
2.1 api包
2.1.1 ihrm_login_api.py
"""
ihrm 登录接口 对象层
"""
import requests
# 定义 ihrm 登录接口 类
class IhrmLoginApi(object):
# 定义方法
@classmethod
def login(cls, req_data):
resp = requests.post(url="http://ihrm-test.itheima.net/api/sys/login", json=req_data)
return resp
# 测试 接口封装是否成功
if __name__ == '__main__':
# 准备请求体数据
data = {"mobile": "13800000002", "password": "123456"}
resp = IhrmLoginApi.login(data)
print("登录成功:", resp.json())
2.2 common包
2.2.1 read_json_file.py
2.2.1.1 相对路径写法
- 在 common/ 下创建 文件 read_json_file.py
- 在 文件内,创建 函数,读取json文件中的数据,转换成 [(),(),()] 格式数据
- 测试此函数功能通过
import json
# 定义工具函数,读取json文件中的数据,转换成 [(),(),()] 格式数据
def read_json_data(filename):
with open(filename, "r", encoding="utf8") as f:
json_data = json.load(f)
login_list = []
for data in json_data:
tmp = tuple(data.values())
login_list.append(tmp)
return login_list
if __name__ == '__main__':
res = read_json_data("../data/login_data.json") # 相对路径写法
print(res)
- 建议读取 json文件时,使用 绝对路径法传入文件名
- 在 config.py 中,添加 全局变量,获取 项目目录
BASE_DIR = os.path.dirname(__file__) - 拼接 json文件的绝对路径
filename = BASE_DIR+"/data/login_data.json" - 使用 绝对路径,传入 json文件读取函数。
read_json_data(filename)
- 在 config.py 中,添加 全局变量,获取 项目目录
2.2.1.2 绝对路径写法
在计算机的存储路径是固定的。
import json
from config import BASE_DIR
# 定义工具函数,读取json文件中的数据,转换成 [(),(),()] 格式数据
def read_json_data(filename):
with open(filename, "r", encoding="utf8") as f:
json_data = json.load(f)
login_list = []
for data in json_data:
tmp = tuple(data.values())
login_list.append(tmp)
return login_list
if __name__ == '__main__':
# res = read_json_data("../data/login_data.json")
filename = BASE_DIR + "/data/login_data.json" # 绝对路径写法
res = read_json_data(filename)
print(res)
2.2.2 assert_tools.py
"""
定义 通用的 工具函数,实现断言
"""
def common_assert(resp, status_code, success, code, message):
assert status_code == resp.status_code
assert success is resp.json().get("success")
assert code == resp.json().get("code")
assert message in resp.json().get("message")
2.2.3 logging_use.py
-
将 loggin_use.py 文件部署到项目中。 如:拷贝至 common/ 下。
-
在 项目下 创建 log/ 用来存放生成的 xxx.log 日志文件
-
在 项目中,使用日志之前,初始化日志信息,指定 日志文件名【必填】、单位、单位间隔、保留文件个数。
-
在 需要打印输出的位置,使用 logging.级别(“想要输出的信息”)
import logging.handlers
import logging
from config import BASE_DIR
def init_log_config(filename, when='midnight', interval=1, backup_count=7):
"""
功能:初始化日志配置函数
:param filename: 日志文件名
:param when: 设定日志切分的间隔时间单位
:param interval: 间隔时间单位的个数,指等待多少个 when 后继续进行日志记录
:param backup_count: 保留日志文件的个数
:return:
"""
# 1. 创建日志器对象
logger = logging.getLogger()
# 2. 设置日志打印级别
logger.setLevel(logging.DEBUG)
# logging.DEBUG 调试级别
# logging.INFO 信息级别
# logging.WARNING 警告级别
# logging.ERROR 错误级别
# logging.CRITICAL 严重错误级别
# 3. 创建处理器对象
# 控制台对象
st = logging.StreamHandler()
# 日志文件对象
fh = logging.handlers.TimedRotatingFileHandler(filename,
when=when,
interval=interval,
backupCount=backup_count,
encoding='utf-8')
# 4. 日志信息格式
fmt = "%(asctime)s %(levelname)s [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s"
formatter = logging.Formatter(fmt)
# 5. 给处理器设置日志信息格式
st.setFormatter(formatter)
fh.setFormatter(formatter)
# 6. 给日志器添加处理器
logger.addHandler(st)
logger.addHandler(fh)
if __name__ == '__main__':
# 初始化日志
init_log_config(BASE_DIR + '/log/sh27.log', interval=3, backup_count=5)
# 打印输出日志信息
logging.debug('我是一个调试级别的日志')
logging.info("AAA BBB CCC")
logging.error("xxxx 错误。。")

2.3 data文件夹
2.3.1 login_data.json
总共15条测试案例,但是本案例数据只有7条,仅做演示,后续可以补充全部。
[
{
"desc": "登录成功",
"req_data": {
"mobile": "13800000002",
"password": "123456"
},
"status_code": 200,
"success": true,
"code": 10000,
"message": "操作成功"
},
{
"desc": "手机号不存在",
"req_data": {
"mobile": "13874893701",
"password": "123456"
},
"status_code": 200,
"success": false,
"code": 20001,
"message": "用户名或密码错误"
},
{
"desc": "密码错误",
"req_data": {
"mobile": "13800000002",
"password": "123456890"
},
"status_code": 200,
"success": false,
"code": 20001,
"message": "用户名或密码错误"
},
{
"desc": "手机号为空",
"req_data": {
"mobile": null,
"password": "123456"
},
"status_code": 200,
"success": false,
"code": 20001,
"message": "用户名或密码错误"
},
{
"desc": "多参",
"req_data": {
"mobile": "13800000002",
"password": "123456",
"abc": "123"
},
"status_code": 200,
"success": true,
"code": 10000,
"message": "操作成功"
},
{
"desc": "少参",
"req_data": {
"mobile": "13800000002"
},
"status_code": 200,
"success": false,
"code": 20001,
"message": "用户名或密码错误"
},
{
"desc": "无参",
"req_data": null,
"status_code": 200,
"success": false,
"code": 99999,
"message": "抱歉,系统繁忙,请稍后重试!"
}
]
2.4 report文件夹
2.5 scripts包
2.5.1 test_ihrm_login_params.py
## parameterize参数化
1. 在 通用测试方法上一行,添加 @pytest.mark.parameterize()
2. 给 parameterize()添加参数。参1:一个字符串,内容为json文件中,一组测试数据的键。参2:[(),(),()]格式数据。
3. 给 通用测试方法,添加形参。参数与 parameterize()的 参1 保持一致。
4. 修改 通用测试方法 内部实现,使用 形参。
- 定义通用测试方法,测试登录接口。
- 作参数化,一个接口就一个方法。
import logging
import pytest
from api.ihrm_login_api import IhrmLoginApi
from common.assert_tools import common_assert
from common.logging_use import init_log_config
from common.read_json_file import read_json_data
from config import BASE_DIR
class TestIhrmLoginParams(object):
init_log_config(BASE_DIR + '/log/sh27.log', interval=3, backup_count=5)
# 读取json文件,获取[(),(),()]格式数据
data = read_json_data(BASE_DIR + "/data/login_data.json")
@pytest.mark.parametrize("desc, req_data, status_code, success, code, message", data)
# 定义 通用测试方法 - 测试ihrm登录接口
def test_ihrm_login(self, desc, req_data, status_code, success, code, message):
# 调用 自己封装的 api, 获取响应结果
resp = IhrmLoginApi.login(req_data)
# 打印查看
# print(desc, ":", resp.json())
logging.info(f"{desc} : {resp.json()}")
# 断言
common_assert(resp, status_code, success, code, message)
2.6 config.py
import os
# 定义全局变量,获取项目路径(绝对路径)
BASE_DIR = os.path.dirname(__file__)
2.7 pytest.ini
[pytest]
addopts = -s
testpaths = ./scripts
python_files = test*.py
python_classes = TestAdd*Params
python_functions = test*
2861

被折叠的 条评论
为什么被折叠?



