• pytest文档55-plugins插件开发


    前言

    前面一篇已经学会了使用hook函数改变pytest运行的结果,代码写在conftest.py文件,实际上就是本地的插件了。
    当有一天你公司的小伙伴觉得你写的还不错,或者更多的小伙伴想要你这个功能,于是你就想着放到github上,写成一个插件,方便小伙伴使用pip去安装。

    插件开发

    先新建一个工程,工程名称就是插件名称,一般以pytest-开头命名,目录结构如下

    • setup.py 在安装python的相关模块和库时,我们一般使用pip install 模块名或者python setup.py install,前者是在线安装,会安装该包的相关依赖包;
      后者是下载源码包然后在本地安装,不会安装该包的相关依赖包

    • README.rst README 文档,告诉用户如何使用你的插件,具体能实现什么功能

    • pytest_change_report.py 也就是之前conftest.py里面写的hook函数实现的功能

    • tests 用于测试本插件的相关功能,属于自测的内容

    • tests/conftest.py 开启需要的插件pytester

    • tests/test_change_report.py 测试插件的代码

    setup.py

    在安装python的相关模块和库时,我们一般使用pip install 模块名或者python setup.py install,前者是在线安装,会安装该包的相关依赖包;
    后者是下载源码包然后在本地安装,不会安装该包的相关依赖包.
    setup.py 描述安装包相关的信息

    from setuptools import setup
    
    """The setup script.
    # 作者-上海悠悠 QQ交流群:717225969
    # blog地址 https://www.cnblogs.com/yoyoketang/
    """
    
    setup(
        name='pytest-change-report',
        url='https://github.com/yoyoketang/pytest-change-report',
        version='1.0',
        author="yoyo",
        author_email='283340479@qq.com',
        description='turn . into √,turn F into x',
        long_description='print result on terminal turn . into √,turn F into x using hook',
        classifiers=[
            'Framework :: Pytest',
            'Programming Language :: Python',
            'Topic :: Software Development :: Testing',
            'Programming Language :: Python :: 3.6',
        ],
        license='proprietary',
        py_modules=['pytest_change_report'],
        keywords=[
            'pytest', 'py.test', 'pytest-change-report',
        ],
    
        install_requires=[
            'pytest'
        ],
        entry_points={
            'pytest11': [
                'change-report = pytest_change_report',
            ]
        }
    )
    

    pytest_change_report.py

    插件的核心功能,也就是之前在conftest.py用hook函数实现的功能。
    我们现在实现的功能:
    1.把测试的结果.改成√,F改成x
    2.命令行加个--change参数开关,默认不开启,当加上参数`--change on·的时候才生效

    import pytest
    # 作者-上海悠悠 QQ交流群:717225969
    # blog地址 https://www.cnblogs.com/yoyoketang/
    
    
    def pytest_addoption(parser):
        parser.addoption(
            "--change",
            action="store",
            default="off",
            help="'Default 'off' for change, option: on or off"
        )
    
    
    def pytest_report_teststatus(report, config):
        '''turn . into √,turn F into x, turn E into 0'''
        if config.getoption("--change") == "on":
            if report.when == 'call' and report.failed:
                return (report.outcome, 'x', 'failed')
            if report.when == 'call' and report.passed:
                return (report.outcome, '√', 'passed')
    

    测试插件

    当插件功能实现完成后,需要在tests目录测试自己写的插件

    tests/conftest.py 文件开启pytester,专门用于测试插件的

    '''pytester is needed for testing plgugins.'''
    
    
    pytest_plugins = ['pytester']
    

    tests/test_change_report.py 文件写测试用例

    import pytest
    # 作者-上海悠悠 QQ交流群:717225969
    # blog地址 https://www.cnblogs.com/yoyoketang/
    
    def test_raw_report(testdir):
        """Make sure that our plugin works."""
        # create a temporary pytest test file
        testdir.makepyfile(
            """
            def test_01():
                a = "hello"
                b = "hello"
                assert a == b
    
            def test_02():
                a = "hello"
                b = "hello world"
                assert a == b
             """
                )
    
        # run all tests with pytest
        result = testdir.runpytest()
    
        # check that 1 test passed, 1 test failed.
        result.assert_outcomes(passed=1, failed=1)
        result.stdout.fnmatch_lines(["*.F*", ])
    
    def test_change_on_report(testdir):
        """Make sure that our plugin works."""
        # create a temporary pytest test file
        testdir.makepyfile(
            """
            def test_01():
                a = "hello"
                b = "hello"
                assert a == b
    
            def test_02():
                a = "hello"
                b = "hello world"
                assert a == b
             """
                )
    
        # run all tests with pytest
        result = testdir.runpytest("--change", "on")
    
        # check that 1 test passed, 1 test failed.
        result.stdout.fnmatch_lines(['*√x*', ])
    
    
    def test_change_off_report(testdir):
        """Make sure that our plugin works."""
        # create a temporary pytest test file
        testdir.makepyfile(
            """
            def test_01():
                a = "hello"
                b = "hello"
                assert a == b
    
            def test_02():
                a = "hello"
                b = "hello world"
                assert a == b
             """
                )
    
        # run all tests with pytest
        result = testdir.runpytest("--change", "off")
    
        # check that 1 test passed, 1 test failed.
        result.stdout.fnmatch_lines(['*.F*', ])
    
    
    def test_change_default_report(testdir):
        """Make sure that our plugin works."""
        # create a temporary pytest test file
        testdir.makepyfile(
            """
            def test_01():
                a = "hello"
                b = "hello"
                assert a == b
    
            def test_02():
                a = "hello"
                b = "hello world"
                assert a == b
             """
                )
    
        # run all tests with pytest
        result = testdir.runpytest("--change")
    
        # check stderr pytest: error: argument --change: expected one argument
        result.stderr.fnmatch_lines(['*argument --change: expected one argument*', ])
    
    
    def test_verbose_report(testdir):
        """Make sure that our plugin works."""
        # create a temporary pytest test file
        testdir.makepyfile(
            """
            def test_01():
                a = "hello"
                b = "hello"
                assert a == b
    
            def test_02():
                a = "hello"
                b = "hello world"
                assert a == b
             """
                )
    
        # run all tests with pytest
        result = testdir.runpytest("-v")
    
        # check that 1 test passed, 1 test failed.
        result.stdout.fnmatch_lines(['*::test_01 PASSED*', '*::test_02 FAILED*'])
    
    
    
    def test_change_verbose_report(testdir):
        """Make sure that our plugin works."""
        # create a temporary pytest test file
        testdir.makepyfile(
            """
            def test_01():
                a = "hello"
                b = "hello"
                assert a == b
    
            def test_02():
                a = "hello"
                b = "hello world"
                assert a == b
             """
                )
    
        # run all tests with pytest
        result = testdir.runpytest("--change", "on", "-v")
    
        # check that 1 test passed, 1 test failed.
        result.stdout.fnmatch_lines(['*::test_01 passed*', '*::test_02 failed*'])
    
    
    def test_help(testdir):
        """Make sure that our plugin works."""
        # create a temporary pytest test file
        testdir.makepyfile(
            """
            def test_01():
                a = "hello"
                b = "hello"
                assert a == b
             """
                )
    
        # run all tests with pytest
        result = testdir.runpytest("--help")
    
        # check --help
        result.stdout.fnmatch_lines(["*--change=*", ])
    

    本地安装插件

    cd到插件的项目目录,使用pip安装

    pip install .

    >pip install .
    Processing d:softpytest-change-report
    Using legacy setup.py install for pytest-change-report, since package 'wheel' is not installed.
    Installing collected packages: pytest-change-report
      Attempting uninstall: pytest-change-report
        Found existing installation: pytest-change-report 1.0
        Uninstalling pytest-change-report-1.0:
          Successfully uninstalled pytest-change-report-1.0
        Running setup.py install for pytest-change-report ... done
    Successfully installed pytest-change-report-1.0
    

    安装完成后,在cmd输入 pip show pytest-change-report就可以看到前面setup.py里面的描述内容

    >pip show pytest-change-report
    Name: pytest-change-report
    Version: 1.0
    Summary: turn . into √,turn F into x
    Home-page: https://github.com/yoyoketang/pytest-change-report
    Author: yoyo
    Author-email: 283340479@qq.com
    License: proprietary
    Location: e:python36libsite-packagespytest_change_report-1.0-py3.6.egg
    Requires: pytest
    Required-by:
    

    安装完成后,输入pytest测试tests/test_change_report.py

    >pytest
    ============================= test session starts =============================
    
    collected 7 items
    
    tests	est_change_report.py .......                                      [100%]
    
    ========================== 7 passed in 0.89 seconds ===========================
    

    测试文件里面的用例全部通过

    README.rst

    最后需要写个 README.rst 使用教程文档,这样你写的插件就能被其它小伙伴学习和使用了。

    ==============
    pytest-change-report: pytest plugin
    ==============
    
    
    **This pytest plugin turn . into √,turn F into x**
    
    
    Usage
    =====
    
    从github源码安装
    
       pip install git+https://github.com/yoyoketang/pytest-change-report.git
    
    命令行运行示例
    
       pytest --change on
    
    
    demo
    ====
    
    先写pytest用例test_demo.py
    
        def test_01():
            a = "hello"
            b = "hello"
            assert a == b
    
    
        def test_02(login):
            a = "hello"
            b = "hello world"
            assert a == b
    
    命令行执行pytest, 默认不会改变之前的报告内容
    
        >pytest test_demo.py
        ============================= test session starts =============================
        collected 2 items
    
        test_demo.py .F                                                          [100%]
    
        ================================== FAILURES ===================================
        ___________________________________ test_02 ___________________________________
    
            def test_02():
                a = "hello"
                b = "hello world"
        >       assert a == b
        E       AssertionError: assert 'hello' == 'hello world'
        E         - hello
        E         + hello world
    
        test_demo.py:10: AssertionError
        ===================== 1 failed, 1 passed in 0.11 seconds ======================
    
    加上 --change on 参数后运行
    
        >pytest test_demo.py --change on
        ============================= test session starts =============================
        collected 2 items
    
        test_demo.py √x                                                          [100%]
    
        ================================== FAILURES ===================================
        ___________________________________ test_02 ___________________________________
    
            def test_02():
                a = "hello"
                b = "hello world"
        >       assert a == b
        E       AssertionError: assert 'hello' == 'hello world'
        E         - hello
        E         + hello world
    
        test_demo.py:10: AssertionError
        ===================== 1 failed, 1 passed in 0.08 seconds ======================
    
    
    
    pytest.ini
    ==========
    
    可以添加到pytest.ini配置文件,这样默认就会带上--change参数
    
          [pytest]
          --change = on
    
    # 作者-上海悠悠 QQ交流群:717225969
    # blog地址 https://www.cnblogs.com/yoyoketang/
    

    提交github

    最后把插件代码提交到github仓库,方便下载https://github.com/yoyoketang/pytest-change-report

  • 相关阅读:
    java实现动态上传多个文件并解决文件重名问题
    MySQL存储过程之事务管理
    Java IO--字符流--InputStreamReader 和 OutputStreamWriter
    Java IO--字符流--BufferedReader和BufferedWriter
    java线程同步小结
    进程和线程的区别与联系
    java中“==”和equals方法的区别,再加上特殊的String引用类型
    java.util.Date 与 java.sql.Date 之间的转换
    Java Applet 与Servlet之间的通信
    Applet 应用程序进行数字签名,对系统文件进行读写操作
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/13638661.html
Copyright © 2020-2023  润新知