前面了解了pytest中的fixture的配置内容以及conftest.py中的應用,既然fixture可以代替setup和teardown,怎麼在不同的場景下進行使用運作呢?比如我隻想要啟動浏覽器一次呢?如果每個用例按照前面的都加入fixture那麼每條用例都會運作,其實fixture中有參數可以進行配置,配置後可以在不同的場景下進行使用,這裡就要引入新的知識fixture的作用範圍。
fixture作用範圍
fixture中的scope參數可以進行配置,我們可以從源碼中看到scope的預設參數為function。下面也介紹了scope中的其他參數:“class”,“module”,“session”
def fixture( # noqa: F811
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]:
"""用于辨別夾具工廠功能的裝飾器。
該裝飾器可以使用,也可以不使用參數,來定義
夾具的功能。
fixture函數的名稱稍後可以被引用以導緻its
在運作測試之前調用:測試子產品或類可以使用
``pytest.mark.usefixtures(fixturename)`` marker.
測試函數可以直接使用fixture名稱作為其中的輸入參數
從fixture函數傳回的fixture執行個體的情況
注入。
:param scope:
The scope for which this fixture is shared; one of ``"function"``
(default), ``"class"``, ``"module"``, ``"package"`` or ``"session"``.
function
參數scope預設才是就是function,主要應用單個測試函數中,yield前面的代碼在測試用例運作前執行,後面的代碼在測試用例運作之後運作。未添加到的測試函數,不進行執行
# test_01.py
import pytest
@pytest.fixture(scope='function')
def login():
print('輸入使用者名,密碼,完成登入!')
yield
print('關閉浏覽器!')
class Test_01:
def test_01(self, login):
print('需要用到登入功能')
print('----用例01---')
def test_02(self):
print('不需要登入功能')
print('----用例02---')
def test_03(self, login):
print('需要用到登入功能')
print('----用例03---')
if __name__ == '__main__':
pytest.main(['-s', 'test__01.py'])
module
scope值為“module”表示為子產品級别的fixture每個子產品之運作1次,無論子產品中多少個測試用例,都隻運作一次。
# test_01.py
import pytest
@pytest.fixture(scope='module')
def login():
print('輸入使用者名,密碼,完成登入!')
yield
print('關閉浏覽器!')
class Test_01:
def test_01(self, login):
print('需要用到登入功能')
print('----用例01---')
def test_02(self):
print('不需要登入功能')
print('----用例02---')
def test_03(self, login):
print('需要用到登入功能')
print('----用例03---')
if __name__ == '__main__':
pytest.main(['-s', 'test__01.py'])
class
scope的值為“class”表示類機會的fixture中每個測試函數都隻執行一次。無論子產品中多少個用例,都隻執行一次。
# test_01.py
import pytest
@pytest.fixture(scope='class')
def login():
print('輸入使用者名,密碼,完成登入!')
yield
print('關閉浏覽器!')
class Test_01:
def test_01(self, login):
print('需要用到登入功能')
print('----用例01---')
def test_02(self):
print('不需要登入功能')
print('----用例02---')
def test_03(self, login):
print('需要用到登入功能')
print('----用例03---')
if __name__ == '__main__':
pytest.main(['-s', 'test__01.py'])
session
scope的值為“session”表示會話級别的fixture。每次會話都會隻執行一次。每個添加的用例隻會執行1次fixture
# test__01.py
import pytest
@pytest.fixture(scope='session')
def login():
print('輸入使用者名,密碼,完成登入!')
yield
print('關閉浏覽器!')
class Test_01:
def test_01(self, login):
print('需要用到登入功能')
print('----用例01---')
def test_02(self):
print('不需要登入功能')
print('----用例02---')
def test_03(self, login):
print('需要用到登入功能')
print('----用例03---')
if __name__ == '__main__':
pytest.main(['-s', 'test__01.py'])
執行順序
了解了fixture中scope參數的各個使用範圍,那麼如果同時使用,這些執行順序是什麼樣子的呢?實踐證明下
# test__01.py
import pytest
@pytest.fixture(scope='session')
def fix_session():
print('這是屬于fixture中的會話級别')
yield
print('session')
@pytest.fixture(scope='class')
def fix_class():
print('這是屬于fixture中的類級别')
yield
print('session')
@pytest.fixture(scope='module')
def fix_module():
print('這是屬于fixture中的子產品級别')
yield
print('module')
@pytest.fixture()
def fix_function():
print('這是屬于fixture中的函數級别')
yield
print('function')
class Test_01:
def test_01(self, fix_function, fix_class,fix_module,fix_session):
print('----用例01---')
if __name__ == '__main__':
pytest.main(['-s', 'test__01.py'])
通過上面實踐發現執行順序:session>>module>>class>>function