pytest文檔之內置fixture之request

測試架構師百里 發佈 2022-07-11T19:17:33.201783+00:00

FixtureRequest 是來自 fixture 或者 測試用例的請求,它有訪問測試上下文的權限, FixtureRequest_pytest.fixtures  pytest documentation。我們使用request.module屬性來從測試模塊中選擇性地獲取smtpserver屬性。

前言

request 是 pytest 的內置 fixture , "為請求對象提供對請求測試上下文的訪問權,並且在fixture被間接參數化的情況下具有可選的「param」屬性。"這是官方文檔對request的描述,可參考的文檔不多。

一、FixtureRequest

FixtureRequest 是來自 fixture 或者 測試用例的請求,它有訪問測試上下文的權限, FixtureRequest_pytest.fixtures pytest documentation。

class FixtureRequest[原始碼](https://docs.pytest.org/en/latest/_modules/_pytest/fixtures.html#FixtureRequest)

請求對象提供對請求的測試上下文的訪問,並且具有可選的 param 屬性,以防設備被間接參數化。

fixturename
正在為其執行此請求的 fixture 名稱。

scope
作用域字符串,「function」、「class」、「module」、「session」之一。

fixturenames
此請求中所有活動狀態的 fixture 的名稱。

node
基礎集合節點(取決於當前請求範圍)。

config
與此請求關聯的 pytest 配置對象。

function
如果請求具有每個函數範圍,則測試函數對象。

cls
類(可以是None),其中收集了測試函數。

instance
在其上收集測試函數的實例(可以是None)。

module
收集測試函數的Python模塊對象。

fspath
收集此測試的測試模塊的文件系統路徑。

keywords
基礎節點的關鍵字/標記詞典。

session
Pytest會話對象。

addfinalizer(finalizer: Callable[], object]) → None[原始碼]
添加finalizer/teardown函數,以便在請求的測試上下文中的最後一個測試完成執行後調用。

applymarker(marker) → None[原始碼]
對單個測試函數調用應用標記。

如果不希望在所有函數調用上都有關鍵字/標記,則此方法非常有用。

參數
marker -- A _pytest.mark.MarkDecorator 調用創建的對象 pytest.mark.NAME(...) .

raiseerror(msg: Optional[str]) → NoReturn[原始碼]
使用給定的消息引發FixtureLookupError。

getfixturevalue(argname: str) → Any[原始碼]
動態運行命名的fixture函數。

如果可能,建議通過函數參數聲明fixtures。但是,如果您只能在測試設置時決定是否使用另一個fixture,那麼您可以使用此函數在fixture或測試函數體中檢索它。

引發
pytest.FixtureLookupError -- 如果找不到給定的固定裝置。
摺疊 

二、request.param

前面講fixture參數化的時候,有接觸到 "request.param" 用於獲取測試的請求參數,以下示例

'''
import pytest

# 測試數據
test_data = ["user1", "user2"]


@pytest.fixture(params=test_data)
def register_users(request):
     # 獲取當前的測試數據
     user = request.param
     print("\n拿著這個帳號去註冊:%s"%user)
     result = "success"
     return user, result


def test_register(register_users):
    user, result = register_users
    print("在測試用例裡面裡面獲取到當前測試數據:%s"%user)
    print(result)
    assert result == "success"

此案例裡面我們可以在fixture參數化的時候,通過request.param獲取到測試的請求參數,但是在用例裡面用 request.param 卻不能獲取到測試的請求參數

def test_register_x(register_users, request):
    print(request.param)

這樣運行,會拋異常:'FixtureRequest' object has no attribute 'param'

拿著這個帳號去註冊:user1
F
register_users = ('user1', 'success')
request = <FixtureRequest for <Function test_register_x[user1]>>

    def test_register_x(register_users, request):
>       print(request.param)
E       AttributeError: 'FixtureRequest' object has no attribute 'param'

D:\test_x7.py:27: AttributeError

三、request.config

request.config 是獲取測試的配置文件參數,這個在前面講命令行參數的時候有用到過.

在 conftest.py 寫一個 hook函數, pytest_addoption 的作用是用於獲取命令行參數,request.config 用於讀取測試的配置數據

import pytest


def pytest_addoption(parser):
    parser.addoption(
        "--cmdopt", action="store", default="type1", help="my option: type1 or type2"
    )

@pytest.fixture
def cmdopt(request):
    return request.config.getoption("--cmdopt")

於是在測試用例裡面可以通過 request.config 來獲取到配置參數,也可以通過自己定義的 cmdopt 來獲取。

import pytest

def test_answer_1(request):
    type = request.config.getoption("--cmdopt")
    print("獲取到命令行參數:%s" % type)


def test_answer_2(cmdopt):
    print("獲取到命令行參數:%s" % cmdopt)

四、request.module

fixture 函數可以通過接受 request 對象來反向獲取請求中的測試函數、類或模塊上下文,進一步擴展之前的 smtp fixture示例,讓我們從fixture的測試模塊讀取可選的伺服器URL
這是官方文檔的一個示例

# conftest.py

@pytest.fixture(scope="module")
def smtp(request):
    server = getattr(request.module, "smtpserver", "smtp.qq.com")
    print("fixture 獲取到的server :%s" %server)
    smtp = smtplib.SMTP(server, 587, timeout=5)
    yield smtp
    print("完成 %s (%s)" % (smtp, server))
    smtp.close()

我們使用request.module屬性來從測試模塊中選擇性地獲取smtpserver屬性
快速創建另一個測試模塊,在其模塊名稱空間中實際設置伺服器URL,新建一個test_anothersmtp.py文件,輸入以下代碼:

# test_anothersmtp.py
smtpserver = "mail.python.org"

def test_showhelo(smtp):

    print("case showhelo")

這時候運行用例,會獲取到 test_anothersmtp.py 裡面定義的 smtpserver

============================= test session starts =============================
platform win32 -- Python 3.6.6, pytest-4.5.0, py-1.9.0, pluggy-0.13.1
Test order randomisation NOT enabled. Enable with --random-order or --random-order-bucket=<bucket_type>
rootdir: D:\
rerunfailures-9.1, xdist-2.1.0
collected 1 item

..\..\..\..\module2\test_anothersmtp.py 
fixture 獲取到的server :mail.python.org
case showhelo
.完成 <smtplib.SMTP object at 0x000001D00754CB00> (mail.python.org)


========================== 1 passed in 0.64 seconds ===========================

用例裡面沒定義 smtpserver 的話,會用默認屬性 "smtp.qq.com"

五、request的相關成員對象

在conftest.py 寫一個fixture 可以獲取到request的一些成員對象相關信息

# conftest.py

@pytest.fixture(autouse=True)
def print_request(request):
    print("\n=======================request start=================================")
    print(request.module)
    print(request.function)
    print(request.cls)
    print(request.fspath)
    print(request.fixturenames)
    print(request.fixturename)
    print(request.scope)
    print("\n=======================request end=================================")

使用命令行"pytest -s text_x.py"運行用例,會看到列印的結果

test_1.py
=======================request start=================================
<module 'web.cases.module2.test_1' from 'D:\\web\\cases\\module2\\test_1.py'>
<function test_answer_1 at 0x0000012D1C9FD9D8>
None
D:\web\cases\module2\test_1.py
['_verify_url', 'base_url', '__pytest_repeat_step_number', 'show_request', 'request']
show_request
function

=======================request end=================================
獲取到命令行參數:type1
.
=======================request start=================================
<module 'web.cases.module2.test_1' from 'D:\\web\\cases\\module2\\test_1.py'>
<function test_answer_2 at 0x0000012D1C9FD730>
None
D:\web\cases\module2\test_1.py
['_verify_url', 'base_url', '__pytest_repeat_step_number', 'show_request', 'cmdopt', 'request']
show_request
function

=======================request end=================================

在列印測試用例的詳細日誌的時候,還是很有用的。

總結

今天的文章就到這裡了喲,喜歡的小夥伴記得點讚收藏評論加關注喲。

關鍵字: