接口自动化测试框架开发 (pytest+allure+aiohttp+ 用例自动生成)
近期准备优先做接口测试的覆盖,为此需要开发一个测试框架,经过思考,这次依然想做点儿不一样的东西。
-
接口测试是比较讲究效率的,测试人员会希望很快能得到结果反馈,然而接口的数量一般都很多,而且会越来越多,所以提高执行效率很有必要
-
接口测试的用例其实也可以用来兼做简单的压力测试,而压力测试需要并发
-
接口测试的用例有很多重复的东西,测试人员应该只需要关注接口测试的设计,这些重复劳动最好自动化来做
-
pytest和allure太好用了,新框架要集成它们
-
接口测试的用例应该尽量简洁,最好用yaml,这样数据能直接映射为请求数据,写起用例来跟做填空题一样,便于向没有自动化经验的成员推广 加上我对Python的协程很感兴趣,也学了一段时间,一直希望学以致用,所以http请求我决定用aiohttp来实现。 但是pytest是不支持事件循环的,如果想把它们结合还需要一番功夫。于是继续思考,思考的结果是其实我可以把整个事情分为两部分。 第一部分,读取yaml测试用例,http请求测试接口,收集测试数据。 第二部分,根据测试数据,动态生成pytest认可的测试用例,然后执行,生成测试报告。 这样一来,两者就能完美结合了,也完美符合我所做的设想。想法既定,接着 就是实现了。
第一部分(整个过程都要求是异步非阻塞的)
读取yaml测试用例
一份简单的用例模板我是这样设计的,这样的好处是,参数名和aiohttp.ClientSession().request(method,url,**kwargs)是直接对应上的,我可以不费力气的直接传给请求方法,避免各种转换,简洁优雅,表达力又强。
args:
- post
- /xxx/add
kwargs:
-
caseName: 新增xxx
data:
name: ${gen_uid(10)}
validator:
-
json:
successed: True
异步读取文件可以使用aiofiles这个第三方库,yaml_load是一个协程,可以保证主进程读取yaml测试用例时不被阻塞,通过await yaml_load()
便能获取测试用例的数据
async def yaml_load(dir='', file=''):
"""
异步读取yaml文件,并转义其中的特殊值
:param file:
:return:
"""
if dir:
file = os.path.join(dir, file)
async with aiofiles.open(file, 'r', encoding='utf-8', errors='ignore') as f:
data = await f.read()
data = yaml.load(data)
# 匹配函数调用形式的语法
pattern_function = re.compile(r'^\${([A-Za-z_]+\w*\(.*\))}$')
pattern_function2 = re.compile(r'^\${(.*)}$')
# 匹配取默认值的语法
pattern_function3 = re.compile(r'^\$\((.*)\)$')
def my_iter(data):
"""
递归测试用例,根据不同数据类型做相应处理,将模板语法转化为正常值
:param data:
:return:
"""
if isinstance(data, (list, tuple)):
for index, _data in enumerate(data):
data[index] = my_iter(_data) or _data
elif isinstance(data, dict):
for k, v in data.items():
data[k] = my_iter(v) or v
elif isinstance(data, (str, bytes)):
m = pattern_function.match(data)
if not m:
m = pattern_function2.match(data)
if m:
return eval(m.group(1))
if not m:
m = pattern_function3.match(data)
if m:
K, k = m