pytest利用request?fixture實(shí)現(xiàn)個(gè)性化測(cè)試需求詳解
前言
在深入理解 pytest-repeat 插件的工作原理這篇文章中,我們看到pytest_repeat
源碼中有這樣一段
看到參數(shù)為request
,我們知道fixture裝飾的函數(shù)入?yún)ⅲ荒苁瞧渌鹒ixture,所以這里request
一定也是fixture
。那它到底怎么用呢?這篇文章將詳細(xì)介紹,并通過實(shí)戰(zhàn)項(xiàng)目加深理解。
request fixture
The request fixture is a special fixture providing information of the requesting test function.
這是pytest
官方文檔的介紹,意思就是請(qǐng)求fixture是一個(gè)特殊的fixture,提供請(qǐng)求測(cè)試函數(shù)的信息。
源碼直達(dá),感興趣的朋友可以查看源碼FixtureRequest
request.node
當(dāng)前測(cè)試用例的節(jié)點(diǎn)對(duì)象,表示當(dāng)前執(zhí)行的測(cè)試用例??梢允褂迷搶?duì)象獲取測(cè)試用例的名稱、文件路徑、測(cè)試類等信息。
import pytest ? ? @pytest.fixture def my_fixture(request): ? ?node = request.node ? ?print(f"Current test case: {node.name}") ? ?print(f"Test file path: {node.fspath}") ? ?print(f"Test class: {node.getparent}") ? ? ? def test_demo(my_fixture): ? ?pass
輸出結(jié)果為:
Current test case: test_demo
Test file path: /Users/pxl/test_dir/test_demo.py
Test class: <bound method Node.getparent of <Function test_demo>>
fixture 使用了 request
參數(shù),并通過 request.node
獲取了當(dāng)前測(cè)試用例的相關(guān)信息。具體來說,我們打印了當(dāng)前測(cè)試用例的名稱、文件路徑和測(cè)試類名稱。
request.config
前運(yùn)行的配置對(duì)象,表示當(dāng)前 Pytest 的配置信息??梢允褂迷搶?duì)象獲取命令行參數(shù)、配置文件設(shè)置等信息。
pytest.ini
[pytest] markers = ? ?p0: 冒煙 ? ?p1: 功能
@pytest.fixture def my_fixture(request): ? ?config = request.config ? ?print(f"Command line arguments: {config.option}") ? ?print(f"INI file options: {config.getini('markers')}")
該 fixture 使用了 request
參數(shù),并通過 request.config
獲取了當(dāng)前 Pytest 的配置信息。具體來說,我們打印了命令行參數(shù)和配置文件中的一個(gè)選項(xiàng)。
request.param
當(dāng)前 fixture 的參數(shù),表示當(dāng)前 fixture 的實(shí)例所需的參數(shù)值
@pytest.fixture(params=[1, 2, 3]) def my_fixture(request): ? ?param_value = request.param ? ?print(f"Current parameter value: {param_value}") ? ?return param_value
該 fixture 使用了 request
參數(shù),并通過 request.param
獲取了當(dāng)前實(shí)例所需的參數(shù)值。
request.fixturename
返回當(dāng)前 fixture 的名稱。
@pytest.fixture def my_fixture(request): ? ?fixture_name = request.fixturename ? ?print(f"Current fixture name: {fixture_name}")
我們使用 request.fixturename
獲取了當(dāng)前 fixture 的名稱,并將其打印出來.
request.fixturenames
返回當(dāng)前測(cè)試函數(shù)所使用的所有 fixture 的名稱列表
@pytest.fixture def my_fixture(request): ? ?pass ? def test_example(my_fixture, request): ? ?fixture_names = request.fixturenames ? ?print(f"Current fixture name: {fixture_names}") ?
我們使用 request.fixturename
s獲取了test_example
使用的所有 fixture 的名稱
request.cls
當(dāng)前測(cè)試類的類對(duì)象。
class TestClass: ? ?@pytest.fixture ? ?def my_fixture(self, request): ? ? ? ?class_obj = request.cls ? ? ? ?print(f"Current class object: {class_obj}")
使用 request.cls
獲取了當(dāng)前測(cè)試類的類對(duì)象,并將其打印出來。
request.addfinalizer(finalizer_func)
在 fixture 完成后執(zhí)行指定的函數(shù)。
@pytest.fixture def my_fixture(request): ? ?def finalizer_func(): ? ? ? ?print("Finalizer function called") ? ? ?request.addfinalizer(finalizer_func) ? ? ?print("Fixture setup")
我們使用 request.addfinalizer()
方法注冊(cè)了一個(gè) finalizer 函數(shù) finalizer_func
。該函數(shù)將在 fixture 執(zhí)行完畢后被調(diào)用,并打印一條消息。
request.applymarker(marker)
為當(dāng)前測(cè)試用例或 fixture 應(yīng)用指定的 marker。
@pytest.fixture def my_fixture(request): ? ?request.applymarker(pytest.mark.slow)
我們使用 request.applymarker()
方法為當(dāng)前 fixture 添加了一個(gè) pytest.mark.slow
的標(biāo)記。這個(gè)標(biāo)記可以被 Pytest 識(shí)別并用于特定的測(cè)試運(yùn)行策略。
request.config.getoption(name)
獲取命令行選項(xiàng)的值。
@pytest.fixture def my_fixture(request): ? ?my_option = request.config.getoption("--my_option") ? ?print(f"Value of --my_option: {my_option}")
我們使用 request.config.getoption()
方法獲取了命令行選項(xiàng) --my_option
的值,并將其打印出來。
request.module
當(dāng)前測(cè)試用例所屬的模塊對(duì)象
def my_fixture(request): ? ?module_obj = request.module ? ?print(f"Current module object: {module_obj}")
我們使用 request.module
獲取了當(dāng)前測(cè)試用例所屬的模塊對(duì)象,并將其打印出來
request.param_index
參數(shù)化 fixture 的參數(shù)索引
@pytest.fixture(params=[1, 2, 3]) def my_fixture(request): ? ?param_value = request.param ? ?param_index = request.param_index ? ?print(f"Current parameter value: {param_value}") ? ?print(f"Current parameter index: {param_index}") ? ?return param_value
我們對(duì)帶有參數(shù)的 my_fixture
fixture 進(jìn)行了參數(shù)化。使用 request.param_index
可以獲取當(dāng)前參數(shù)在參數(shù)列表中的索引,并將其打印出來。
request.keywords
當(dāng)前測(cè)試用例的關(guān)鍵字集合
@pytest.fixture def my_fixture(request): ? ?keywords = request.keywords ? ?print(f"Current test keywords: pytest?request?fixture個(gè)性化測(cè)試,pytest?request?fixture")
我們使用 request.keywords
獲取了當(dāng)前測(cè)試用例的關(guān)鍵字集合,并將其打印出來
request.getfixturevalue(fixturename)
獲取已注冊(cè)的 fixture 對(duì)象的值
import pytest ? @pytest.fixture def my_fixture(): ? ?return "Hello, Fixture!" ? def test_example(request): ? ?fixture_value = request.getfixturevalue("my_fixture") ? ?assert fixture_value == "Hello, Fixture!" ?
實(shí)戰(zhàn)
到這里request fixture
的常用屬性和方法應(yīng)該了解差不多了。更多屬性和方法,可以參考官方文檔。
接下來我們就利用request
屬性實(shí)現(xiàn)數(shù)據(jù)庫環(huán)境的切換??磳?shí)現(xiàn)代碼
conftest.py
def pytest_addoption(parser): ? ?parser.addoption("--test", action="store_true", help="Run tests in test mode") ? ? @pytest.fixture(scope="session") def config_parser(request): ? ?class Clazz(object): ? ? ? ?config = ConfigParser() ? ? ? ?config.read(config_path) ? ? ? ?section = 'test' if request.config.getoption("--test") else 'prod' ? ? ? ?log.info(f"section: {config.sections()}") ? ? ? ?db_host = config.get(section, 'host') ? ? ? ?db_port = config.get(section, 'port') ? ? ? ?db_username = config.get(section, 'username') ? ? ? ?db_password = config.get(section, 'password') ? ? ? ?db_database = config.get(section, 'database') ? ? ? ?api_url = config.get(section, 'url') ? ? ?return Clazz ? ? @pytest.fixture(scope="session") def db_connection(config_parser): ? ?db_conn = MySQLDB( ? ? ? ?config_parser.db_host, ? ? ? ?int(config_parser.db_port), ? ? ? ?config_parser.db_username, ? ? ? ?config_parser.db_password, ? ? ? ?config_parser.db_database ? ) ? ? ?yield db_conn ? ? ?db_conn.close()
config_parser
是一個(gè)會(huì)話級(jí)別的 fixture,它返回一個(gè)配置解析器對(duì)象。這個(gè)配置解析器對(duì)象可以讀取配置文件,并根據(jù)傳入的命令行參數(shù) --test
來確定讀取哪個(gè)配置文件的特定部分(測(cè)試環(huán)境或生產(chǎn)環(huán)境)。具體流程如下:
a. 首先,在 pytest_addoption
函數(shù)中,通過調(diào)用 parser.addoption()
方法來添加一個(gè)命令行選項(xiàng) --test
,它的作用是告訴 pytest 在測(cè)試模式下運(yùn)行。
b. 在 config_parser
fixture 中,我們首先創(chuàng)建了一個(gè)名為 Clazz
的類,它包含了從配置文件中讀取的各個(gè)配置項(xiàng)的值。
c. 根據(jù)傳入的 --test
參數(shù)值,決定使用測(cè)試環(huán)境還是生產(chǎn)環(huán)境的配置。如果 --test
參數(shù)被指定,則使用配置文件中的 test
部分,否則使用 prod
部分。
d. 通過 config.get()
方法獲取具體的配置項(xiàng)的值,例如 db_host
、db_port
、db_username
等。
e. 最后,將 Clazz
類作為返回值,供其他測(cè)試代碼使用。
db_connection
是一個(gè)會(huì)話級(jí)別的 fixture,它返回一個(gè)數(shù)據(jù)庫連接對(duì)象。這個(gè)對(duì)象在測(cè)試期間可以被使用,并在測(cè)試完成后進(jìn)行關(guān)閉。具體流程如下:
a. 在 db_connection
fixture 中,我們創(chuàng)建了一個(gè) MySQLDB
對(duì)象,將從 config_parser
fixture 中獲取的數(shù)據(jù)庫連接參數(shù)傳入。
b. 使用 yield
語句將數(shù)據(jù)庫連接對(duì)象返回給測(cè)試代碼。yield
使得這個(gè) fixture 可以在測(cè)試期間提供數(shù)據(jù)庫連接,而在測(cè)試完成后繼續(xù)執(zhí)行下面的代碼。
c. 在 yield
之后的代碼將在測(cè)試完成后執(zhí)行,這里使用 db_conn.close()
來關(guān)閉數(shù)據(jù)庫連接。
可以看到我們正是使用request.config.getoption
這個(gè)方法來 獲取命令行選項(xiàng)的值。
這段代碼展示了如何使用 pytest 的 fixture 來管理測(cè)試環(huán)境和資源的初始化和清理。通過使用會(huì)話級(jí)別的 fixture,可以確保在整個(gè)測(cè)試會(huì)話期間只進(jìn)行一次配置解析和數(shù)據(jù)庫連接操作,避免重復(fù)的開銷和不必要的操作。
后續(xù)
到這里我們有攻克了一個(gè)知識(shí)點(diǎn)request
,不僅介紹了它的基本用法,也介紹了筆者在工作中真實(shí)使用場(chǎng)景。多加嘗試,才能印象深刻。
到此這篇關(guān)于pytest利用request fixture實(shí)現(xiàn)個(gè)性化測(cè)試需求詳解的文章就介紹到這了,更多相關(guān)pytest request fixture內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python 給DataFrame增加index行名和columns列名的實(shí)現(xiàn)方法
今天小編就為大家分享一篇python 給DataFrame增加index行名和columns列名的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-06-06詳解python的sorted函數(shù)對(duì)字典按key排序和按value排序
這篇文章主要介紹了詳解python的sorted函數(shù)對(duì)字典按key排序和按value排序,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08解決Pytorch 加載訓(xùn)練好的模型 遇到的error問題
今天小編就為大家分享一篇解決Pytorch 加載訓(xùn)練好的模型 遇到的error問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-01-01python中用ctypes模擬點(diǎn)擊的實(shí)例講解
在本篇文章里小編給各位整理了一篇關(guān)于python中用ctypes模擬點(diǎn)擊的實(shí)例講解內(nèi)容,需要的朋友可以參考學(xué)習(xí)下。2020-11-11基于python不同開根號(hào)的速度對(duì)比分析
這篇文章主要介紹了基于python不同開根號(hào)的速度對(duì)比分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-03-03