1.pytest中的xunit風格前后置處理
pytest中用例的前后置可以直接使用類似于unittest中的前后置處理,但是pytest中的前后置處理方式更
加豐富,分為模塊級、類級、方法級、函數級等不同等級的前后置處理,具體見下面的代碼:
test_demo_001.py文件
def setup_function():#類外使用
print('函數級的前置,每個函數級用例前均運行一次')
def teardown_function():#類外使用
print('函數級的前置,每個函數級用例后均運行一次')
def test_function_001():
print('測試:函數級的用例test_function_001')
def test_function_002():
print('測試:函數級的用例test_function_002')
def setup_module():
print('模塊級的前置,每個文件中所有用例執行前僅運行一次')
def teardown_module():
print('模塊級的后置,每個文件中所有用例執行后僅運行一次')
class TestDemo001:
@classmethod
def setup_class(cls):
print('類級的前置,TestDemo001類下的所有用例執行前運行一次')
@classmethod
def teardown_class(cls):
print('類級的后置,TestDemo001類下的所有用例執行后運行一次')
def setup_method(self): #類中使用
print('方法級的前置,每個方法級用例前均運行一次')
def teardown_method(self): #類中使用
print('方法級的后置,每個方法級用例后均運行一次')
def test_aaa_001(self):
print('測試:類下方法級的用例test_aaa_001')
def test_aaa_002(self):
print('測試:類下方法級的用例test_aaa_002')
class TestDemo002:
@classmethod
def setup_class(cls):
print('類級的前置,TestDemo002類下的所有用例執行前運行一次')
@classmethod
def teardown_class(cls):
print('類級的后置,TestDemo002類下的所有用例執行后運行一次')
def setup_method(self): #等價于def setup(self):
print('方法級的前置,每個方法級用例前均運行一次')
def teardown_method(self): #等價于def teardown(self):
print('方法級的后置,每個方法級用例后均運行一次')
def test_bbb_001(self):
print('測試:類下方法級的用例test_bbb_001')
def test_bbb_002(self):
print('測試:類下方法級的用例test_bbb_002')
'''
setup/teardown 等價于 setup_method/teardown_method;2者僅使用一種即可,如果同時時候,只使
用setup_method/teardown_method
整體運行過程:
setup_module
setup_function--->test_function_001--->teardown_function
setup_function--->test_function_002--->teardown_function
setup_class #TestDemo001的
setup_method--->test_aaa_001--->teardown_method
setup_method--->test_aaa_002--->teardown_method
teardown_class #TestDemo001的
setup_class #TestDemo002的
setup_method--->test_bbb_001--->teardown_method
setup_method--->test_bbb_002--->teardown_method
teardown_class #TestDemo002的
teardown_module
'''
2.使用fixture實現靈活的用例前后置處理
使用Xunit風格的前置后置的使用,我們發現這種前后置無法復用,在另外的一個.py文件或者.py文件中 的類使用時,需要重新再寫,相對不靈活。pytest結合fixture可以實現用例進行靈活的前后置處理。
2.1.@pytest.fixture進行用例的前置處理
import pytest
@pytest.fixture()
def aaa():
print('這是用例的前置操作')
def test_001(aaa):
print('用例test_001')
@pytest.fixture #fixture中不傳參數,可以不帶括號
def bbb():
print('用例前置操作,并給返回值')
return 100
def test_002(bbb):
print('用例test_002')
print('可以使用前置函數的名稱來作為其返回值使用:bbb={}'.format(bbb))
def test_003(bbb,aaa):
print('用例test_003')
print('可以同時做多個前置操作,操作順序按傳遞的參數順序來進行')
print('我們可以發現前置函數aaa,bbb一次定義,可以多次使用,體現了靈活性')
print(bbb,aaa)
if __name__ == '__main__':
pytest.main()
2.2.@pytest.fixture的嵌套使用
#fixture的嵌套,會先調用里層的fixture,在調用外層的fixture
@pytest.fixture()
def aaa():
print('111111111111')
return 'aaa'
@pytest.fixture()
def bbb(aaa):
print('22222222')
return ['bbb',aaa]
def test_001(bbb):
print('測試用例test_001')
print(bbb)
if __name__ == '__main__':
pytest.main()
2.3.@pytest.fixture結合@pytest.mark.parametrize()實現參數 化
import yaml,pytest
#讀取參數化數據的文件內容
def get_yaml_data(yaml_path):
with open(yaml_path,'r',encoding='utf-8') as f:
data = yaml.safe_load(f)
return data
#獲取yaml文件的數據
yaml_data = get_yaml_data('./login.yaml')
@pytest.fixture()
def case_data(request):
return request.param
#indirect=True時'case_data'當做函數運行,就是這里定義的fixture
#indirect=False時'case_data'當做普通變量使用,默認值為False
#工作中建議使用默認值:False,就當做普通變量使用即可,這時可以不使用fixture進行參數化
@pytest.mark.parametrize('case_data',yaml_data,indirect=True)
def test_002(case_data):
print(case_data)
if __name__ == '__main__':
pytest.mian(['-vs','demo1.py'])
2.4.直接使用@pytest.fixture()來進行參數化
#演示代碼時,需要先在當前目下新建login.yaml文件
#不使用@pytest.mark.parametrize()來參數化,直接利用@pytest.fixture()的傳參功能進行參數化
import yaml,pytest
#封裝讀取參數化數據的文件內容
def get_yaml_data(yaml_path):
with open(yaml_path,'r',encoding='utf-8') as f:
data = yaml.safe_load(f)
return data
#通過在fixture中使用parmas接受參數化的值,將值傳遞給固定的接受參數requests
#如果傳入的是列表,會將列表中的每個元素返回,如果傳入的是字典會將字的每個key返回
@pytest.fixture(params=get_yaml_data('./login.yaml')[0])
def case_data(request):
return request.param
#測試用例test_003使用fixture:case_data,case_data的值就是fixture函數中的返回值
def test_003(case_data):
print(case_data)
2.5.結合yield來進行前后置處理
import pytest,allure
from selenium import webdriver
@pytest.fixture()
def brower():
driver = webdriver.Chrome()
yield driver
driver.quit()
?
?