pytest使用parametrize將參數化變量傳遞到fixture
分享一個關於在pytest中,如何將測試用例文件中的變量傳遞到fixture函數。
一、交代應用場景
- 目前組內的項目,在根目錄下是有一個conftest.py文件的,這裡有個生成api token的fixture函數,就叫它gen_token()吧。
- 每個case包下,也會有個conftest.py,用於存放適用於本模塊下測試用例的fixture函數,比如有個叫setup_before()。
- 因為拿token是請求接口的前提,所以在case裡,比如有個test_case()裡,要傳頂層的fixture函數,也就是這樣test_case(gen_token)。
- 頂層的gen_token(),是需要3個傳參的。因為不同case可能涉及到的生成不同用戶的token,所以我們把這個參數放在瞭case文件裡。
ok,大背景是這樣的。
現在有小夥伴來需求瞭,她要在setup_before()裡去造數,通過請求另一個接口,這個請求也需要使用token。
那麼,問題也就可以轉化為:
- 要將case文件裡的參數,傳遞到fixture函數中。
- gen_token()裡返回的值,setup_before()和test_case()裡都要拿到。
二、使用@pytest.mark.parametrize、以及fixture的調用來解決
這裡把實際代碼抽象一下,轉化為簡易代碼,方便演示和理解:
# 目錄結構 -- /demo_top -- /demo_sub __init__.py conftest.py test_case.py __init__.py conftest.py
以下分別是/demo_top/conftest.py、/demo_top/demo_sub/conftest.py、/demo_top/demo_sub/test_case.py的內容。
1. /demo_top/conftest.py
# content of /demo_top/conftest.py import pytest @pytest.fixture() def gen_token(request): params = request.param print("\n根目錄下gen_token()拿到的參數:", params) if params[0] + params[1] == 5: return "api_token" else: return None
這裡,模擬生成token的fixture函數,當傳過來的值相加等於5,就會返回"api_token",否則返回None。
2. /demo_top/demo_sub/conftest.py
# content of /demo_top/demo_sub/conftest.py import pytest @pytest.fixture() def setup_before(request, gen_token): print("執行子級setup_before,拿到的傳參:", request.param) print("執行子級setup_before,拿到gen_token的返回值:", gen_token) if gen_token: yield "造數完成" print("測試用例test_case執行完畢,清理測試數據") else: pytest.skip("跳過")
這裡模擬瞭給測試用例造數據的fixture函數,如果沒拿到token的話,就跳過測試用例。
3. /demo_top/demo_sub/test_case.py
# content of /demo_top/demo_sub/test_case.py import pytest test_param = [(1, 4)] @pytest.mark.parametrize("gen_token", test_param, indirect=True) @pytest.mark.parametrize("setup_before", test_param, indirect=True) def test_case1(gen_token, setup_before): print("\n測試用例裡拿到的gen_token返回值:", gen_token) print("測試用例裡拿到的setup_before返回值:", setup_before) print("執行測試用例test_case1...") if __name__ == '__main__': pytest.main(['-s', 'test_case.py'])
這是測試用例文件瞭,裡面有個測試函數test_case1,因為它需要用到2個fixture函數返回的值,所以gen_token, setup_before都請求。
參數傳遞
- @pytest.mark.parametrize:使用pytest內置的parametrize,來把參數傳遞給目標fixture函數,你希望把參數傳遞給哪個fixture函數就加哪個。比如這裡的gen_token和setup_before,註意名稱與fixture名稱一致。
- indirect=True:作用是讓parametrize中的參數名稱,也就是"gen_token"當成函數執行,並且後面的參數值test_param,作為"gen_token"的傳參。
- request.param:接受傳參的fixture函數,使用request.param來獲取值。
fixture調用fixture
fixture之間的相互調用,在之前的文章裡已經有過詳述瞭。既然這裡setup_before依賴gen_token,之間傳遞調用即可setup_before(request, gen_token)。
在各環節做瞭些print打印出信息,幫助理解執行過程。
test_case.py [100%] ============================== 1 passed in 0.08s ============================== 根目錄下gen_token()拿到的參數: (1, 4) 執行子級setup_before,拿到的傳參: (1, 4) 執行子級setup_before,拿到gen_token的返回值: api_token . 測試用例裡拿到的gen_token返回值: api_token 執行測試用例test_case1... 測試用例test_case執行完畢,清理測試數據 Process finished with exit code 0
再看下gen_token不返回token的情況,改下傳參test_param = [(2, 4)]。
test_case.py [100%] ============================= 1 skipped in 0.08s ==============================s 根目錄下gen_token()拿到的參數: (2, 4) 執行子級setup_before,拿到的傳參: (2, 4) 執行子級setup_before,拿到gen_token的返回值: None Skipped: 跳過 Process finished with exit code 0
測試用例不執行。
以上就是pytest使用parametrize將參數化變量傳遞到fixture的詳細內容,更多關於pytest parametrize變量傳遞fixture的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- python單測框架之pytest常見用法
- Pytest框架 conftest.py文件的使用詳解
- pytest接口測試之fixture傳參數request的使用
- Python基礎教程之pytest參數化詳解
- 詳解如何使用Pytest進行自動化測試