首頁 > 軟體

python中Pytest常用的外掛

2022-06-16 18:02:39

前言

除了框架本身提供的功能外,Pytest還支援上百種第三方外掛,良好的擴充套件性可以更好的滿足大家在用例設計時的不同需求。本文將為大家詳細介紹下面5項常用的外掛。

1. 用例依賴

編寫用例的時候,我們會注意用例之間的獨立性,但部分用例之間確實存在關聯,無法做到徹底獨立,那麼我們就可以通過使用外掛pytest-dependency設定用例之間的依賴關係。當用例A依賴於用例B時,若用例B執行失敗,則用例A將會自動跳過不執行。如此,就可以避免去執行一個必定會失敗的用例,相當於pytest.mark.skip。

(1)安裝:

pip install pytest-dependency

(2)使用說明:

首先,在標記被依賴用例時,需要在被依賴的用例上新增裝飾器pytest.mark.dependency(),且被依賴用例需要在關聯用例前執行。也可以給被依賴用例設定別名,通過新增引數name實現。

在關聯的依賴用例上,同樣需要新增裝飾器pytest.mark.dependency(depends=['用例名稱']),與之前不同的是,裝飾器必須要填寫depends引數完成用例的關聯,關聯的被依賴用例存在多個時可以使用“,”隔開。

此外,還可以通過scope引數指定用例依賴的範圍,同樣是session、package、module、class這四種型別,此處不詳細展開。

具體通過下方的範例以及執行結果來進一步說明。

(3)範例及執行結果分析

範例:

import pytest
class TestCase:
    # 通過裝飾器@pytest.mark.dependency()標記當前用例為被依賴用例,被依賴用例需要優先關聯用例執行
    @pytest.mark.dependency()
    def test_01(self):
        print("測試用例01,執行失敗")
        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,執行成功!")
    # 使用depends引數指定定義的別名關聯用例
    @pytest.mark.dependency(depends=['func_2'])
    def test_04(self):
        print("測試用例04,執行成功!")
    # depends引數可以關聯多個測試用例,使用「,」分隔即可
    @pytest.mark.dependency(depends=['test_01', 'func_2'])
    def test_05(self):
        print("測試用例05,跳過")
if __name__ == '__main__':
    pytest.main(['-vs'])

執行結果如下:

我們可以看出,只有依賴用例執行成功時,當前用例才會被執行,否則會被跳過。依賴多個用例時,只有全部成功,才會執行,否則一樣會跳過。

2. 失敗重跑

有些情況下,用例在執行過程中可能會受到一些客觀因素的影響,導致用例執行失敗,通過使用pytest-rerunfailures外掛,可以在失敗後重新執行用例,並設定重新執行的最大次數。以此保證用例執行結果的準確性。

(1)安裝:

pip install pytest-rerunfailures

(2)使用說明:

失敗重跑共有兩種使用方式,分別是通過裝飾器執行和命令列執行。

使用裝飾器時,需要在用例上新增裝飾器pytest.mark.flaky(reruns=重新執行最大次數, reruns_delay=執行間隔時間(單位:秒)),在執行過程中,新增了裝飾器的用例在執行失敗後會按照設定的次數和時間重新執行。

通過在命令列執行時,同樣需要指定"rerun"和"rerun-delay"兩個引數來實現,如:pytest --reruns 重新執行最大次數 --reruns-delay 間隔時間。

注意:reruns是重新執行的最大次數,如果在達到這一數量前用例執行成功,則不會繼續重跑,判斷用例執行通過;否則執行到最大次數後,用例仍失敗,則判斷用例執行失敗。

具體通過下方的範例和執行結果進一步說明。

(3)範例及執行結果分析

範例:

import pytest
import random
class TestCase:
    # 使用裝飾器設定用例失敗後的重新執行最大次數和每次執行的間隔時間(單位:秒)
    @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'])

執行結果如下:

我們可以看出,當用例斷言失敗後,會重新執行,直到達到設定的最大次數或執行成功為止。

3. 指定用例執行順序

pytest在執行用例的時候,預設是按照檔案中用例的先後順序執行,有時我們可能在維護測試用例時遇到需要修改用例執行順序的情況,但是如果每次都通過修改大段的用例程式碼先後位置來控制,並不利於維護。因此,使用外掛pytest-ordering可以快速實現用例執行順序的設定,後期維護時,也只需要修改對應的執行順序引數即可。

(1)安裝:

pip install pytest-ordering

(2)使用說明:

通過給用例新增裝飾器pytest.mark.run(order=執行順序)設定用例的執行順序。在執行的時候,使用裝飾器pytest.mark.run的用例會優先沒有裝飾器的用例執行,設定了執行順序的用例則按照order引數設定的大小升序執行。

具體通過下方的範例和執行結果進一步說明。

(3)範例及執行結果分析

範例:

import pytest
class TestCase:
    def test_01(self):
        print("測試用例01")
    def test_02(self):
        print("測試用例02")
    # 使用裝飾器設定執行順序為2
    @pytest.mark.run(order=2)
    def test_03(self):
        print("測試用例03")
    # 使用裝飾器設定執行順序為1
    @pytest.mark.run(order=1)
    def test_04(self):
        print("測試用例04")
if __name__ == "__main__":
    pytest.main(['-vs'])

執行結果:

我們可以看出,執行的順序和預期一致。優先執行標明瞭執行順序的用例,並按照order的值由小到大執行。

4. 分散式執行

當專案的用例很多的時候,執行通常會耗時頗久,通過分散式執行,則可以大量縮短整體用例的執行時間。pytest-xdist外掛就可以幫助我們完成測試用例的分散式執行。

(1)安裝:

pip install pytest-xdist

(2)使用說明:

在命令列執行用例時,通過引數-n設定並行啟動的程序數量。除了設定具體的數量外,還可以設定為auto,這種情況下,會依據當前裝置的cpu數量執行。

此外,還可以通過--dist引數,設定用例分組,同一個組內的用例會在同一個程序中執行。

  • --dist=loadscope 同一個module或同一個class下的用例會分配為同一組,按class分組優先於module。
  • --dist=loadfile 同一個.py檔案中的用例會分配為同一組。

具體通過下方的範例和執行結果進一步說明。

(3)範例及執行結果分析

範例:

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執行

執行結果:

從上方的兩次執行結果中可以看出,使用分散式執行後,用例的執行時間明顯縮短。範例中的用例彼此之間沒有關聯,如果實際使用時用例之間存在依賴關係,可以使用--dist引數為用例分組,確保關聯的用例在同一組內。

5. 多重斷言

有時,在一個用例中,我們需要對結果進行不同維度的多個斷言,但是使用assert斷言時,只要有一個斷言失敗,後續的斷言就不會繼續執行。現在,我們可以通過使用pytest-assume外掛來解決這個問題,當斷言失敗後,仍會繼續執行後續的斷言。

(1)安裝:

pip install pytest-assume

(2)使用說明:

在用例中,把使用assert進行的斷言,改為使用pytest.assume()進行斷言即可。

具體通過下方的範例和執行結果進一步說明。

(3)範例及執行結果分析

範例:

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'])

執行結果:

從執行結果中可以看出,使用assert斷言時,斷言失敗不會再執行後續的內容;而使用pytest.assume()斷言時,斷言失敗仍會執行至用例結束。這樣更有利於我們一次性獲取用例執行中全部錯誤資訊。

6. 小結

本文為大家介紹了一些常用的pytest框架的外掛,可以幫助我們解決一些實際使用過程中遇到的問題。目前,pytest支援的外掛已經多達868個,除了本文介紹的5個常用外掛外,還有很多支援其它需求的外掛,大家可以根據自己的需要嘗試查詢使用相關的外掛,以便能夠更好的設計出符合業務場景的測試用例。

到此這篇關於python中Pytest常用的外掛的文章就介紹到這了,更多相關python Pytest 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com