概述
大家都知道 pytest 的插件一般以 pytest-
作为前缀,
在 pypi 搜索 pytest-yaml
,可以搜到下面三个插件:
pytest-yaml
pytest-yaml-yoyo
pytest-yaml-sanmu
第一个插件较为简单,读取指定 yaml 文件的内容,并保存到 fixture 中,并且自 2018 年后不再更新
第二个插件较为复杂,甚至有些超越【插件】的范畴,集成了一系列如读取 yaml 文件、生成用例、接口请求、数据库连接等功能,成为一个开箱即用的接口测试框架
第三个插件较为简单,只有【将 yaml 文件识别为测试用例】,这个单一的职责,它定位不是一个作为直接面向用户的工具,而是一个搭建框架的脚手架。
借助这个脚手架,
你可以封装出像 pytest-yaml-yoyo
那样的 yaml 接口测试框架,
更可以封装出像 opentest
那样的 yaml 全栈测试框架(Web + App+API)
安装
与 pytest 其他插件的安装方式相同,使用 pip 命令即可
pip install pytest-yaml-sanmu
需要注意有两点:
- 该插件仅支持 python 3.10 及以上版本
- 本插件和
pytest-yaml
存在冲突,只能二选一进行安装
使用
01.启用插件
因为 yaml 应用场景非常广泛,为避免误处理非测试用例的 yaml 文件,
本插件需要手动启用才会进行工作,在 pytest 配置文件中进行实现
[pytest]
# 启用插件,执行yaml用例
run_yaml_case = 1
未启用时,插件表现与未安装一致
02.yaml 用例文件名
本插件约定:测试用例的文件名必须是 test_
开头
以下名字的 yaml 会被插件进行识别,并进一步处理:
test_api.yaml
test_web.yaml
test_app.yaml
test_测试用例.yaml
test_0_x_1.yaml
pytest 能够识别的 yaml 文件
以下名字的 yaml 不会被插件进行识别,仿佛不存在一般
abc.yaml
api_test.yaml
docker-compose.yaml
pytest 不能识别的 yaml 文件
03.yaml 用例文件内容
本插件约定,用例内容必须:
- 包含
test_name
字段,字符串格式,用例定义用例名, - 包含
steps
字段,数组(列表)格式,用例用例定义步骤 - 每一个用例步骤都是对象(字典)格式
# test_api.yaml
test_name: abc # 用例名称,字符串格式
steps: # 用例步骤,数组(列表)格式
- a: 1 # 每一个步骤,必须要是对象(字典)
- b: 2 # 每一个步骤,必须要是对象(字典)
- c: 3 # 每一个步骤,必须要是对象(字典)
以上 yaml 定义了一个名为 abc 的用例,并且包含 3 个测试步骤
执行效果如图
pytest 执行 yaml 文件中的用例
04.yaml 用例执行规则
正如前文所言,本插件的职责非常单一,即:将 yaml 文件中的用例交给被 pytest 识别、执行。
除此之外,它没有其他的功能,既不会请求接口,也不会控制浏览器,更不会连接数据库。
yaml 中的用例步骤该怎么执行,反倒是必须由你自行定义。
也是正因为如此,才为使用过本插件的应用留下了极大的扩展空间。
具体来说 yaml 用例执行规则定义通过 hook 实现:
- 在 conftest.py 中创建函数
pytest_yaml_run_step
- 在函数中处理参数
item
示例如下
hook 打印 yaml 用例步骤
执行结果如下
hook 的处理效果
从执行结果可以发现这样的规律:
- pytest 可以自动找到 yaml 用例文件
- hook 执行了 3 次,和用例步骤的数量一致
- 每次打印的内容,和用例步骤的内容一致
可以推测出pytest-yaml-samu的流程和原理:
本插件会按照 yaml 文件中所定义的用例步骤,
按照固定的顺序、数量、内容,
对 pytest_yaml_run_step
进行调用
基于此,只需可以在函数中加入断言,使 yaml 成为真正意义上的测试用例
具体的例子可以关注本文后续更新。
反馈
本插件是从 sanmu 框架中提取出来的,旨在让更多人封装出属于自己的 yaml 测试框架。
尽管已经在 sanmu 框架等的多处场景进行使用,但因本人水平有限,难免存在不足或 BUG,
计划
暂定的更新计划有:
- [ ] 用例文件的名称规则可自定义
- [ ] 将用例名称的字段从
test_name
改为name
- [ ] 在 yaml 中支持使用
for
、if
等语法 - [ ] 为 yaml 用例文件给出错误提示和修改建议
- [ ] 在 yaml 中直接使用 fixture 的返回值