有時候,為了滿足某些場景的需要,我們知道有些測驗函式在這時候肯定不能執行,或者執行了也會失敗,那么我們
可以選擇去跳過這個測驗函式,這樣也就不會影響整體的測驗函式運行效果,不至于在你運行的眾多綠色通過的測驗
用例中,給你加點紅色的failed或者error,
舉個例子,有些測驗函式只能在windows上運行,那么換了個Linux平臺就不可以,就需要跳過這個測驗函式,再比如,
有些測驗用例會有一些外部資源的依賴,像資料庫,那么當資料庫資源不可用的時候,也需要去跳過這個測驗函式,
在pytest中提供了這樣一個機制來跳過測驗函式,
一、skip
用法很簡單,只要在需要跳過的測驗函式上面安上@pytest.mark.skip()即可,可以傳遞一個引數reason,填寫
跳過的理由,不填也可以,
@pytest.mark.skip(reason="沒啥理由,就不想執行")
def test_the_unknown():
...
運行結果:
test_skipif.py [100%]
============================= 1 skipped in 0.02s ==============================s
Skipped: 沒啥理由,就不想執行
Process finished with exit code 0
可以看到,這個測驗用例被成功跳過,并且還有reason的輸出,不過pytest默認情況下,不會顯示跳過的測驗函式的詳細資訊,
避免輸出與正常的混在一起,太亂,
二、pytest.skip(reason)
1. 在測驗函式或者fixture函式里使用
除了上述用法,還可以用pytest.skip(reason)函式,在測驗函式中或者setup函式里進行跳過,比如,當有些引數不符合你
的預期,那么就跳過后面的執行,
上示例代碼:
import pytest
@pytest.fixture()
def demo_fixture(request):
test_input = request.param
if test_input == 3:
pytest.skip("傳入的值等于3就跳過執行")
@pytest.mark.parametrize("demo_fixture", [1, 3], indirect=True)
def test_the_unknown3(demo_fixture):
...
if __name__ == "__main__":
pytest.main(["-s", '-r' "test_skipif.py"])
在上述代碼里,我在測驗函式test_the_unknown3里做了一個引數化,并且在fixture函式demo_fixture拿到這個引數,
按理來說,引數化了1和3,所以測驗函式會執行2次,
我在fixture函式里加了判斷,當拿到的引數,等于3的時候,就跳過執行,所以最終的運行結果應該是,1執行,3跳過,
test_skipif.py [100%]
======================== 1 passed, 1 skipped in 0.09s =========================.s
Skipped: 傳入的值等于3就跳過執行
Process finished with exit code 0
結果符合預期,
這個用法,剛好解決了我一個實際問題,
那就是別的小組有不少人寫case用的測驗資料,是會通過別的case或者別的介面呼叫后傳遞過來的,那么當這些依賴有問題的時候
case運行就會有問題,導致誤報,如果使用pytest.skip(reason)這個函式,那么可以有效緩解case誤報的問題,
2. allow_module_level=True跳過整個模塊
如果你需要判斷某些條件符合時候,就要整個模塊都跳過,就可以加上這個引數allow_module_level=True,
import pytest
a = 1
if a != 3:
pytest.skip("a不等于3就跳過整個檔案模塊", allow_module_level=True)
@pytest.fixture()
def demo_fixture(request):
test_input = request.param
if test_input == 3:
pytest.skip("傳入的值等于3就跳過")
@pytest.mark.parametrize("demo_fixture", [1, 3], indirect=True)
def test_the_unknown1(demo_fixture):
...
def test_the_unknown2():
...
def test_the_unknown3():
...
運行一下:
============================= 1 skipped in 0.02s ==============================
Skipped: a不等于3就跳過整個檔案模塊
Process finished with exit code 0
三、skipif
1. skipif有條件的跳過
上面提到了在函式里寫判斷,當滿足某個條件時通過pytest.skip函式來跳過,其實還可以直接用skipif,同樣可以
達到有條件地跳過某些內容的目的,
import sys
@pytest.mark.skipif(sys.version_info < (4, 0), reason="版本4.0以下就跳過執行")
def test_function():
print(sys.version_info)
運行結果:
test_module1.py [100%]
============================= 1 skipped in 0.02s ==============================s
Skipped: 版本4.0以下就跳過執行
Process finished with exit code 0
2.模塊之間共享skip標記
比如說,我現在有2個測驗模塊,分別是test_module1.py和test_module2.py,
我在test_module1.py當中,定義一個skipif作為marker 共享,也就是not_equal_5,
那么在test_module2.py當中匯入這個marker,就可以直接使用了,看代碼效果:
# content of test_module1.py
import pytest
import sys
version_judge = pytest.mark.skipif(
sys.version_info < (4, 0), reason="版本4.0以下就跳過執行"
)
@version_judge
def test_the_unknown2():
...
if __name__ == "__main__":
pytest.main(["-s", '-r' "test_module1.py"])
在test_module2.py中匯入marker使用,運行后的預期結果,應該是test_the_unknown1跳過執行,
# content of test_module2.py
import pytest
from interface.demo.test_module1 import version_judge
@version_judge
def test_the_unknown1():
...
def test_the_unknown2():
...
if __name__ == "__main__":
pytest.main(["-s", '-r' "test_module2.py"])
運行下test_module2.py:
test_module2.py [100%]
======================== 1 passed, 1 skipped in 0.08s =========================s
Skipped: 版本4.0以下就跳過執行
.
Process finished with exit code 0
四、跳過類或模塊下的所有測驗函式
1. 跳過類下的所有測驗函式
如果把skipif放在類上,這個類下面的所有測驗函式都會跳過,
import pytest
import sys
version_judge = pytest.mark.skipif(
sys.version_info < (4, 0), reason="版本4.0以下就跳過執行"
)
@version_judge
class TestDemo():
def test_the_unknown2(self):
...
def test_the_unknown3(self):
...
def test_the_unknown1():
...
if __name__ == "__main__":
pytest.main(["-s", '-r' "test_module1.py"])
運行結果,類TestDemo下的2個測驗方法都會被跳過,
test_module1.py [100%]
======================== 1 passed, 2 skipped in 0.09s =========================s
Skipped: 版本4.0以下就跳過執行
s
Skipped: 版本4.0以下就跳過執行
.
Process finished with exit code 0
2.跳過模塊下的所有測驗函式
如果想跳過模塊的所有測驗函式,可以使用全域變數pytestmark:
import pytest
import sys
pytestmark = pytest.mark.skipif(sys.version_info < (4, 0), reason="版本4.0以下就跳過執行")
class TestDemo():
def test_the_unknown2(self):
...
def test_the_unknown3(self):
...
def test_the_unknown1():
...
if __name__ == "__main__":
pytest.main(["-s", '-r' "test_module1.py"])
運行,模塊下的3個測驗都會被跳過
test_module1.py [100%]
============================= 3 skipped in 0.02s ==============================s
Skipped: 版本4.0以下就跳過執行
s
Skipped: 版本4.0以下就跳過執行
s
Skipped: 版本4.0以下就跳過執行
Process finished with exit code 0
另外,如果多個skipif裝飾器應用于同一個測驗函式,只要任何一個條件為真,該函式將被跳過,
五、跳過檔案或目錄
有時可能需要跳過一整個檔案或目錄,例如,有檔案里的代碼你不想去執行,在這種情況下,必須從pytest搜集到的集合中排除檔案和目錄,
有關更多資訊,請參閱自定義測驗集合,后續看情況單獨分享,
六、匯入依賴失敗跳過
當有些依賴的包匯入失敗的時候,可以通過pytest.importorskip這個函式來跳過,同樣,可以用在模塊級別,fixture函式或者測驗函式里,
import pytest
# docutils = pytest.importorskip("docutils")
class TestDemo():
def test_the_unknown2(self):
...
def test_the_unknown3(self):
pytest.importorskip("docutils")
def test_the_unknown1():
...
if __name__ == "__main__":
pytest.main(["-s", '-r' "test_module1.py"])
運行結果,應該是跳過一個,執行2個:
test_module1.py [100%]
======================== 2 passed, 1 skipped in 0.09s =========================.s
Skipped: could not import 'docutils': No module named 'docutils'
.
Process finished with exit code 0
代碼里的docutils是一個第三方庫,你也可以根據庫的版本號跳過:
docutils = pytest.importorskip("docutils", minversion="0.3")
版本將從指定模塊的__version__屬性中讀取,如果不符合條件,也會跳過,
七、總結
- 無條件跳過模塊中的所有測驗
pytestmark = pytest.mark.skip("all tests still WIP")
- 基于某些條件跳過模塊中的所有測驗
pytestmark = pytest.mark.skipif(sys.platform == "win32", reason="tests for linux only")
- 如果缺少某些匯入,則跳過模塊中的所有測驗
pexpect = pytest.importorskip("pexpect")
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/278760.html
標籤:其他
