pytest插件开发 L4

pytest 编写自己的插件

Pytest 编写插件 1 - 修改默认编码

pytest_collection_modifyitems 收集上来的测试用例实现定制化功能

解决问题:

  • 自定义用例的执行顺序
  • 解决编码问题 (中文的测试用例名称)
  • 自动添加标签

Pytest 编写插件 1 - 修改默认编码

含有中文的测试用例名称,改写编码格式:

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')
from typing import Optional, List

def pytest_runtest_setup(item: "Item") -> None:
    print("hook : setup")

def pytest_runtest_teardown(item: "Item", nextitem: Optional["Item"]) -> None:
    print("teardwn")

# 收集完测试用例 之后被调用的hook函数
def pytest_collection_modifyitems(
    session: "Session", config: "Config", items: List["Item"]
) -> None:
    print(items)
    # name 用例的名字
    # nodeid 就是测试用例路径
    for item in items:
        item.name = item.name.encode('utf-8').decode('unicode-escape')
        item._nodeid = item.nodeid.encode('utf-8').decode('unicode-escape')
    items.reverse()


Pytest 编写插件 2 - 添加命令行参数

def pytest_addoption(parser):
    mygroup = parser.getgroup("hogwarts")     #group 将下面所有的 option都展示在这个group下。
    mygroup.addoption("--env",    #注册一个命令行选项
        default='test',      # 参数的默认值
        dest='env',            #  存储的变量,为属性命令,可以使用Option对象访问到这个值,暂用不到
        help='set your run env'    # 帮助提示 参数的描述信息
        )

@pytest.fixture(scope='session')
def cmdoption(request):
    return request.config.getoption("--env")
import pytest
import yaml

# 定义一个命令行参数
def pytest_addoption(parser):
    mygroup = parser.getgroup("hogwarts")  #group 将下面所有的 option都展示在这个group下。
    mygroup.addoption("--env",  #注册一个命令行选项
        default='test',   # 参数的默认值
        dest='env',      # 存储的变量,为属性命令,可以使用Option对象访问到这个值,暂用不到
        help='set your run env'  # 帮助提示 参数的描述信息
        )


@pytest.fixture(scope='session')
def cmdoption(request):
    myenv = request.config.getoption("--env", default='test')
    if myenv == 'test':
        datapath = "datas/test/data.yml"
    elif myenv == 'dev':
        datapath = "datas/dev/data.yml"

    with open(datapath) as f:
        datas = yaml.safe_load(f)
    return myenv,datas

打包发布

打包发布到 pypi

打包项目构成

  • 源码包
  • setup.py
  • 测试包

setup.py 配置

构建文件 setup.py 代码路径:
https://ceshiren.com/t/topic/14156

from setuptools import setup,find_packages
setup(
    name='pytest_encode',
    url='https://github.com/xxx/pytest-encode',
    version='1.0',
    author="xixi",
    author_email='418974188@qq.com',
    description='set your encoding and logger',
    long_description='Show Chinese for your mark.parametrize(). Define logger variable for getting your log',
    classifiers=[# 分类索引 ,pip 对所属包的分类
        'Framework :: Pytest',
        'Programming Language :: Python',
        'Topic :: Software Development :: Testing',
        'Programming Language :: Python :: 3.8',
    ],
    license='proprietary',
    packages = find_packages(), #['pytest_encode'],
    keywords=[
        'pytest', 'py.test', 'pytest_encode',
    ],

    # 需要安装的依赖
    install_requires=[
        'pytest'
    ],
    # 入口模块 或者入口函数
    entry_points={
        'pytest11': [
            'pytest_encode = pytest_encode.main',
        ]
    },
    zip_safe=False
)

# main.py
# 收集完测试用例 之后被调用的hook函数
from typing import List

def pytest_collection_modifyitems(
    session: "Session", config: "Config", items: List["Item"]
) -> None:
    print(items)
    # name 用例的名字
    # nodeid 就是测试用例路径
    for item in items:
        item.name = item.name.encode('utf-8').decode('unicode-escape')
        item._nodeid = item.nodeid.encode('utf-8').decode('unicode-escape')
    items.reverse()

# test_encode.py
import pytest


@pytest.mark.parametrize('name',['哈利波特','赫敏'])
def test_mm(name):
    print(f"name: {name}")

目录结构:

打包命令

依赖包安装:
pip install setuptools  python 的包管理工具,负责 安装和发布,尤其是安装拥有信赖关系的包。
pip install wheel       生成 *.whl 格式的安装包,本质上也是一个压缩包

打包命令:
python setup.py sdist bdist_wheel

发布命令

python3 -m pip install --user --upgrade twine       ## 安装 twine 工具
python3 -m twine upload --repository testpypi dist/*     ## 上传代码