【pytest】skip、skipif 跳過測試用例,xfail 處理預計會失敗的測試用例

如何跳過測試用例:

skip 直接跳過測試用例:

使用方法:@pytest.mark.skip(reason='這個是跳過的原因!') 裝飾要跳過的測試方法或測試類上;

  1. 裝飾在測試方法只跳過該方法對應的測試用例;
  2. 裝飾在使用了 parametrize 參數化的測試方法上,跳過生成的所有測試用例;
  3. 裝飾在測試類上,跳過測試類中所有的測試用例;
  4. reason 參數是跳過用例的原因,可以不寫;
# test_moduleName.py

import pytest

class TestClass001:

    def test_func_001(self):
        pass

    @pytest.mark.skip(reason="這個是跳過的原因!")  # 裝飾在單個的測試方法上,只跳過1個測試用例
    def test_func_002(self):
        pass

    @pytest.mark.skip  # 裝飾在使用了 parametrize 參數化的測試方法上,跳過生成的所有測試用例
    @pytest.mark.parametrize('data', [1, 2, 3])
    def test_func_003(self, data):
        pass


@pytest.mark.skip  # 裝飾在測試類上,跳過測試類中所有的測試用例
class TestClass002:

    def test_func_004(self):
        pass

    def test_func_005(self):
        pass
# 執行結果
============================= test session starts =============================
collected 7 items

test_moduleName.py::TestClass001::test_func_001 PASSED
test_moduleName.py::TestClass001::test_func_002 SKIPPED
test_moduleName.py::TestClass001::test_func_003[1] SKIPPED
test_moduleName.py::TestClass001::test_func_003[2] SKIPPED
test_moduleName.py::TestClass001::test_func_003[3] SKIPPED
test_moduleName.py::TestClass002::test_func_004 SKIPPED
test_moduleName.py::TestClass002::test_func_005 SKIPPED

======================== 1 passed, 6 skipped in 0.22s =========================

Process finished with exit code 0

skipif 滿足某些條件時跳過測試用例:

使用方法:@pytest.mark.skipif(condition, reason='跳過的原因!') 裝飾在要跳過的測試方法或測試類上;

  1. condition 參數:condition 是條件表達式,如果 condition 爲 Ture,則跳過測試用例,否則便不跳過;
  2. condition 參數默認爲 True,和 reason 參數一樣可以省略不寫;
  3. condition 條件表達式必須是字符串(條件表達式外面加上引號便可,pytest 會自動解析);
# test_moduleName.py

import pytest

# 校驗條件
device_sys = 'Android'
android_sys = 6.0


class TestClass001:

    def test_func_001(self):
        pass

    # 條件表達式不成立,此用例不會被跳過
    @pytest.mark.skipif(condition='android_sys < 6.0', reason='系統版本過低,此用例跳過!')
    def test_func_002(self):
        pass
    
    # condition 參數默認爲 True,和 reason 參數一樣可以省略不寫;
    @pytest.mark.skipif  
    def test_func_003(self, data):
        pass


# 條件表達式成立,此測試類中所有用例被跳過
@pytest.mark.skipif('device_sys != "iOS"', reason='iOS設備專用case,Android設備需跳過!')
class TestClass002:

    def test_func_004(self):
        pass

    def test_func_005(self):
        pass
# 執行結果
============================= test session starts =============================
collected 5 items

test_moduleName.py::TestClass001::test_func_001 PASSED
test_moduleName.py::TestClass001::test_func_002 PASSED
test_moduleName.py::TestClass001::test_func_003 SKIPPED
test_moduleName.py::TestClass002::test_func_004 SKIPPED
test_moduleName.py::TestClass002::test_func_005 SKIPPED

======================== 2 passed, 3 skipped in 0.05s =========================

使用 pytest.skip() 在用例內部跳過決定是否跳過測試用例:

當用例是否跳過的判斷條件在導入時無法判斷時,可以在用例內部執行時再進行跳過:pytest.skip(reason='跳過的原因!')

注意:pytest.skip(reason='跳過的原因!') 中間沒有 mark;

# test_moduleName.py

android_sys = 5.0

class TestClass001:

    def test_func_001(self):
        pass

    def test_func_002(self):
        if android_sys < 6:
            pytest.skip('系統版本過低,此用例不適用!')
# 執行結果
============================= test session starts =============================
collected 2 items

test_moduleName.py::TestClass001::test_func_001 PASSED
test_moduleName.py::TestClass001::test_func_002 SKIPPED

======================== 1 passed, 1 skipped in 0.14s =========================

使用 pytest.skip() 跳過整個模塊:

import pytest
import sys

if sys.platform.startswith("win"):  # 如果平臺不是windows
    # 跳過整個模塊
    pytest.skip(msg='MacOS 專用case, Windows 系統需跳過!', allow_module_level=True)  

全局共享 skip 標記:

  1. 在公共模塊創建 skip 標記;
  2. 在測試模塊導入 skip 標記;
  3. 裝飾在測試類或測試方法上;
# conftest.py

import pytest

# 校驗條件
version = 5
# 1. 創建 skip 標記
isSkip = pytest.mark.skipif(version < 6, reason="版本過低,此用例不適用!")
# test_moduleName.py

2. 導入 skip 標記
from .conftest import isSkip


class TestClass001:
    
    # 用 skip 標記裝飾測試方法或者測試類
    @isSkip
    def test_func_001(self):
        pass

    def test_func_002(self):
        pass

導入模塊失敗時跳過測試用例:

importorskip(modname, minversion=None, reason=None);

注意:如果模塊導入成功,該方法會返回模塊本身,如果導入失敗,則會跳過測試模塊後面的所有代碼;

  • modname 參數   :要導入的模塊名稱;
  • minversion 參數 :要導入模塊的最低版本號, 如果給定,導入的模塊__version__屬性必須至少爲此最小版本,否則仍會跳過測試;
  • reason 參數        :跳過理由;
# test_moduleName.py

import pytest

# 如果模塊導入成功,該方法會返回模塊本身,如果導入失敗,則會跳過測試模塊後面的所有代碼;
time = pytest.importorskip('time')

time.sleep(3)

class TestClass001:

    def test_func_001(self):
        pass

    def test_func_002(self):
        pass

處理預計會失敗的用例:

@pytest.mark.xfail(condition, reason='理由!')

  • 預計失敗,condition條件滿足/表達式爲True時,用例失敗則標記爲 XFAIL,用例通過則標記爲 XPASS,表達式爲False時沒任何作用!
  • 通過修改 pytest.ini 可以強制執行 XPASS 爲 Fail
    [pytest]
    xfail_strict = true
# test_moduleName.py

import pytest

# 校驗條件
sys_version = 8

class TestClass001:

    # 表達式不成立,此方法不生效
    @pytest.mark.xfail(sys_version < 5, reason='原因!')
    def test_func_001(self):
        pass

    # 表達式成立,預計失敗,實際通過,結果爲 XPASS
    @pytest.mark.xfail(sys_version < 10, reason='原因!')
    def test_func_002(self):
        assert 1

    # 表達式成立,預計失敗,實際失敗,結果爲 XFAIL
    @pytest.mark.xfail(sys_version < 10, reason='原因!')
    def test_func_003(self):
        assert 0
# 執行結果
============================= test session starts =============================
collected 3 items

test_moduleName.py::TestClass001::test_func_001 PASSED
test_moduleName.py::TestClass001::test_func_002 XPASS
test_moduleName.py::TestClass001::test_func_003 XFAIL

=================== 1 passed, 1 xfailed, 1 xpassed in 0.05s ===================

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章