pytest-xlsx 是一个 pytest 的插件,它可以将 xlsx 文件作为 pytest 可以执行的测试文件和测试用例,
这样软件测试人员就可以通过 Excel 便捷的实现关键字驱动测试(像 Robot Framework 那样)
在 xlsx 中使用关键字驱动测试
在 xlsx 中使用用例标记
在 xlsx 中使用数据驱动测试
目前绝大部分人都是通过 pytest.mark.parametrize
加载和执行 excel 文件的,类似这样:
import pytest
# excel内容传递给 pytest.mark.parametrize
@pytest.mark.parametrize("data", read_excel("ddt.xlsx"))
def test_(data):
print(data["name"]) # 用例名称
print(data["step"]) # 用例步骤
print(data["assert"]) # 用例断言
如果 excel 中有 N 组既定的数据,就会执行 N 个用例。
这种方式优势是简单
理解简单:参数化是 pytest 中常见的用法
实现简单:创建和执行由pytest实现
维护简单:只需要维护 read_excel
函数
劣势也是简单,比如:
命令行中显示的是 python 文件,而不是 excel 文件
命令行中显示 python 文件
如果出错了也只会显示 python 代码的报错信息,不会显示 excel 中的数据
执行 excel 文件需要先写好 python 代码,甚至每一个 excel 都可能要配一个 python 用例
无法在 excel 中使用自定义标记、参数化测试、动态夹具等 pytest 特色功能
因为从本质上来看,excel 在这里只是充当了数据文件,而不是用例文件,用例还是代码中的那个函数
def test_(data):
...
本插件作为一个全新解决方案
不需要编写代码读取、解析 excel 文件内容,也不需要编写代码创建用例
因为现在 pytest 真的可以把 excel 作为用例文件了!
命令行中显示excel文件
而且用例失败时可以显示表格内容,
例如下图可以直观的判断出是【点击新增地址】时,定位失败
用例失败时显示表格内容
你可以通过 pip 安装本插件
pip install pytest-xlsx==0.3.1
本文是 pytest-xlsx==0.3.1 的使用说明,若是其他版本,细节上可能有些许差异
创建一个 test_
开头的 xlsx 文件,例如:
test_my_blog.xlsx
文件名的
test_
前缀遵循了 pytest 一贯的测试文件命名惯例,同时也能避免加载不打算作为测试用例的文件,毕竟 xlsx 文件更多的用武之地是数据存储
在 xlsx 写入以下内容,这是我们创建的第一个测试用例
步骤 ID | 步骤名称 | 标记 | 参数 | |
---|---|---|---|---|
0 | 用例名称 | name | 登录 | |
1 | 打开浏览器 | browser | chrome | |
2 | 打开博客 | get | https://baidu.com/login | |
3 | 输入用户名 | input | //*[@id="username"] | admin |
4 | 输入密码 | input | //*[@id="password"] | 123456 |
5 | 点击登录 | click | //*[@id="login"] | |
0 | 用例名称 | name | 评论 | |
1 | 打开浏览器 | browser | chrome | |
2 | 打开博客 | get | https://baidu.com/post/1 | |
3 | 输入内容 | input | //*[@id="comment"] | admin |
4 | 点击发布 | click | //*[@id="ubmit"] |
执行xlsx文件
如果在启动 pytest 时,传递 -vvs
参数可以得到更加详细的内容
输出xlsx内容
从输出信息可知 pytest-xlsx 做了哪些事:
将 test_my_blog.xlsx 作为测试文件
将 sheet 标题(Sheet1)和 excel(评论、登录)内容作为测试 ID
将 excel 的内容作为测试用例的内容,并打印出来
test_*.xlsx
文件,将被 pytest 视为测试文件
测试文件中的 Sheet,将被 pytest 视为测试类
Sheet 中标记
字段的内容是 name
和 mark
的行,将被 pytest 视为用例信息
此外的所有内容,将被 pytest 视为用例步骤
支持多个文件、多个 Sheet、多个用例,同时编辑和执行
xlsx 中的内容分为两部分:
标记
字段的内容是 name
或 mark
的,作为用例信息,用来创建用例
name:指定用例名字
mark:和pytest中的mark用法类似,指定用例标记,或使用数据驱动测
用例信息之外的其他内容,作为用例步骤,用来执行用例
用例内容全部交给 xlsx_runner
进行执行
默认的 xlsx_runner
只会进行打印,上图可以看到 xlsx 中的用例步骤被打印出来了
xlsx_runner
是一个夹具,你可以重新定义
xlsx_runner 是一个 fixture,所以只需要在 conftest.py
中重新定义同名 fixture,
即可让测试步骤安装你的想法执行
比如:将测试步骤写入到文件中,而不是打印到屏幕上
import pytest
from pytest_xlsx.runner import Runner, XlsxItem
class FileRunner(Runner): # 1. 定义Runner
def execute(self, item: XlsxItem): # 2. 实现execute方法
"""
:param item: 用例对象
:return:
"""
if item.is_first_step: # 如果是第一个步骤
self.f = open(f"{item.name}.txt", "w", encoding="utf-8") # 则创建文件
# 写入 步骤序号 和 步骤内容
self.f.write(f"{item.current_step_no}:{item.current_step}\n")
if item.is_last_step: # 如果是最后一个步骤
self.f.close() # 关闭文件
def xlsx_runner_(): # 3. 重写xlsx_runner,使用自定义Runner
return FileRunner()
具体步骤:
继承 pytest_xlsx.runner.Runner
,实现一个新的 class 名为 FileRunner
实现 runTest
方法,这方法会接收到全部的用例步骤
创建名为 xlsx_runner
的 fixtures,并返回 FileRunner
实例对象
定义好 fixture 后,再执行 pytest 就看不到测试步骤被打印了
反倒是在目录中创建了相应的 txt 文件
除了打印、写入文件之外,你还可以根据项目需要,将测试步骤用于浏览器控制(Web 自动化测试)、接口调用(API 自动化测试)等场景。
execute 方法所接收的 item 参数,是 XlsxItem
的实例对象,其拥有以下属性
属性名 | 属性内容 | 类型 | 备注 |
---|---|---|---|
xlsx_data | 从 xlsx 中读取到的全部数据 | dict | |
nodeid | 当前测试用例 id | str | |
name | 当前用例名称 | str | |
current_step_no | 当前用例步骤序号 | int | 第一个是 0 |
max_step_no | 最大用例步骤序号 | int | 步骤数量 - 1 |
is_first_step | 是否是第一个步骤 | bool | |
is_last_step | 是否最后一个步骤 | bool | |
current_step | 当前步骤内容 | dict |
XlsxItem 在执行某一个用例时,会依次读取步骤内容,然后将自己传递给 xlsx_runner,
也就是说,在同一个用例中有多少个步骤,xlsx_runner 的 execute 就会被调用多少次,
你可以通过访问 item参数的属性,来判断当前是哪一个步骤,并决定如何执行
目前,pytest-xlsx 的配置只有一项:
xlsx_meta_column_name=标记
,用来指定用例信息的列名
如果你的 xlsx 使用 “关键字” 这一列存储 name 和 mark,比如这样
那么应该在配置文件中进行指定新的列名即可
[pytest]
xlsx_meta_column_name = 关键字
注意:pytest 加载配置文件时不会指定的文件字符编码。如果配置文件中有非 ASCII 内容,务必将配置文件的字符编码改为操作系统的默认编码
pytest-xlsx 在实现上遵循 pytest 惯例和约定,对 pytest 的其他插件亦有极好的兼容性,
以下插件已经验证完美兼容(若有更多兼容性问题,或者兼容验证结果,欢迎提出):
pytest-html
pytest-allure
pytest-xdist
更多。。。
✅ 支持 parametrize
✅ 支持 mark (支持:skip、skipif、xfail、用户自定义 mark,暂不支持:usefixtures)
▢ 支持 fixture
▢ 支持指令集(类似 RF 的用户关键字)
原创不易,喜欢请星标+点赞+在看,关注公众号《XXXXX》,不错过技术干货,谢谢鼓励!