Pytest中fixture的作用範圍(六)
- 2019 年 10 月 7 日
- 筆記
前面介紹了fixture的參數化,以及conftest.py的系列知識,本文章主要總結fixture的參數scope,通過它可以指定fixture的作用範圍。scope的參數主要應用於控制fixture執行配置和銷毀邏輯的頻率。在scope的參數中主要有四個值可以選擇,分別是function(函數級別),class(類級別).module(模組級別),session(會話級別),它的默認值是函數級別。下面依據各個案例來說明該參數的實際應用。
先來看函數級別,也就是說函數級別中,每個測試函數只需要執行一次,配置程式碼在測試用例運行前執行,銷毀程式碼是在測試用例運行之後執行。見案例程式碼:
#!/usr/bin/python3 #coding:utf-8 import pytest @pytest.fixture(scope='function') def api(): print('開始執行') yield print('結束執行') def test_login_001(api): assert 1==1該fixture僅僅是函數級別的應用,不會應用於其他的方面,見執行後的結果資訊:
platform darwin -- Python 3.7.4, pytest-4.0.2, py-1.8.0, pluggy-0.12.0 rootdir: /Applications/code/stack/study/xunit/scope, inifile: plugins: html-1.22.0, allure-adaptor-1.7.10, metadata-1.8.0 collected 1 item test_001.py SETUP F api test_001.py::test_login_001 (fixtures used: api). TEARDOWN F api
下來看類級別的,類級別的主要指的是每個測試類需要運行一次,無論測試類裡面有多少個測試方法,都會被執行到並且共享fixture,見案例程式碼:
#!/usr/bin/python3 #coding:utf-8 import pytest @pytest.fixture(scope='class') def api(): print('開始執行') yield print('結束執行') class TestLogin(object): def test_login_001(self,api): assert 1==1 def test_login_002(self): assert 1==1見執行後的結果資訊:
platform darwin -- Python 3.7.4, pytest-4.0.2, py-1.8.0, pluggy-0.12.0 rootdir: /Applications/code/stack/study/xunit/scope, inifile: plugins: html-1.22.0, allure-adaptor-1.7.10, metadata-1.8.0 collected 2 items test_001.py SETUP C api test_001.py::TestLogin::test_login_001 (fixtures used: api). test_001.py::TestLogin::test_login_002 (fixtures used: api). TEARDOWN C api
來來看模組級別的,在模組級別的fixture每個模組只需要執行一次,無論模組裡面有多少個測試函數,類方法,都可以共享這個fixture,見案例程式碼:
import pytest @pytest.fixture(scope='module') def api(): print('開始執行') yield print('結束執行') def test_login_001(api): assert 1==1 class TestApi(object): def test_api_001(self,api): assert 1==1見執行後的輸出資訊:
platform darwin -- Python 3.7.4, pytest-4.0.2, py-1.8.0, pluggy-0.12.0 rootdir: /Applications/code/stack/study/xunit/scope, inifile: plugins: html-1.22.0, allure-adaptor-1.7.10, metadata-1.8.0 collected 2 items test_001.py SETUP M api test_001.py::test_login_001 (fixtures used: api). test_001.py::TestApi::test_api_001 (fixtures used: api). TEARDOWN M api
是否存在這樣的一個疑問,函數級別的是否可以應用在類級別,類級別的是否可以應用於函數級別了,見測試程式碼:
import pytest @pytest.fixture(scope='function') def api(): print('開始執行') yield print('結束執行') def test_login_001(api): assert 1==1 class TestApi(object): def test_api_001(self,api): assert 1==1見輸出的資訊:
platform darwin -- Python 3.7.4, pytest-4.0.2, py-1.8.0, pluggy-0.12.0 rootdir: /Applications/code/stack/study/xunit/scope, inifile: plugins: html-1.22.0, allure-adaptor-1.7.10, metadata-1.8.0 collected 2 items test_001.py SETUP F api test_001.py::test_login_001 (fixtures used: api). TEARDOWN F api SETUP F api test_001.py::TestApi::test_api_001 (fixtures used: api). TEARDOWN F api
最後一個是會話級別的,會話級別的fixture每次會話只需要運行一次,一次pytest會話中的所有測試函數,方法都可以共享該fixture,見案例程式碼:
#!/usr/bin/python3 #coding:utf-8 import pytest @pytest.fixture(autouse=True,scope='session') def wuya(): print('start') yield print('end')見測試的程式碼:
#!/usr/bin/python3 #coding:utf-8 import pytest def test_login_001(): assert 1==1 class TestApi(object): def test_api_001(self): assert 1==1
見執行後輸出的結果資訊:
platform darwin -- Python 3.7.4, pytest-4.0.2, py-1.8.0, pluggy-0.12.0 rootdir: /Applications/code/stack/study/xunit/scope, inifile: plugins: html-1.22.0, allure-adaptor-1.7.10, metadata-1.8.0 collected 2 items test_001.py SETUP S wuya test_001.py::test_login_001 (fixtures used: wuya). test_001.py::TestApi::test_api_001 (fixtures used: wuya). TEARDOWN S wuya
在pytest中也可以使用userfixture指定多個fixture,這樣來標記測試函數或者測試的類,使用usefixture,需要在一個參數中指定一個或者多個fixture字元串,這樣的一個場景在特定的場景下還是可以的,見案例的測試程式碼:
#!/usr/bin/python3 #coding:utf-8 import pytest @pytest.fixture() def api(): return 1 @pytest.fixture() def init(): print('start') yield print('end') @pytest.mark.usefixtures('api','init') def test_login_001(api): assert api==1見執行後輸出的資訊:
platform darwin -- Python 3.7.4, pytest-4.0.2, py-1.8.0, pluggy-0.12.0 rootdir: /Applications/code/stack/study/xunit/scope, inifile: plugins: html-1.22.0, allure-adaptor-1.7.10, metadata-1.8.0 collected 1 item test_001.py SETUP F api SETUP F init test_001.py::test_login_001 (fixtures used: api, init). TEARDOWN F init TEARDOWN F api
在如上的結果資訊中,就可以看到,測試函數共享了兩個fixture。
在前面使用fixture的時候說到了autouse的選項,也應該看到,如果不使用該選項,每次共享fixture都需要指定,但是使用了它後就不需要指定了,那麼標準的說法應該是:依據選項autouse=True,使作用域內的測試函數都執行該fixture,這與那些需要多次執行,但不依賴任何的狀態或者外部數據的程式碼配合的比較好。針對如上的程式碼修改,見修改後的源碼:
#!/usr/bin/python3 #coding:utf-8 import pytest @pytest.fixture(autouse=True) def api(): return 1 @pytest.fixture(autouse=True) def init(): print('start') yield print('end') def test_login_001(api): assert api==1見執行後輸出的結果資訊:
platform darwin -- Python 3.7.4, pytest-4.0.2, py-1.8.0, pluggy-0.12.0 rootdir: /Applications/code/stack/study/xunit/scope, inifile: plugins: html-1.22.0, allure-adaptor-1.7.10, metadata-1.8.0 collected 1 item test_001.py SETUP F api SETUP F init test_001.py::test_login_001 (fixtures used: api, init). TEARDOWN F init TEARDOWN F api