測試開發(fā)必知必會:Pytest框架實戰(zhàn)

應(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é)果:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容