• 【pytest官方文档】解读- 开发可pip安装的第三方插件


    在上一篇的 hooks 函数分享中,开发了一个本地插件示例,其实已经算是在编写插件了。今天继续跟着官方文档学习更多知识点。

    一个插件包含一个或多个钩子函数,pytest 正是通过调用各种钩子组成的插件,实现了配置、搜集、运行和报告的所有方面的功能。

    通常 pytes t中的插件有如下 3 类:

    • 内置插件 : 从 pytest 内部的_pytest目录加载
    • 外部插件 : 通过setuptools入口发现的模块
    • conftest.py: 在测试目录中自动发现的模块

    第一个内置插件的路径在/Lib/site-packages/_pytest这里,有兴趣的可以看下。

    第三个conftest.py我们也很熟悉了,像之前写fixture函数以及本地hooks函数插件,都是在conftest.py中。

    第二个外部插件中提到的setuptools是什么呢?

    其实这是 pytest 的一个特性库,通过这个setuptools,我们的插件代码可以通过pip安装并上传到PyPI。

    本章就来开发一个可以 pip 安装的第三方插件

    一、cookiecutter-pytest-plugin

    但是在开发之前,先来了解下cookiecutter-pytest-plugin这个项目。这是官方文档中强烈推荐的,可以帮助我们快速生成一个规范标准的插件项目。

    项目地址:https://github.com/pytest-dev/cookiecutter-pytest-plugin

    跟着项目介绍的文档一步步来就行。

    先安装该项目:

    $ pip install cookiecutter
    

    然后可以使用这个工具开始创建我们自己的插件项目了。

    $ cookiecutter https://github.com/pytest-dev/cookiecutter-pytest-plugin
    

    一步步跟着出现的指令提示,输入对应的项目信息即可。

    最后的输入的一个测试插件项目是这样的。

    二、开发第三方插件

    重新写一个插件,可以通过命令行,来输出搜集到的测试用例的相关信息并保存到csv文件中去。

    可以直接在上面生成好的插件项目模板里写我们自己的代码。

    • 红色文件,就是我们插件代码的主体部分
    • 绿色部分,是我们自测插件代码的地方

    最后还有个重要文件setup.py,因为插件模板项目自动生成了,里面就是插件项目的相关信息,以及依赖。

    1. 插件主体代码

    import pytest
    import csv
    import re
    
    pytest_plugins = 'pytester'
    
    def pytest_addoption(parser):
        group = parser.getgroup("testplan")
        group.addoption("--testplan",
                           action="store",
                           default=None,
                           help="生成包含测试元数据的CSV并退出,而不运行测试"
                       )
    
    
    def pytest_collection_modifyitems(session, config, items):
        path = config.getoption('testplan')
        if path:
            with open(path, mode='w') as fd:
                writer = csv.writer(fd, delimiter=',', quotechar='"',
                                    quoting=csv.QUOTE_MINIMAL)
                writer.writerow(["title", "description", "markers"])
    
                for item in items:
                    title = item.nodeid
                    description = re.sub('\n\s+', '\n', item.obj.__doc__.strip())
                    markers = ','.join([m.name for m in item.iter_markers()])
                    writer.writerow([title, description, markers])
    
            pytest.exit(f"测试计划已生成: {path}")
    
    • pytest_addoption: 添加命令行参数
    • pytest_collection_modifyitems: 重写搜集用例的这个钩子函数

    主要就是把搜集到的case的标题,描述和markers这3样写到 csv 文件中。

    2. 测试插件代码

    插件主体代码写好了,我们需要自测一下。

    按之前的话,可以直接把插件代码写到本地conftest文件里作为本地代码直接调用测试即可。

    不过 Pytest 附带一个名为pytester的插件,它可以帮助我们为插件代码编写测试。这个插件在默认情况下是禁用的,所以在使用之前要先开启。

    在 test 目录下的 conftest 文件中声明即可。

    接下来上插件测试代码,然后讲解一下相关用法:

    import pytest
    
    def test_pingguo(pytester):
        """Make sure that our plugin works."""
        pytester.makeini(
            """
            [pytest]
            markers =
                nightly
                performance
                integration
                high
                medium
                low
            """
        )
    
        pytester.makepyfile(
            """
                import pytest
                
                @pytest.mark.performance
                def test_one():
                    \"""test_one\"""
                    assert False
                
                
                @pytest.mark.high
                def test_two():
                    \"""test_two\"""
                    assert True
                
                
                def test_three():
                    \"""test_three\"""
                    assert True
                
                
                class TestPingGuo():
                    @pytest.mark.high
                    @pytest.mark.performance
                    def test_a(self):
                        \"""
                        TestPingGuo.test_a,测试
                        \"""
                        assert False
                
                    def test_b(self):
                        \"""
                        TestPingGuo.test_b
                        测试
                        \"""
                        assert True
            """
        )
    
        # run all tests with pytest
        result = pytester.runpytest("--testplan=testplan.csv")
    
    

    这里最重要的就是pytester提供的方法,比如上面用到的:

    • pytester.makeini:因为我的测试case上加了不同的 marker,这些是需要注册在 ini 文件里的
    • pytester.makepyfile: 这里就是写的测试用例代码了

    其实就是在对应的方法里,写上我们的原生代码,只是需要被""" """包起来,当做字符串,然后 pytest 会自行解析我们的代码,在临时目录里创建对应的文件然后运行。

    不仅如此,还可以创建其他的文件,比如conftest。这是源码,有兴趣的可以进去一探究竟。

    pytester.runpytest("--testplan=testplan.csv")这里可以添加要执行的命令行参数。

    运行测试

    直接运行测试代码,看下结果。

    注意我这里的文件也是被生成在了临时目录里,打开控制台输出的路径就可以找到。

    打开 csv 文件验证一下结果,输出正确。

    3. 打包

    回到项目根目录,命令行输入:

    python setup.py sdist build
    

    完成后会生成dist目录,下面就有对应的包。

    4. 上传 pypi

    没有账号的要先注册登录一下,记得要去对应填写的邮箱里点击激活认证才可以。

    接着安装twine,我能使用这个工具来上传。

    pip install twine
    

    安装完成后就可以执行了上传:

    twine upload dist/*
    

    提示需要输入注册的账号和密码,最后完成上传。

    上传完成后就可以在pypi中打开自己的插件主页了,现在其他小伙伴也可以安装插件了。

  • 相关阅读:
    请立即修复!服务器巨头核心固件曝7个高危漏洞
    kubernetes驱逐机制总结
    基于单片机的空气质量检测系统
    NLP中的对抗训练(附PyTorch实现)
    隔离上网,安全上网
    Maven 私服搭建指南
    C++实现最小栈
    FLASK中的鉴权的插件Flask-HTTPAuth
    17. 机器学习——SVM
    k8s-部署rancher-页面化管理
  • 原文地址:https://www.cnblogs.com/pingguo-softwaretesting/p/16803980.html