python中Pytest常用的插件
前言
除了框架本身提供的功能外,Pytest還支持上百種第三方插件,良好的擴展性可以更好的滿足大家在用例設計時的不同需求。本文將為大家詳細介紹下面5項常用的插件。
1. 用例依賴
編寫用例的時候,我們會注意用例之間的獨立性,但部分用例之間確實存在關聯,無法做到徹底獨立,那么我們就可以通過使用插件pytest-dependency設置用例之間的依賴關系。當用例A依賴于用例B時,若用例B執(zhí)行失敗,則用例A將會自動跳過不執(zhí)行。如此,就可以避免去執(zhí)行一個必定會失敗的用例,相當于pytest.mark.skip。
(1)安裝:
pip install pytest-dependency
(2)使用說明:
首先,在標記被依賴用例時,需要在被依賴的用例上添加裝飾器pytest.mark.dependency(),且被依賴用例需要在關聯用例前執(zhí)行。也可以給被依賴用例設置別名,通過添加參數name實現。
在關聯的依賴用例上,同樣需要添加裝飾器pytest.mark.dependency(depends=['用例名稱']),與之前不同的是,裝飾器必須要填寫depends參數完成用例的關聯,關聯的被依賴用例存在多個時可以使用“,”隔開。
此外,還可以通過scope參數指定用例依賴的范圍,同樣是session、package、module、class這四種類型,此處不詳細展開。
具體通過下方的示例以及執(zhí)行結果來進一步說明。
(3)示例及執(zhí)行結果分析
示例:
import pytest
class TestCase:
# 通過裝飾器@pytest.mark.dependency()標記當前用例為被依賴用例,被依賴用例需要優(yōu)先關聯用例執(zhí)行
@pytest.mark.dependency()
def test_01(self):
print("測試用例01,執(zhí)行失敗")
assert 1 == 2
# 通過使用裝飾器關聯被依賴用例,通過depends參數指定用例名稱關聯用例
@pytest.mark.dependency(depends=['test_01'])
def test_02(self):
print("測試用例02,跳過")
# 標記被依賴用例時,可以通過name參數指定別名
@pytest.mark.dependency(name="func_2")
def test_03(self):
print("測試用例03,執(zhí)行成功!")
# 使用depends參數指定定義的別名關聯用例
@pytest.mark.dependency(depends=['func_2'])
def test_04(self):
print("測試用例04,執(zhí)行成功!")
# depends參數可以關聯多個測試用例,使用“,”分隔即可
@pytest.mark.dependency(depends=['test_01', 'func_2'])
def test_05(self):
print("測試用例05,跳過")
if __name__ == '__main__':
pytest.main(['-vs'])執(zhí)行結果如下:

我們可以看出,只有依賴用例執(zhí)行成功時,當前用例才會被執(zhí)行,否則會被跳過。依賴多個用例時,只有全部成功,才會執(zhí)行,否則一樣會跳過。
2. 失敗重跑
有些情況下,用例在執(zhí)行過程中可能會受到一些客觀因素的影響,導致用例執(zhí)行失敗,通過使用pytest-rerunfailures插件,可以在失敗后重新執(zhí)行用例,并設置重新運行的最大次數。以此保證用例執(zhí)行結果的準確性。
(1)安裝:
pip install pytest-rerunfailures
(2)使用說明:
失敗重跑共有兩種使用方式,分別是通過裝飾器執(zhí)行和命令行執(zhí)行。
使用裝飾器時,需要在用例上添加裝飾器pytest.mark.flaky(reruns=重新執(zhí)行最大次數, reruns_delay=執(zhí)行間隔時間(單位:秒)),在執(zhí)行過程中,添加了裝飾器的用例在執(zhí)行失敗后會按照設置的次數和時間重新執(zhí)行。
通過在命令行執(zhí)行時,同樣需要指定"rerun"和"rerun-delay"兩個參數來實現,如:pytest --reruns 重新執(zhí)行最大次數 --reruns-delay 間隔時間。
注意:reruns是重新執(zhí)行的最大次數,如果在達到這一數量前用例執(zhí)行成功,則不會繼續(xù)重跑,判斷用例執(zhí)行通過;否則執(zhí)行到最大次數后,用例仍失敗,則判斷用例執(zhí)行失敗。
具體通過下方的示例和執(zhí)行結果進一步說明。
(3)示例及執(zhí)行結果分析
示例:
import pytest
import random
class TestCase:
# 使用裝飾器設置用例失敗后的重新執(zhí)行最大次數和每次執(zhí)行的間隔時間(單位:秒)
@pytest.mark.flaky(reruns=3, reruns_delay=1)
def test_01(self):
result = random.choice(['a', 'b', 'c', 'd', 'e'])
print(f"result={result}")
assert result == 'c'
if __name__ == '__main__':
pytest.main(['-vs'])執(zhí)行結果如下:

我們可以看出,當用例斷言失敗后,會重新執(zhí)行,直到達到設置的最大次數或執(zhí)行成功為止。
3. 指定用例執(zhí)行順序
pytest在執(zhí)行用例的時候,默認是按照文件中用例的先后順序執(zhí)行,有時我們可能在維護測試用例時遇到需要修改用例執(zhí)行順序的情況,但是如果每次都通過修改大段的用例代碼先后位置來控制,并不利于維護。因此,使用插件pytest-ordering可以快速實現用例執(zhí)行順序的設置,后期維護時,也只需要修改對應的執(zhí)行順序參數即可。
(1)安裝:
pip install pytest-ordering
(2)使用說明:
通過給用例添加裝飾器pytest.mark.run(order=執(zhí)行順序)設置用例的執(zhí)行順序。在執(zhí)行的時候,使用裝飾器pytest.mark.run的用例會優(yōu)先沒有裝飾器的用例執(zhí)行,設置了執(zhí)行順序的用例則按照order參數設置的大小升序執(zhí)行。
具體通過下方的示例和執(zhí)行結果進一步說明。
(3)示例及執(zhí)行結果分析
示例:
import pytest
class TestCase:
def test_01(self):
print("測試用例01")
def test_02(self):
print("測試用例02")
# 使用裝飾器設置執(zhí)行順序為2
@pytest.mark.run(order=2)
def test_03(self):
print("測試用例03")
# 使用裝飾器設置執(zhí)行順序為1
@pytest.mark.run(order=1)
def test_04(self):
print("測試用例04")
if __name__ == "__main__":
pytest.main(['-vs'])執(zhí)行結果:

我們可以看出,執(zhí)行的順序和預期一致。優(yōu)先執(zhí)行標明了執(zhí)行順序的用例,并按照order的值由小到大執(zhí)行。
4. 分布式運行
當項目的用例很多的時候,執(zhí)行通常會耗時頗久,通過分布式運行,則可以大量縮短整體用例的執(zhí)行時間。pytest-xdist插件就可以幫助我們完成測試用例的分布式運行。
(1)安裝:
pip install pytest-xdist
(2)使用說明:
在命令行執(zhí)行用例時,通過參數-n設置并行啟動的進程數量。除了設置具體的數量外,還可以設置為auto,這種情況下,會依據當前設備的cpu數量執(zhí)行。
此外,還可以通過--dist參數,設置用例分組,同一個組內的用例會在同一個進程中執(zhí)行。
- --dist=loadscope 同一個module或同一個class下的用例會分配為同一組,按class分組優(yōu)先于module。
- --dist=loadfile 同一個.py文件中的用例會分配為同一組。
具體通過下方的示例和執(zhí)行結果進一步說明。
(3)示例及執(zhí)行結果分析
示例:
import pytest
from time import sleep
class TestCase1:
@pytest.mark.parametrize('keyword', ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])
def test_baidu_search(self, keyword):
sleep(1)
print(f'搜索關鍵字{keyword}')
class TestCase2:
@pytest.mark.parametrize('user', ['user1', 'user2', 'user3', 'user4', 'user5', 'user6', 'user7', 'user8', 'user9', 'user10']) def test_login(self, user):
sleep(1)
print(f'用戶{user}登錄成功')
if __name__ == '__main__':
# pytest.main(['-vs']) # 不使用pytest-xdist運行
pytest.main(['-vs', '-n', '2']) # 使用pytest-xdist運行執(zhí)行結果:


從上方的兩次執(zhí)行結果中可以看出,使用分布式運行后,用例的運行時間明顯縮短。示例中的用例彼此之間沒有關聯,如果實際使用時用例之間存在依賴關系,可以使用--dist參數為用例分組,確保關聯的用例在同一組內。
5. 多重斷言
有時,在一個用例中,我們需要對結果進行不同維度的多個斷言,但是使用assert斷言時,只要有一個斷言失敗,后續(xù)的斷言就不會繼續(xù)執(zhí)行?,F在,我們可以通過使用pytest-assume插件來解決這個問題,當斷言失敗后,仍會繼續(xù)執(zhí)行后續(xù)的斷言。
(1)安裝:
pip install pytest-assume
(2)使用說明:
在用例中,把使用assert進行的斷言,改為使用pytest.assume()進行斷言即可。
具體通過下方的示例和執(zhí)行結果進一步說明。
(3)示例及執(zhí)行結果分析
示例:
import pytest
class TestCase:
# 使用assert斷言
def test_01(self):
print("斷言1")
assert 1 == 1
print('斷言2')
assert 2 == 1
print("斷言3")
assert 3 == 3
print('用例結束')
# 使用pytest.assume()斷言
def test_02(self):
print('斷言1')
pytest.assume(1 == 1)
print('斷言2')
pytest.assume(2 == 1)
print('斷言3')
pytest.assume(3 == 3)
print('用例結束')
if __name__ == '__main__':
pytest.main(['-vs'])執(zhí)行結果:

從執(zhí)行結果中可以看出,使用assert斷言時,斷言失敗不會再執(zhí)行后續(xù)的內容;而使用pytest.assume()斷言時,斷言失敗仍會執(zhí)行至用例結束。這樣更有利于我們一次性獲取用例執(zhí)行中全部錯誤信息。
6. 小結
本文為大家介紹了一些常用的pytest框架的插件,可以幫助我們解決一些實際使用過程中遇到的問題。目前,pytest支持的插件已經多達868個,除了本文介紹的5個常用插件外,還有很多支持其它需求的插件,大家可以根據自己的需要嘗試查找使用相關的插件,以便能夠更好的設計出符合業(yè)務場景的測試用例。
到此這篇關于python中Pytest常用的插件的文章就介紹到這了,更多相關python Pytest 內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
python使用 multiprocessing 多進程處理批量數據的示例代碼
這篇文章主要介紹了使用 multiprocessing 多進程處理批量數據的示例代碼,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-09-09

