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:\soft\pytest-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:\python36\lib\site-packages\pytest_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\test_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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM