【pytest官方文檔】解讀- 如何自定義mark標記,並將測試用例的數據傳遞給fixture函數
- 2022 年 9 月 6 日
- 筆記
- pytest學習筆記, 把蘋果咬哭的不規律日常
在之前的分享中,我們知道可以使用yield
或者return
關鍵字把fixture函數
里的值傳遞給test函數
。
這種方法很實用,比如我在fixture函數
里向資料庫里插入必要的測試數據,那我就可以把相關數據返回給test函數
用來做相關斷言查詢等操作。
那如果我想把test函數
(也就是測試用例)中的數據傳給fixture函數
使用,要如何實現呢?
直接先貼上一段示例程式碼:
import pytest
@pytest.fixture
def fixt(request):
marker = request.node.get_closest_marker("fixt_data")
if marker is None:
# Handle missing marker in some way...
data = None
else:
data = marker.args[0]
# Do something with the data
return data
@pytest.mark.fixt_data(42)
def test_fixt(fixt):
assert fixt == 42
一、前置知識
程式碼中可能有2個知識點,可能有的小夥伴並不熟悉,分別來看下。
1. Mark 標記
什麼是mark
標記,幹什麼用?
標記
可以將元數據應用於測試函數(注意,不能是fixture函數),後續可以通過fixture函數
或者plugins插件
進行訪問。
框架有一些內置
的marks,也可以支援我們自定義
。
內置的在之前的系列分享中有出現過幾個,比如:
pytest.mark.parametrize
:參數化pytest.mark.skip
:跳過測試用例pytest.mark.skipif
: 根據條件跳過用例
其他就不展開了,上述提到的分享文章鏈接會附在文末。
而在上述示例程式碼中,pytest.mark.fixt_data
則是屬於自定義的mark標記,fixt_data
我也可以改成fixt_pingguo
也是可以的。
2. request
request
本身也是一個fixture函數,但是很特殊
,用於提供當前正在執行請求的上下文資訊。
在上述示例程式碼中,測試函數test_fixt
請求了fixture函數fixt
,那麼在這次請求中相關聯到的資訊就可以在request
中獲得。
比如:
fixturename
: 當前這個fixture函數的名稱module
: 當前測試函數所在的模組scope
:當前fixture函數作用範圍node
:基於當前測試範圍搜集到的底層節點對象,這裡又包含了很多資訊。
…
就不一一展開了,有興趣的童鞋可以在編輯器里打個斷點,查看對應的資訊詳情。
二、通過自定義mark傳遞數據
回到示例程式碼,我們可以先直接執行一下程式碼。
測試是通過的(warning先忽略,因為沒有註冊自定義的mark),也就是說@pytest.mark.fixt_data(42)
中的42
是成功的帶到了fixture函數
中,經過函數中的處理後最後返回出來。
其中的get_closest_marker("fixt_data")
方法,是返回與名稱fixt_data
匹配的第一個mark,從最近的級別到更遠的級別,比如從函數到模組級別。
所以在這裡,被找到的mark就是我們自定義的這個@pytest.mark.fixt_data(42)
標記了。
1. 自定義mark知識點
標記是使用工廠對象pytest.mark
動態創建的,用於裝飾器,所以我們可以用語法糖@
直接使用即可。
mark對象被創建之後,就被會收集起來,然後可以通過fixture
或帶有Node.iter_markers
的鉤子函數訪問,可以訪問到這個mark對象的屬性。
有 2 個屬性:
mark.args
:這是個元組mark.kwargs
:這是個字典
所以我們可以使用上面的方式來進行傳參,比如現在新建一個自定義mark:
@pytest.mark.timeout(10, "slow", method="thread")
def test_function():
...
這裡傳參實際上就是
mark.args == (10, "slow")
mark.kwargs == {"method": "thread"}
回到最上方的示例程式碼,在fixture函數
中就可以使用data = marker.args[0]
來獲取到參數42
。
如果在測試函數上同時使用了多個自定義mark
,那麼舉例測試函數最近的mark就會被首先迭代。比如:
@pytest.mark.timeout(10, "slow", method="thread")
@pytest.mark.slow
def test_function():
...
結果就是先@pytest.mark.slow
,然後是@pytest.mark.timeout
。
2. 註冊自定義的mark
在運行最上方的示例程式碼時出現了一個warning,因為我們沒有註冊自定義的標記導致,現在來進行註冊。
新建pytest.ini
配置文件,在裡面添加即可:
[pytest]
markers =
fixt_data: pingguo test
fixt_data2
這裡冒號:
後面的描述是可選的,比如fixt_data2
就是沒有添加描述。
重新執行下最上方的程式碼:
platform win32 -- Python 3.9.12, pytest-7.1.3, pluggy-1.0.0
rootdir: D:\PythonCode\my_python, configfile: pytest.ini
collected 1 item
usemarks.py .
============================== 1 passed in 0.00s ==============================
Process finished with exit code 0
註冊完成。
pytest合集見連接