應(yīng)用場景:
pytest?框架可以解決我們多個測試腳本一起執(zhí)行的問題。
它提供了測試用例的詳細失敗信息,使得開發(fā)者可以快速準確地改正問題。它兼容最新版本的 Python。它還兼容?unittest、doctest?和?nose,開箱即用。接下來我們詳細了解下pytest框架。
01
安裝和介紹
概念:
pytest?是?python?的一種單元測試框架,同自帶的 Unittest?測試框架類似,相比于 Unittest?框架使用起來更簡潔,效率更高
官網(wǎng):https://docs.pytest.org/en/latest/
中文文檔地址:https://www.osgeo.cn/pytest/
01
特點和書寫規(guī)則
特點:
非常容易上手,入門簡單,文檔豐富,文檔中有很多實例可以參考
支持簡單的單元測試和復(fù)雜的功能測試
支持參數(shù)化
執(zhí)行測試過程中可以將某些測試跳過,或者對某些預(yù)期失敗的 Case?標記成失敗?支持重復(fù)執(zhí)行失敗的 Case
支持運行由 Nose, Unittest 編寫的測試 Case
具有很多第三方插件,并且可以自定義擴展
方便的和持續(xù)集成工具集成
安裝:
通過pip命令安裝指定版本
pip3 install?pytest==5.4.3
pytest是python的第三方測試框架,是基于unittest的擴展框架,比unittest更簡潔,更高效。
使用 pytest編寫用例,必須遵守以下規(guī)則:
測試文件名必須以“test”開頭或者"test"結(jié)尾(如:test_ab.py)
測試方法必須以“test”開頭。test*.py或?*test.py
測試類命名以“Test”開頭。用例識別:包含所有test_*的方法(測試類不能帶有— init—方法) ?
斷言使用基本的assert即可
使用pytest?需要更改pycharm?集成設(shè)置
Pytest?可以執(zhí)行uinttest 寫的用例和方法
02
運行方式
運行方式分為兩種
命令行模式【建議】
主函數(shù)模式
命令行模式【建議】
命令行中執(zhí)行 pytest?-stest_demo01.py
主函數(shù)模式
import?pytest
class?Test:
def?test_case01(self):
print(1)
def?test_case02(self):
print(2)
#?主函數(shù)執(zhí)行
if?__name__ == '__main__':
pytest.main(['-s','test_demo01.py'])
在test_demo01.py文件中增加主函數(shù)
-s?表示支持控制臺打印,如果不加,print 不會出現(xiàn)任何內(nèi)容
運行結(jié)果
.?表示成功 ???
F?表示失敗
小結(jié):建議使用命令行的形式運行,對比主函數(shù)模式更加方便
03
setup?和?teardown
pytest?在運行自動化腳本的前后會執(zhí)行兩個特殊的方法,分別是?setup?和?teardown?在執(zhí)行腳本之前會執(zhí)行 setup方法,在執(zhí)行腳本之后會執(zhí)行 teardown?方法,我們可以在 setup?中進行獲取驅(qū)動對象的操作,在teardown?中進行關(guān)閉驅(qū)動對象的操作
應(yīng)用場景:
函數(shù)級別方法
運行于測試方法的始末,運行一次測試函數(shù)會運行一次 setup?和teardown。
示例代碼
import?pytest
class?Test:
def?setup(self):
print('test--->setup')
def?teardown(self):
print('test--->teardown')
def?test_case01(self):
print('test--->1')
def?test_case02(self):
print('test--->2')
#?主函數(shù)執(zhí)行
if?__name__ == '__main__':
pytest.main(['-s','test_demo01.py'])
執(zhí)行結(jié)果
示例代碼
import?pytest
class?Test:
def?setup_class(cls):
print('test--->setupcls')
def?teardown_class(cls):
print('test--->teardowncls')
def?test_case01(self):
print('test--->1')
def?test_case02(self):
print('test--->2')
#?主函數(shù)執(zhí)行
if?__name__ == '__main__':
pytest.main(['-s','test_demo01.py'])
執(zhí)行結(jié)果
02
Pytest-常用插件
插件列表網(wǎng)址:??https://plugincompat.herokuapp.com包含很多插件包,大家可依據(jù)工作的需求選擇?使用。
01
Pytest-html測試報告
應(yīng)用場景
自動化測試腳本最終執(zhí)行是通過還是不通過,需要通過測試報告進行體現(xiàn)
使用命令進行安裝 指定版本
pip?install?pytest-html=2.1.1
執(zhí)行命令
pytest?test_login.py?--html=report.html
查看報告
報告展示:
02
控制函數(shù)執(zhí)行順序
應(yīng)用場景:
現(xiàn)實生活中,如果想下訂單,必須先登錄,我們可以通過插件的形式來控制函數(shù)執(zhí)行的順序?安裝
使用命令 pip3 install?pytest-ordering
標記于被測試函數(shù),@pytest.mark.run(order=x)
根據(jù)order傳入的參數(shù)來解決運行順序
order值全為正數(shù)或全為負數(shù)時,運行順序:值越小,優(yōu)先級越高
正數(shù)和負數(shù)同時存在:正數(shù)優(yōu)先級高
示例代碼
import?pytest
class?Test:
def?test_case01(self):
print('test--->001')
@pytest.mark.run(order=2)
def?test_case02(self):
print('test--->002')
@pytest.mark.run(order=1)
def?test_case03(self):
print('test--->003')
執(zhí)行結(jié)果
03
失敗重試
應(yīng)用場景:
由于網(wǎng)絡(luò)的原因造成自動化腳本報錯,我們可以使用失敗重試的插件,當失敗后嘗試再次運行,一般情況最終成功可以視為成功,但最好進行進行排查時候是腳本問題
使用命令pip3install?pytest-rerunfailures?進行安裝使用
在配置文件中的命令行參數(shù)中增加 -- reruns?n
pytest??-s?test_demo2.py?--reruns?3
示例代碼
class?Test:
def?test_a(self):
assert?1,1 # 斷言成功
def?test_b(self):
print('失敗')
assert?0,1 # 斷言失敗
運行結(jié)果
R?表示重試
注意重試時,如果腳本通過,那么后續(xù)不再重試
03
pytest高級用法
01
跳過測試函數(shù)
應(yīng)用場景:
同一個軟件在不同的設(shè)備上可能會有不同的效果,比如,iOS?的 3d?touch?操作是需要 6s?以上設(shè)備支持?的,6 和 6s?都可以安裝同一款應(yīng)用,如果設(shè)備不支持,那么根本沒有必要去測試這個功能。此時,我們可以讓這種函數(shù)進行跳過
使用方式:
在需要跳過的測試腳本之上加上裝飾器 @pytest.mark.skipif(condition, reason="xxx")
condition
reason
跳過的條件,必傳參數(shù)
標注原因,必傳參數(shù)
示例代碼:
class?Test:
def?test_a(self):
assert?1,1 # 斷言成功
@pytest.mark.skipif(condition=True,reason='x')
def?test_b(self):
print('失敗')
assert?0,1 # 斷言失敗
執(zhí)行結(jié)果
02
預(yù)期失敗
應(yīng)用場景:
舉例,測試手機號碼輸入框長度為11位數(shù)字,如果我們傳入一個 12 位數(shù)字,此時可以使用預(yù)期失敗
@pytest.mark.xfail(condition=None, reason=None, raises=None, run=True,?strict=False)
condition??跳過條件,必填參數(shù)
reason???????標注原因,必填參數(shù)
使用方式:
在需要標記預(yù)期失敗的測試腳本之上加上裝飾器示例
示例代碼:
class?Test:
def?test_a(self):
print('-----testa')
assert?1,1 # 斷言成功
@pytest.mark.xfail(condition=True,reason='x')
def?test_b(self):
print('-----testb')
assert?0,1 # 斷言失敗
@pytest.mark.xfail(condition=True, reason='x')
def?test_c(self):
print('-----testc')
assert?0,?2 ?# 斷言失敗
執(zhí)行結(jié)果:
x?表示預(yù)期失敗結(jié)果失敗 不算是bug,X?表示預(yù)期失敗結(jié)果成功 算是bug
03
數(shù)據(jù)參數(shù)化
應(yīng)用場景:
登錄功能都是輸入用戶名,輸入密碼,點擊登錄。但登錄的用戶名和密碼如果想測試多個值是沒有辦法?用普通的操作 ?實現(xiàn)的。數(shù)據(jù)參數(shù)化可以幫我實現(xiàn)這樣的效果。
方法名:
@pytest.mark.parametrize(argnames, argvalues, indirect=False, ids=None,?scope=None)
argnames??參數(shù)名
argvalues???參數(shù)對應(yīng)值,類型必須為可迭代類型,一般使用list
一個參數(shù)使用方式
argnames?為字符串類型,根據(jù)需求決定何時的參數(shù)名
argvalues?為列表類型,根據(jù)需求決定列表元素中的內(nèi)容
在測試腳本中,參數(shù),名字與 argnames?保持一致
在測試腳本中正常使用
argvalues?列表有多少個內(nèi)容,這個腳本就會運行幾次
示例代碼:
class?Test:
@pytest.mark.parametrize('age',[18,19,23,21])
def?test_01(self,age):
print(age)
執(zhí)行結(jié)果:
多個參數(shù):
class?Test:
@pytest.mark.parametrize(('name','age'),[('zhangsan',18),('lisi',19)])?
def?test_01(self,name,age):
print(name,age)
執(zhí)行結(jié)果:
04
Pytest-?xture
應(yīng)用場景:
?xture??修飾器來標記固定的工廠函數(shù),在其他函數(shù),類調(diào)用它時會被激活并優(yōu)先執(zhí)行,通常會被用于完成預(yù)置處理和重復(fù)操作
使用方式:
通過函數(shù)引用
示例代碼:
class?Testlogin:
@pytest.fixture()
def?test_login(self):
print('登錄操作')
uname?= 'lily'
return?uname
def?test_a(self,test_login):
print(f'test_a?{test_login}')
def?test_b(self):
print('不需要登錄操作')
?運行結(jié)果: