python接口自动化框架 unittest+ddt
简介
1.框架用unittest+yaml数据驱动+自定义日志/HTMLTestRunner
2.测试数据中包含可执行代码(入获取当日时间)

data层
存放测试用例数据,mysql数据,常量文件等
ini常量文件
[http]
baseUrl:https://jsonplaceholder.typicode.com/
[sql]
user:root
pwd:123456
connect:https://localhost
yaml测试数据-列表套字典的形式,一个字典为一个测试用例
- description: 测试日期 昨天
data:
user: admin
pwd: 123
date: <(datetime.date.today()+datetime.timedelta(days=-1)).strftime("%Y-%m-%d")>
assert: 201
- description: 测试日期 今天
data:
user: wang
pwd: 123
date: <datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")>
assert: 201
tests层
存放测试用例的地方,可用unittest/pytest
unittest案例
import unittest
import ddt
import requests
from common.readinifile import re_conf
from common.tools import mylog, dic_execute
@ddt.ddt
class TestCaseYaml(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
"""
读取config配置文件
:return:
"""
cls.base = re_conf('http', 'baseUrl')
@ddt.file_data("../data/data.yaml")
@mylog
def test_01(self, **kwargs):
"""
登录测试
:param kwargs:字典形式:用户名,密码,日期 ,描述,断言
:return:
"""
print(kwargs['description'])
kwargs['data'] = dic_execute(kwargs['data'])
info = kwargs['data']
url = self.base+"users"
data = {
"id": 11,
"name": info['date'],
"username": info['user'],
"datetime": info['pwd']
}
res = requests.request('post', url, data=data)
print(res.text)
self.assertEqual(res.status_code, info['assert'])
if __name__ == '__main__':
unittest.main()
公共层
存放一些工具类和方法
1.读取ini文件方法
import configparser
import os
path = os.path.dirname(__file__)
path = os.path.join(path, '../', "data/config.ini")
# 从ini文件中读取参数
def re_conf(title, key=None, file=path):
conf = configparser.ConfigParser()
conf.read(file, encoding='utf-8')
if key is None:
# 读取字段到Section对象
return conf[title]
else:
# 读取具体的值
return conf.get(title, key)
if __name__ == '__main__':
#方式一
confObj = re_conf(title="http", file="../data/config.ini")
print(confObj)
print("方式一 "+confObj.get("baseUrl"))
#方式二
data = re_conf(title="http", key="baseUrl", file="../data/config.ini")
print("方式二 "+data)
2.执行字符串的代码+日志装饰器
import datetime
# 读取文件数据后,把可执行代码执行
def dic_execute(dic: dict):
for k, v in dic.items():
if isinstance(v, str):
if v.startswith('<') and v.endswith('>'):
dic[k] = eval(v[1:-1])
return dic
# 写日志
def write_log(info, grade='INFO', file="log.txt"):
with open(file, 'a+', encoding='utf-8')as f:
times = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
lines = f'{times} {grade} {info}'+'\n'
f.write(lines)
# 日志装饰器
def mylog(func):
def inner(*args, **kwargs):
write_log('-' * 50)
try:
func(*args, **kwargs)
write_log(f'测试成功:{kwargs["description"]}')
write_log(f'入参:{kwargs["data"]}')
except Exception as e:
write_log(f'测试失败:{kwargs["description"]}', grade="WARN")
write_log(f'入参:{kwargs["data"]}', grade="WARN")
write_log(f'错误信息:{str(e)}', grade="WARN")
raise e
return inner
if __name__ == '__main__':
@mylog
def test(**kwargs):
print('函数')
a=1/0
test(name='哈哈哈',pwd=123,description='description',data='testData')

主执行方法main.py文件
import unittest
from common.HTMLTestRunner import HTMLTestRunner
# 生成套件
suite = unittest.TestSuite()
# 添加测试用例
discover = unittest.defaultTestLoader.discover(start_dir='tests', pattern='test*.py')
# 用例加入套件
suite.addTest(discover)
# 三方包执行用例并生成report报告
with open('./report.html', 'wb') as f:
runner = HTMLTestRunner(f, verbosity=2)
runner.run(suite)


浙公网安备 33010602011771号