Python pytest框架之@pytest.fixture()和conftest详解
一、fixture簡介
學pytest就不得不說fixture,fixture是pytest的精髓所在,類似unittest中setup/teardown這種前后置東西。但是比它們要強大、靈活很多,它的優勢是可以跨文件共享
fixture的目的是提供一個固定基線,在該基線上測試可以可靠地和重復地執行。fixture提供了區別于傳統單元測試(setup/teardown)有顯著改進
1、有獨立的命名,并通過聲明它們從測試函數、模塊、類或整個項目中的使用來激活。
2、按模塊化的方式實現,每個fixture都可以互相調用。
3、fixture的范圍從簡單的單元擴展到復雜的功能測試,允許根據配置和組件選項對fixture和測試用例進行參數化,或者跨函數function、類class、模塊module或整個測試會話sessio范圍。
二、用途:
1.做測試前后的初始化設置,如測試數據準備,鏈接數據庫,打開瀏覽器等這些操作都可以使用fixture來實現
2.測試用例的前置條件可以使用fixture實現
3.支持經典的xunit fixture ,像unittest使用的setup和teardown
4.fixture可以實現unittest不能實現的功能,比如unittest中的測試用例和測試用例之間是無法傳遞參數和數據的,但是fixture卻可以解決這個問題
三、fixture作為參數傳入:
1、定義fixture跟定義普通函數差不多,唯一區別就是在函數上加個裝飾器@pytest.fixture(),fixture命名不要用test_開頭,跟用例區分開。用例才是test_開頭的命名。
2、fixture是可以有返回值的,如果沒return默認返回None。用例調用fixture的返回值,直接就是把fixture的函數名稱當成變量傳入
3、fixture裝飾器里的scope有四個級別的參數。“function(不寫默認這個)”,“class”,“module”or“session”
4、除scope之外。還有params、autouse、ids、name等。
5、fixture可以有返回值,如果沒有return,默認會是None;用例調用fixture的返回值,就是直接把fixture的函數名稱作為參數傳入
6、fixture可以返回一個元組、列表或字典
7、test_用例可傳單個、多個fixture參數
8、fixture與fixture間可相互調用
fixture可以返回一個元組、列表或字典@pytest.fixture() def user():print("=====打印裝飾器函數=====")username='wangli'psw=123456assert username=="wangli"assert psw == 123456return username,psw def test_login(user):print(user)assert user[0]=="wangli"assert user[1] == 123456if __name__=="__main__":pytest.main(["-s","test03.py"])"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/test/test/test03.py ============================= test session starts ============================= platform win32 -- Python 3.5.2, pytest-5.1.2, py-1.8.0, pluggy-0.12.0 rootdir: C:\Users\wangli\PycharmProjects\test\test collected 1 itemtest03.py =====打印裝飾器函數===== ('wangli', 123456) .============================== 1 passed in 0.16s ==============================Process finished with exit code 0 test_用例可傳單個、多個fixture參數@pytest.fixture() def username():print("=====打印username裝飾器函數=====")username='wangli'assert username=="wangli"return username @pytest.fixture() def psw():print("=====打印psw裝飾器函數=====")psw=123456assert psw==123456return psw def test_login(username,psw):print(username,psw)assert username=="wangli"assert psw == 123456if __name__=="__main__":pytest.main(["-s","test03.py"])"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/test/test/test03.py ============================= test session starts ============================= platform win32 -- Python 3.5.2, pytest-5.1.2, py-1.8.0, pluggy-0.12.0 rootdir: C:\Users\wangli\PycharmProjects\test\test collected 1 itemtest03.py =====打印username裝飾器函數===== =====打印psw裝飾器函數===== wangli 123456 .============================== 1 passed in 0.13s ==============================Process finished with exit code 0 fixture與fixture間可相互調用@pytest.fixture() def first():print("=====first=====")username='wangli'assert username=="wangli"return username @pytest.fixture() def sencond(first):print("=====sencond=====")psw=123456assert psw==123456return first,psw def test_login(sencond):print(sencond)assert sencond[0]=="wangli"assert sencond[1] == 123456if __name__=="__main__":pytest.main(["-s","test03.py"])"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/test/test/test03.py ============================= test session starts ============================= platform win32 -- Python 3.5.2, pytest-5.1.2, py-1.8.0, pluggy-0.12.0 rootdir: C:\Users\wangli\PycharmProjects\test\test collected 1 itemtest03.py =====first===== =====sencond===== ('wangli', 123456) .============================== 1 passed in 0.02s ==============================Process finished with exit code 0四、fixture源碼詳解:
fixture(scope='function',params=None,autouse=False,ids=None,name=None):
fixture里面有個scope參數可以控制fixture的作用范圍,scope:有四個級別參數"function"(默認),"class","module","session
params:一個可選的參數列表,它將導致多個參數調用fixture功能和所有測試使用它。
autouse:如果True,則為所有測試激活fixture func可以看到它。如果為False則顯示需要參考來激活fixture
ids:每個字符串id的列表,每個字符串對應于params這樣他們就是測試ID的一部分。如果沒有提供ID它們將從params自動生成
name:fixture的名稱。這默認為裝飾函數的名稱。如果fixture在定義它的統一模塊中使用,夾具的功能名稱將被請求夾具的功能arg遮蔽,解決這個問題的一種方法時將裝飾函數命令"fixture_<fixturename>"然后使用"@pytest.fixture(name='<fixturename>')"。
五、fixture的作用范圍
fixture里面有個scope參數可以控制fixture的作用范圍:session>module>class>function
-function:每一個函數或方法都會調用
-class:每一個類調用一次,一個類中可以有多個方法
-module:每一個.py文件調用一次,該文件內又有多個function和class
-session:是多個文件調用一次,可以跨.py文件調用,每個.py文件就是module
function默認模式@pytest.fixture(scope='function')或?@pytest.fixture()
函數級別的,每一個函數或方法都會調用,每個測試用例執行前都會執行一次function級別的fixture
@pytest.fixture()如果不寫參數,參數就是scope="function",它的作用范圍是每個測試用例來之前運行一次,銷毀代碼在測試用例之后運行。
class類級別@pytest.fixture(scope='class')
如果一個class里面有多個用例,都調用了1次fixture,那么此fixture只在此class里所有用例開始前執行一次。
?
module模塊級別@pytest.fixture(scope='module')
每一個.py文件調用一次,fixture為module時,在當前.py腳本里面所有用例開始前只執行一次,模塊里所有的用例執行前執行一次module級別的fixture
@pytest.fixture(scope='module') def test1():b = '男'print('傳出了%s, 且在當前py文件下執行一次!!!' % b)return bdef test3(test1):name = '男'print('找到name')assert test1 == nameclass TestCase:def test4(self, test1):sex = '男'print('找到sex')assert test1 == sex if __name__=="__main__":pytest.main(["-s","test03.py"])"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/test/test/test03.py ============================= test session starts ============================= platform win32 -- Python 3.5.2, pytest-5.1.2, py-1.8.0, pluggy-0.12.0 rootdir: C:\Users\wangli\PycharmProjects\test\test collected 2 itemstest03.py 傳出了男, 且在當前py文件下執行一次!!! 找到name .找到sex .============================== 2 passed in 0.09s ==============================Process finished with exit code 0?
session 會話級別@pytest.fixture(scope='session')
1、可以跨.py文件調用,有多個.py文件調用時,實際只調用了一次fixture
2、conftest.py與運行的用例要在同一個pakage下,并且有__init__.py文件
3、不需要import導入 conftest.py,pytest會自動識別該文件,放到項目的根目錄下就可以全局調用了,如果放到某個package下,那就在改package內有效
4、conftest.py配置腳本名稱是固定的,不能改名稱
多個.py文件只調用1次fixtureimport pytest # conftest.py @pytest.fixture(scope='session') def get_token():token = 'qeehfjejwjwjej11sss@22'print('獲取到token:%s' % token)return tokenimport pytest # test02.py class Test(object):def test2(self,get_token):token = 'qeehfjejwjwjej11sss@22'print("【執行test02.py-Test類-test2用例,獲取get_token:%s】" %get_token)assert get_token == tokenif __name__=="__main__":pytest.main(["-s","test02.py","test03.py"])import pytest #test03.py class Test(object):def test3(self,get_token):token = 'qeehfjejwjwjej11sss@22'print("【執行test03.py-Test類-test3用例,獲取get_token:%s】" %get_token)assert get_token == tokendef test4(self,get_token):token = 'qeehfjejwjwjej11sss@22'print("【執行test03.py-Test類-test4用例,獲取get_token:%s】" %get_token)assert get_token == tokenif __name__=="__main__":pytest.main(["-s","test02.py","test03.py"])"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/test/test02.py ============================= test session starts ============================= platform win32 -- Python 3.5.2, pytest-5.1.2, py-1.8.0, pluggy-0.12.0 rootdir: C:\Users\wangli\PycharmProjects\Test\test collected 3 itemstest02.py 獲取到token:qeehfjejwjwjej11sss@22 【執行test02.py-Test類-test2用例,獲取get_token:qeehfjejwjwjej11sss@22】 . test03.py 【執行test03.py-Test類-test3用例,獲取get_token:qeehfjejwjwjej11sss@22】 .【執行test03.py-Test類-test4用例,獲取get_token:qeehfjejwjwjej11sss@22】 .============================== 3 passed in 0.30s ==============================Process finished with exit code 0多個.py文件只調用多次fixtureimport pytest # conftest.py @pytest.fixture() def get_token():token = 'qeehfjejwjwjej11sss@22'print('獲取到token:%s' % token)return tokenimport pytest # test02.py class Test(object):def test2(self,get_token):token = 'qeehfjejwjwjej11sss@22'print("【執行test02.py-Test類-test2用例,獲取get_token:%s】" %get_token)assert get_token == tokenif __name__=="__main__":pytest.main(["-s","test02.py","test03.py"])import pytest #test03.py class Test(object):def test3(self,get_token):token = 'qeehfjejwjwjej11sss@22'print("【執行test03.py-Test類-test3用例,獲取get_token:%s】" %get_token)assert get_token == tokendef test4(self,get_token):token = 'qeehfjejwjwjej11sss@22'print("【執行test03.py-Test類-test4用例,獲取get_token:%s】" %get_token)assert get_token == tokenif __name__=="__main__":pytest.main(["-s","test02.py","test03.py"])"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/test/test03.py ============================= test session starts ============================= platform win32 -- Python 3.5.2, pytest-5.1.2, py-1.8.0, pluggy-0.12.0 rootdir: C:\Users\wangli\PycharmProjects\Test\test collected 3 itemstest02.py 獲取到token:qeehfjejwjwjej11sss@22 【執行test02.py-Test類-test2用例,獲取get_token:qeehfjejwjwjej11sss@22】 . test03.py 獲取到token:qeehfjejwjwjej11sss@22 【執行test03.py-Test類-test3用例,獲取get_token:qeehfjejwjwjej11sss@22】 .獲取到token:qeehfjejwjwjej11sss@22 【執行test03.py-Test類-test4用例,獲取get_token:qeehfjejwjwjej11sss@22】 .============================== 3 passed in 0.04s ==============================Process finished with exit code 0?
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Python pytest框架之@pytest.fixture()和conftest详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php nginx日志分析,如何通过NG
- 下一篇: 【Python】base64模块对图片进