Pytest是一个非常成熟的全能Python测试框架
- 简单灵活,容易上手;
- 支持参数化;
- 测试用例的skip和xfail,自动失败重试等处理;
- 能够支持简单的单元测试和复杂的功能测试,还可以用来做selenium/appnium等自动化测试、接口自动化测试(pytest+requests);
- pytest有很多第三方插件,并且可以自定义扩展,比较好用的如pytest-allure(HTML测试报告生成),pytest-xdist(多CPU分发)等;
- 可以很好的和Jenkins集成;
官方文档:pytest手册 第三方库:第三方库
本文只介绍pytest插件开发
pytest插件开发
想控制测试用例的顺序,或者接口测试用例的量很大比如上千条需要并发的执行,支持中文或阿拉伯文等多语言,扩展命令行参数,扩展项目里独有的功能 pytest-ordering–控制测试用例执行顺序
插件的加载方式
- 外部插件:用pip install命令来安装的插件
- 本地插件:pytest自动模块发现机制(放在conftest.py中的内容),如fixture
- 内置插件:由代码内部的_pytest目录加载,如hook函数
什么是hook
完成一个过程,把具体的方法封装到不同的步骤中,不同的步骤之间会预留一些未知的步骤,这些被预留好的未知的步骤就是所谓的hook函数。这样,新增hook函数便不会影响到已有的步骤中的内容。 hook函数文件在项目中的路径一般为:External Libraries–>Python 3.X–>site-packages–>hookspec.py 归根结底,hook函数定义了一些流程,我们可以在定义好的流程内改写一些内容
pytest有哪些hook函数
比如pytest_addoption()函数,可以用来添加自定义的命令行参数; pytest_collection_modifyitems()函数,将测试用例收集到一起后对测试用例进行修改,测试用例以函数参数的方式传递进来;
如何改写hook函数
- 写入conftest中。conftest基于自动发现机制,如果将方法写入该文件,则被重写的hook函数可以直接生效。
- 自定义一个项目进行打包。
示例
pytest_collection_modifyitems()函数改写编码方式
如下从hookspec.py文件中复制的函数定义内容,该函数是在执行完收集动作后被调用,可以用来过滤或重新排序Item参数传过来的测试用例,参数items为测试用例。
def pytest_collection_modifyitems(
session: "Session", config: "Config", items: List["Item"]
) -> None:
"""Called after collection has been performed. May filter or re-order
the items in-place.
:param pytest.Session session: The pytest session object.
:param _pytest.config.Config config: The pytest config object.
:param List[pytest.Item] items: List of item objects.
"""
pytest已知有个编码问题–默认Unicode编码格式,不支持中文,接下来就示例如何改写pytest_collection_modifyitems()函数来支持中文编码方式。
- 创建一个测试用例test_name
在这个测试用例中,参数化传入一个列表,列表中的数据为中文姓名,在测试用例中打印输出这些姓名。 该测试用例的运行结果如下,可以看到,三个传入的测试数据均未被编码为中文。
import pytest
@pytest.mark.parametrize('name',['赫敏','哈利','露娜'])
def test_name(name):
print(name)
- 改写pytest_collection_modifyitems()函数
首先确定需要修改编码方式的范围,测试用例的名字和测试用例的路径都是Unicode方式编码的,所以这两个地方都需要进行改写。 接下来,创建一个conftest.py文件,然后把该函数名称和参数照着hookspeck.py文件原样不动的复制过来(我们要重写这个函数,所以一定要保证函数名称和hookspeck中一模一样) 这时候再次运行测试用例test_name(),测试结果如下图。
def pytest_collection_modifyitems(session, config, items):
for item in items:
item.name = item.name.encode('utf-8').decode('unicode-escape')
item._nodeid = item.nodeid.encode('utf-8').decode('unicode-escape')
有关打包,发布
打包
把好的功能打包,发布到www.pypi.org 具体请参考官方文档:https://packaging.python.org/tutorials/packaging-projects/ 项目里必须要有的项: 1.setup文件,这是一个构建工具,其他人使用该包的时候需要通过这个文件对源码进行安装 2.example_package文件夹以及里面的__init__.py,存放源码
setup文件内容参考:
打包需要的两个工具:wheel 和 setuptools 使用命令: python setup.py sdist bdist_wheel 即可打包 打包成功后会多出几个文件夹,其中有个dist文件如下图 里面的pytest_encode-1.0.tar.gz文件是源码包 pytest_encode-1.0-py3-none-any.whl是whl包,可以通过“pip install whl包的路径”命令进行安装 如果项目复杂包很多,可以用“pip freeze >requirements.txt” 命令把依赖的库导出到requirements.txt文件中。
发布
具体发布流程请参考官方文档: https://packaging.python.org/tutorials/packaging-projects/
|