【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這個項目。這是官方文檔中強烈推薦的,可以幫助我們快速生成一個規範標準的插件項目。

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

跟著項目介紹的文檔一步步來就行。

先安裝該項目:

$ pip install cookiecutter

然後可以使用這個工具開始創建我們自己的插件項目了。

$ cookiecutter //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中打開自己的插件主頁了,現在其他小夥伴也可以安裝插件了。