Pytest之skip、skipif、xfail

17
2020-08
今天距2021年137天
這是ITester軟件測試小棧第150次推文

點擊上方藍字“ITester軟件測試小棧“關注我,每周一、三、五早上?07:30準時推送。
微信公眾號后臺回復“資源”、“測試工具包”領取測試資源,回復“微信群”一起進群打怪。
本文5539字,閱讀約需14分鐘
skip、skipif、xfail的用法。mark基本介紹
標記名來過濾測試用例。在自動化過程中,我們可以能遇到問題,比如測試用例比較多,且不在一個層級,想將某些用例作為冒煙測試用例,要怎么處理。pytest提供了mark功能,可以解決此問題。
mark可分為2類:
一類是
系統(tǒng)內置的mark,不同的mark標記提供不同的功能。二類是
自定義的mark,該類mark主要用于給測試用例分門別類,使得運行測試時可以指定運行符合哪一類標記的測試用例。
查看內置的mark,輸入命令:pytest --markers。
@pytest.mark.allure_label:?allure?label?marker
@pytest.mark.allure_link:?allure?link?marker
@pytest.mark.allure_display_name:?allure?test?name?marker
@pytest.mark.allure_description:?allure?description
@pytest.mark.allure_description_html:?allure?description?html
@pytest.mark.filterwarnings(warning):?add?a?warning?filter?to?the?given?test.?see?https://docs.pytest.org/en/latest/warnings.html#pytest-mark-filterwarnings
@pytest.mark.skip(reason=None):?skip?the?given?test?function?with?an?optional?reason.?Example:?skip(reason="no?way?of?currently?testing?this")?skips?the?test.
@pytest.mark.skipif(condition):?skip?the?given?test?function?if?eval(condition)?results?in?a?True?value.??Evaluation?happens?within?the?module?global?context.?Example:?skipif('sys.platform?==?"win32"')?skips?the?test?if?we?are?on?the?win32?platform.?see?https://docs.pytest.org/en/latest/skipping.html
@pytest.mark.xfail(condition,?reason=None,?run=True,?raises=None,?strict=False):?mark?the?test?function?as?an?expected?failure?if?eval(condition)?has?a?True?value.?Optionally?specify?a?reason?for?better?reporting?and?run=False?if?you?don't?even?want?to?execute?the?test?function.?If?only?specific?exception(s)?are?expected,?you?can?list?them?in?raises,?and?if?the?test?fails?in?other?ways,?it?will?be?reported?as?a?true?failure.?See?https://docs.pytest.org/en/latest/skipping.html
@pytest.mark.parametrize(argnames,?argvalues):?call?a?test?function?multiple?times?passing?in?different?arguments?in?turn.?argvalues?generally?needs?to?be?a?list?of?values?if?argnames?specifies?only?one?name?or?a?list?of?tuples?of?values?if?argnames?specifies?multiple?names.?Example:?@parametrize('arg1',?[1,2])?would?lead?to?two?calls?of?the?decorated?test?function,?one?with?arg1=1?and?another?with?arg1=2.see?https://docs.pytest.org/en/latest/parametrize.html?for?more?info?and?examples.
@pytest.mark.usefixtures(fixturename1,?fixturename2,?...):?mark?tests?as?needing?all?of?the?specified?fixtures.?see?https://docs.pytest.org/en/latest/fixture.html#usefixtures
@pytest.mark.tryfirst:?mark?a?hook?implementation?function?such?that?the?plugin?machinery?will?try?to?call?it?first/as?early?as?possible.
@pytest.mark.trylast:?mark?a?hook?implementation?function?such?that?the?plugin?machinery?will?try?to?call?it?last/as?late?as?possible.
以下主要介紹skip、skipif、xfail這三種的用法。
skip
語法:@pytest.mark.skip(reason=None)
說明:跳過執(zhí)行測試用例,可選參數(shù)reason,跳過的原因,會在執(zhí)行結果中打印。
用法:在類、方法或函數(shù)上添加@pytest.mark.skip。
作用于類上,則類下面的所有方法都跳過測試。
現(xiàn)有如下類:
test_demo.py
class?TestDemo():
????def?test_demo01(self):
????????print("這是test_demo01")
????def?test_demo02(self):
????????print("這是test_demo02")
目前因為TestDemo類功能并未完成,想跳過用例執(zhí)行,在類上方添加@pytest.mark.skip即可。
import?pytest
@pytest.mark.skip(reason="功能未實現(xiàn),暫不執(zhí)行")
class?TestDemo():
????def?test_demo01(self):
????????print("這是test_demo01")
????def?test_demo02(self):
????????print("這是test_demo02")運行結果如下:

作用于方法上,則此方法跳過測試。
現(xiàn)在有如下類:
test_demo.py
class?TestDemo():
????def?test_demo01(self):
????????print("這是test_demo01")
????def?test_demo02(self):
????????print("這是test_demo02")
目前因為test_demo02方法功能并未完成,想跳過用例執(zhí)行,在test_demo02方法上添加@pytest.mark.skip即可。
import?pytest
class?TestDemo():
????def?test_demo01(self):
????????print("這是test_demo01")
[email protected](reason="功能未實現(xiàn),暫不執(zhí)行")
????def?test_demo02(self):
????????print("這是test_demo02")
運行結果如下:

現(xiàn)有如下函數(shù):
test_demo.py
def?test_demo01():
????print("這是test_demo01")
def?test_demo02():
????print("這是test_demo02")
目前因為test_demo02函數(shù)功能并未完成,想跳過用例執(zhí)行,在函數(shù)上方添加@pytest.mark.skip即可。
import?pytest
def?test_demo01():
????print("這是test_demo01")
@pytest.mark.skip(reason="功能未實現(xiàn),暫不執(zhí)行")
def?test_demo02():
????print("這是test_demo02")
執(zhí)行結果如下:

補充:除了通過使用標簽的方式,還可以在測試用例中調用pytest.skip()方法來實現(xiàn)跳過,傳入msg參數(shù)來說明跳過原因。
def?test_demo01():
????n?=?1
????while?True:
????????print("當前的的值為{}".format(n))
????????n?+=?1
????????if?n?==?4:
????????????pytest.skip("跳過的值為{}".format(n))
skipif
語法:@pytest.mark.skipif(self,condition, reason=None)。
說明:跳過執(zhí)行測試用例,condition參數(shù)為條件,可選參數(shù)reason,跳過的原因,會在執(zhí)行結果中打印。
從之前的運行結果可以看出一些軟件版本信息。

比如當前的python版本為3.6,要求python版本必須大于3.7,否則跳過測試。
import?pytest
import?sys
def?test_demo01():
????print("這是test_demo01")
@pytest.mark.skipif(sys.version?'3.7',?reason="python版本必須大于3.7")
def?test_demo02():
????print("這是test_demo02")運行結果如下:

xfail
應用場景:用例功能不完善或者用例執(zhí)行失敗,可以標記為xfail。
語法:@pytest.mark.xfail(self,condition=None, reason=None, raises=None, run=True, strict=False)。
說明:期望測試用例是失敗的,但是不會影響測試用例的的執(zhí)行。如果測試用例執(zhí)行失敗的則結果是xfail(不會額外顯示出錯誤信息);如果測試用例執(zhí)行成功的則結果是xpass。
來個小例子實戰(zhàn)下,用例斷言失敗,且標記為xfail。
test_demo.py
import?pytest
def?test_demo01():
????print("這是test_demo01")
@pytest.mark.xfail()
def?test_demo02():
????print("這是test_demo02")
????assert?1?==?2
運行結果為:

接下將用例斷言成功,標記為xfail。
import?pytest
def?test_demo01():
????print("這是test_demo01")
@pytest.mark.xfail()
def?test_demo02():
????print("這是test_demo02")
????assert?1?==?1運行結果為:

補充:
pytest中,pytest.xfail()方法也可以將用例標記為失敗。
語法:pytest.xfail(reason: str = "")。
舉個小例子,比如斷言時,斷言失敗,我們就標記為xfail。
import?pytest
class?TestDemo():
????def?test_001(self):
????????#?斷言是否相等
????????except_result?=?'hello'
????????real_result?=?'hello?world'
????????if?except_result?==?real_result:
????????????print('斷言成功')
????????else:
????????????pytest.xfail('斷言失敗,標記為xfail')
????def?test_002(self):
????????#?斷言包含或不包含
????????assert?'hello'?in?'hello?world'
????????print('這是test_002')
運行結果為:



測試交流Q群:727998947

