Python中Pytest測(cè)試框架的fixture使用詳解
1、fixture的含義
fixture的目的是提供一個(gè)測(cè)試的基線,在此基線基礎(chǔ)上,可以更可靠的進(jìn)行重復(fù)測(cè)試。
2、fixture的優(yōu)勢(shì)
Pytest的fixture相對(duì)于傳統(tǒng)的xUnit的setup/teardown函數(shù)做了顯著的改進(jìn):
(1)測(cè)試fixture有明確的名稱,通過在函數(shù)/模塊/類或者整個(gè)項(xiàng)目中激活來(lái)使用
(2)測(cè)試fixture是模塊化的實(shí)現(xiàn),使用fixture名即可觸發(fā)特定的fixture,fixture可以在其他fixture中進(jìn)行使用測(cè)試fixture不僅可以進(jìn)行簡(jiǎn)單的單元測(cè)試,也可以進(jìn)行復(fù)雜的功能測(cè)試??梢愿鶕?jù)配置和組件的選項(xiàng)進(jìn)行參數(shù)化定制測(cè)試,或者跨函數(shù)/類/模塊或者整個(gè)測(cè)試過程進(jìn)行測(cè)試。
(3)pytest依然支持經(jīng)典的xUnit的樣式,你可以根據(jù)自己的喜好混合兩種樣式。
3、fixture參數(shù)
- scope
- params
- autouse
- ids
- name
def fixture(
fixture_function: Optional[_FixtureFunction] = None,
*,
scope: "Union[_Scope, Callable[[str, Config], _Scope]]" = "function",
params: Optional[Iterable[object]] = None,
autouse: bool = False,
ids: Optional[
Union[
Iterable[Union[None, str, float, int, bool]],
Callable[[Any], Optional[object]],
]
] = None,
name: Optional[str] = None,
) -> Union[FixtureFunctionMarker, _FixtureFunction]:
"""Decorator to mark a fixture factory function.
This decorator can be used, with or without parameters, to define a
fixture function.
The name of the fixture function can later be referenced to cause its
invocation ahead of running tests: test modules or classes can use the
``pytest.mark.usefixtures(fixturename)`` marker.
Test functions can directly use fixture names as input arguments in which
case the fixture instance returned from the fixture function will be
injected.
Fixtures can provide their values to test functions using ``return`` or
``yield`` statements. When using ``yield`` the code block after the
``yield`` statement is executed as teardown code regardless of the test
outcome, and must yield exactly once.
:param scope:
The scope for which this fixture is shared; one of ``"function"``
(default), ``"class"``, ``"module"``, ``"package"`` or ``"session"``.
This parameter may also be a callable which receives ``(fixture_name, config)``
as parameters, and must return a ``str`` with one of the values mentioned above.
See :ref:`dynamic scope` in the docs for more information.
:param params:
An optional list of parameters which will cause multiple invocations
of the fixture function and all of the tests using it. The current
parameter is available in ``request.param``.
:param autouse:
If True, the fixture func is activated for all tests that can see it.
If False (the default), an explicit reference is needed to activate
the fixture.
:param ids:
List of string ids each corresponding to the params so that they are
part of the test id. If no ids are provided they will be generated
automatically from the params.
:param name:
The name of the fixture. This defaults to the name of the decorated
function. If a fixture is used in the same module in which it is
defined, the function name of the fixture will be shadowed by the
function arg that requests the fixture; one way to resolve this is to
name the decorated function ``fixture_<fixturename>`` and then use
``@pytest.fixture(name='<fixturename>')``.
"""
fixture_marker = FixtureFunctionMarker(
scope=scope, params=params, autouse=autouse, ids=ids, name=name,
)
# Direct decoration.
if fixture_function:
return fixture_marker(fixture_function)
return fixture_marker4、實(shí)戰(zhàn)一:fixture作為參數(shù)使用
測(cè)試函數(shù)可以通過接受一個(gè)已經(jīng)命名的fixture對(duì)象來(lái)使用它們。對(duì)于每個(gè)參數(shù)名,如果fixture已經(jīng)聲明定義,會(huì)自動(dòng)創(chuàng)建一個(gè)實(shí)例并傳入該測(cè)試函數(shù)。
fixture函數(shù)通過裝飾器標(biāo)志@pytest.fixture來(lái)注冊(cè)。
下面是一個(gè)簡(jiǎn)單的獨(dú)立的測(cè)試模塊,包含一個(gè)fixture及使用它的測(cè)試函數(shù)。
使用場(chǎng)景:
- 用例1需要登錄
- 用例2不需要登錄
- 用例3需要登錄
用法
在方法前面加@pytest.fixtrue()
實(shí)戰(zhàn)
- 單個(gè)fixture
import pytest
@pytest.fixture()
def login():
print("這個(gè)是登錄方法")
def test_case1(login):
print("test_case1,需要登錄")
pass
def test_case2():
print("test_case2,不用登錄")
pass
def test_case3(login):
print("test_case3,需要登錄")
pass
if __name__ == '__main__':
pytest.main()
- 多個(gè)fixture
import pytest
//名字可以作為參數(shù)
@pytest.fixture()
def login():
print("這個(gè)是登錄方法")
return ('tom',"123")
@pytest.fixture()
def operate():
print("登錄后的操作")
def test_case1(login,operate):
print(login)
def test_case2():
print("test_case2,不用登錄")
def test_case3(login):
print(login)
if __name__ == '__main__':
pytest.main()
5、實(shí)戰(zhàn)二:fixture的作用范圍
測(cè)試函數(shù)可以通過接受一個(gè)已經(jīng)命名的fixture對(duì)象來(lái)使用他們。
對(duì)于每個(gè)參數(shù)名,如果fixture已聲明定義,會(huì)自動(dòng)創(chuàng)建一個(gè)實(shí)例并傳入該測(cè)試函數(shù)。fixture函數(shù)通過裝飾器標(biāo)志@pytest.fixture來(lái)注冊(cè)。
下面是一個(gè)簡(jiǎn)單的獨(dú)立的測(cè)試模塊,包含一個(gè)fixture及使用它的測(cè)試函數(shù)
| 名稱 | 范圍 | 說(shuō)明 |
| function | 函數(shù)級(jí) | 每一個(gè)函數(shù)或方法都會(huì)調(diào)用 |
| class | 類級(jí)別 | 每個(gè)測(cè)試類只運(yùn)行一次 |
| module | 模塊級(jí) | 每一個(gè).py文件調(diào)用一次 |
| package | 包級(jí) | 每一個(gè)python包只調(diào)用一次(暫不支持) |
| session | 會(huì)話級(jí) | 每次會(huì)話只需要運(yùn)行一次,會(huì)話內(nèi)所有方法及類,模塊都共享這個(gè)方法 |
作用范圍順序:session》module》class》function
使用場(chǎng)景
整個(gè)模塊有多條測(cè)試用例,需要在全部用例執(zhí)行之前打開瀏覽器,全部執(zhí)行之后去關(guān)閉瀏覽器,打開和關(guān)閉操作只執(zhí)行一次。
import pytest
# 作用域:module是在模塊之前執(zhí)行,模塊之后執(zhí)行
@pytest.fixture(scope="module")
def open():
print("打開瀏覽器")
yield
print("執(zhí)行teardown!")
print("最后關(guān)閉瀏覽器")
@pytest.mark.usefixtures("open")
def test_search1():
print("test_search1")
def test_search2(open):
print("test_search2")
def test_search3(open):
print("test_search3")return 與 yield的區(qū)別:
- return:在程序函數(shù)中返回某個(gè)值,返回之后函數(shù)不在繼續(xù)執(zhí)行,徹底結(jié)束。
- yield: 帶有yield的函數(shù)是一個(gè)迭代器,函數(shù)返回某個(gè)值時(shí),會(huì)停留在某個(gè)位置,返回函數(shù)值后,會(huì)在前面停留的位置繼續(xù)執(zhí)行直到程序結(jié)束
6、實(shí)戰(zhàn)三:fixture與conftest.py結(jié)合使用
在使用之前我們先來(lái)了解什么是conftest.py?
實(shí)現(xiàn)測(cè)試用例的過程中,當(dāng)你發(fā)現(xiàn)需要使用來(lái)自多個(gè)文件的fixture函數(shù)的時(shí)候,可以將這些fixture函數(shù)放到conftest.py中。
你不需要導(dǎo)入這些fixture函數(shù),它會(huì)由pytest自動(dòng)檢索。
fixture函數(shù)的檢索順序是從測(cè)試類開始,然后測(cè)試的模塊,然后就是conftest.py文件,最后是內(nèi)置的插件和第三方插件。
使用場(chǎng)景
你與其他測(cè)試工程師合作一起開發(fā)時(shí),公共的模塊要在不同文件中,要在大家都訪問到的地方(建議可以放在項(xiàng)目的根目錄,因?yàn)檎业絚onftest.py文件,先在同級(jí)目錄找,如果同級(jí)目錄找不到時(shí),會(huì)向上級(jí)目錄繼續(xù)找,指導(dǎo)找到為止)
ps:conftest.py名稱是固定,不能修改
實(shí)戰(zhàn)
conftest.py的內(nèi)容如下:
import pytest
#這個(gè)一定不要忘記寫
@pytest.fixture(scope="session")
def login():
# setup操作
print("用戶需要先完成登錄操作")
username = "hxc"
name = "pytest書籍"
# 相當(dāng)于return,但是return不會(huì)執(zhí)行后面的語(yǔ)句,yield是可以
yield username,name
# teardown操作
print("完成登出操作")test_conftestDemo.py的內(nèi)容如下:
import pytest
def test_search(login):
username,name = login
print(f"用戶名:{username},搜索商品:{name}")
def test_cart(login):
print("添加購(gòu)物車")
def test_order():
print("下單pytest書籍")
def test_login(login):
print("添加購(gòu)物車之前先登錄")
def test_get_product(connectDB):
print("獲取商品信息先連接數(shù)據(jù)庫(kù)")
@pytest.fixture()
def connectDB():
print("連接數(shù)據(jù)庫(kù)")
yield
print("斷開數(shù)據(jù)庫(kù)")
7、實(shí)戰(zhàn)四:fixture參數(shù)化
測(cè)試過程中需要大量的測(cè)試數(shù)據(jù),如果每一個(gè)測(cè)試用例都編寫一條測(cè)試用例,用例將是非常龐大的。
一般會(huì)使用將測(cè)試用例用到的數(shù)據(jù)一參數(shù)的形式傳入待測(cè)試用例中,并為每條測(cè)試數(shù)據(jù)生成一個(gè)測(cè)試結(jié)果數(shù)據(jù)。
使用場(chǎng)景
測(cè)試離不開數(shù)據(jù),為了數(shù)據(jù)靈活,一般數(shù)據(jù)都是通過參數(shù)傳的
使用方法
在fixture方法上加裝飾器@pytest.fixture(params=[1,2,3]),就會(huì)傳入三個(gè)數(shù)據(jù)1,2,3,分別將這三個(gè)數(shù)據(jù)傳入到用例當(dāng)中。傳入的數(shù)據(jù)需要使用一個(gè)固定的參數(shù)名request來(lái)接收。
import pytest
@pytest.fixture(params=["selenium", "appium"])
def login(request):
print(f"用戶名:{request.param}")
return request.param
def test_demo1(login):
print(f"demo1 case 數(shù)據(jù)為: {login}")
import pytest
@pytest.fixture(params=[["selenium",123],["appium",123456]])
def login(request):
print(f"用戶名:{request.param}")
return request.param
def test_demo1(login):
print(f"demo1 case: 數(shù)據(jù)為: {login}")
到此這篇關(guān)于Python中Pytest測(cè)試框架的fixture使用詳解的文章就介紹到這了,更多相關(guān)Pytest框架的fixture內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Pytest?Fixture參數(shù)講解及使用
- pytest內(nèi)置fixture使用臨時(shí)目錄流程詳解
- pytest使用parametrize將參數(shù)化變量傳遞到fixture
- pytest接口測(cè)試之fixture傳參數(shù)request的使用
- pytest fixtures裝飾器的使用和如何控制用例的執(zhí)行順序
- Pytest框架之fixture的詳細(xì)使用教程
- python+pytest接口自動(dòng)化之token關(guān)聯(lián)登錄的實(shí)現(xiàn)
- Pytest使用fixture實(shí)現(xiàn)token共享的方法
相關(guān)文章
Django Path轉(zhuǎn)換器自定義及正則代碼實(shí)例
這篇文章主要介紹了Django Path轉(zhuǎn)換器自定義及正則代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05
Python實(shí)現(xiàn)猜數(shù)字小游戲
這篇文章介紹了Python實(shí)現(xiàn)猜數(shù)字小游戲,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以收藏下,方便下次瀏覽觀看2021-12-12
python 獲取字典鍵值對(duì)的實(shí)現(xiàn)
這篇文章主要介紹了python 獲取字典鍵值對(duì)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
Python用20行代碼實(shí)現(xiàn)完整郵件功能
這篇文章主要介紹了如何使用Python實(shí)現(xiàn)完整郵件功能的相關(guān)資料,需要的朋友可以參考下面文章內(nèi)容,希望能幫助到您2021-09-09
從零打造一個(gè)Python圖形化exe編譯工具的踩坑實(shí)錄與完整解析
把?Python?腳本編譯成?EXE?可執(zhí)行文件,是很多?Python?開發(fā)者的剛需,本文介紹了一個(gè)將Python腳本編譯為EXE文件的圖形化工具的設(shè)計(jì)與實(shí)現(xiàn),希望對(duì)大家有所幫助2026-04-04
Python如何運(yùn)用pyaudio庫(kù)去做一個(gè)固定采樣率音頻錄制器
這篇文章主要介紹了Python如何運(yùn)用pyaudio庫(kù)去做一個(gè)固定采樣率音頻錄制器問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05

