1. 程式人生 > >pytest-28-重復執行用例(pytest-repeat)

pytest-28-重復執行用例(pytest-repeat)

UNC cas 範圍 第一次 tco file 自動化 更多 設置

平常在做功能測試的時候,經常會遇到某個模塊不穩定,偶然會出現一些bug,對於這種問題我們會針對此用例反復執行多次,最終復現出問題來。
自動化運行用例時候,也會出現偶然的bug,可以針對單個用例,或者針對某個模塊的用例重復執行多次。

pytest-repeat

pytest-repeat是pytest的一個插件,用於重復執行單個用例,或多個測試用例,並指定重復次數,pytest-repeat支持的版本:

  • Python 2.7, 3.4+ 或 PyPy
  • py.test 2.8或更高

使用pip安裝pytest-repeat

pip install pytest-repeat

使用--count命令行選項指定要運行測試用例和測試次數

py.test --count=10 test_file.py

重復執行--count

運行以下代碼,項目結構如下

web_conf_py是項目工程名稱
│  conftest.py  
│  __init__.py
│              
├─baidu
│  │  conftest.py
│  │  test_1_baidu.py
│  │  test_2.py
│  │  __init__.py 
│          
├─blog
│  │  conftest.py
│  │  test_2_blog.py
│  │  __init__.py      

代碼參考:

# web_conf_py/conftest.py
import pytest

@pytest.fixture(scope="session")
def start():
    print("\n打開首頁")
    return "yoyo"

# web_conf_py/baidu/conftest.py
import pytest

@pytest.fixture(scope="session")
def open_baidu():
    print("打開百度頁面_session")

# web_conf_py/baidu/test_1_baidu.py
import pytest
import time

def test_01(start, open_baidu):
    print("測試用例test_01")
    time.sleep(1)
    assert start == "yoyo"

def test_02(start, open_baidu):
    print("測試用例test_02")
    time.sleep(1)
    assert start == "yoyo"

if __name__ == "__main__":
    pytest.main(["-s", "test_1_baidu.py"])


# web_conf_py/baidu/test_2.py
import pytest
import time

def test_06(start, open_baidu):
    print("測試用例test_01")
    time.sleep(1)
    assert start == "yoyo"
def test_07(start, open_baidu):
    print("測試用例test_02")
    time.sleep(1)
    assert start == "yoyo"

if __name__ == "__main__":
    pytest.main(["-s", "test_2.py"])

cmd進入到工程目錄後,不帶--count參數只會執行一次

pytest baidu/test_1_baidu.py -s

E:\YOYO\web_conf_py>pytest baidu/test_1_baidu.py -s
============================= test session starts =============================
platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
rootdir: E:\YOYO\web_conf_py, inifile:
plugins: xdist-1.23.2, repeat-0.7.0, metadata-1.7.0, html-1.19.0, forked-0.2
collected 2 items

baidu\test_1_baidu.py
打開首頁
打開百度頁面_session
測試用例test_01
.測試用例test_02
.

========================== 2 passed in 1.03 seconds ===========================

加上參數--count=5,用例會重復執行5次

pytest baidu/test_1_baidu.py -s --count=5

E:\YOYO\web_conf_py>pytest baidu/test_1_baidu.py -s --count=5
============================= test session starts =============================
platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
rootdir: E:\YOYO\web_conf_py, inifile:
plugins: xdist-1.23.2, repeat-0.7.0, metadata-1.7.0, html-1.19.0, forked-0.2
collected 10 items

baidu\test_1_baidu.py
打開首頁
打開百度頁面_session
測試用例test_01
.測試用例test_01
.測試用例test_01
.測試用例test_01
.測試用例test_01
.測試用例test_02
.測試用例test_02
.測試用例test_02
.測試用例test_02
.測試用例test_02
.

========================== 10 passed in 5.06 seconds ==========================

從運行的用例結果看,是先重復5次test_01,再重復5次test_02,有時候我們希望執行的順序是test_01,test_02按這樣順序重復五次,接下來就用到一個參數--repeat-scope

--repeat-scope

--repeat-scope類似於pytest fixture的scope參數,--repeat-scope也可以設置參數: sessionmoduleclass或者function(默認值)

  • function(默認)範圍針對每個用例重復執行,再執行下一個用例
  • class 以class為用例集合單位,重復執行class裏面的用例,再執行下一個
  • module 以模塊為單位,重復執行模塊裏面的用例,再執行下一個
  • session 重復整個測試會話,即所有收集的測試執行一次,然後所有這些測試再次執行等等

使用--repeat-scope=session重復執行整個會話用例

pytest baidu/test_1_baidu.py -s --count=5 --repeat-scope=session

E:\YOYO\web_conf_py>pytest baidu/test_1_baidu.py -s --count=5 --repeat-scope=session
============================= test session starts =============================
platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
rootdir: E:\YOYO\web_conf_py, inifile:
plugins: xdist-1.23.2, repeat-0.7.0, metadata-1.7.0, html-1.19.0, forked-0.2
collected 10 items

baidu\test_1_baidu.py
打開首頁
打開百度頁面_session
測試用例test_01
.測試用例test_02
.測試用例test_01
.測試用例test_02
.測試用例test_01
.測試用例test_02
.測試用例test_01
.測試用例test_02
.測試用例test_01
.測試用例test_02
.

========================== 10 passed in 5.07 seconds ==========================

@pytest.mark.repeat(count)

如果要在代碼中標記要重復多次的測試,可以使用@pytest.mark.repeat(count)裝飾器

# test_1_baidu.py
import pytest
import time

def test_01(start, open_baidu):
    print("測試用例test_01")
    time.sleep(0.5)
    assert start == "yoyo"

@pytest.mark.repeat(5)
def test_02(start, open_baidu):
    print("測試用例test_02")
    time.sleep(0.5)
    assert start == "yoyo"

if __name__ == "__main__":
    pytest.main(["-s", "test_1_baidu.py"])

這樣執行用例時候,就不用帶上--count參數,只針對test_02重復執行5次

E:\YOYO\web_conf_py>pytest baidu/test_1_baidu.py -s
============================= test session starts =============================
platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
rootdir: E:\YOYO\web_conf_py, inifile:
plugins: xdist-1.23.2, repeat-0.7.0, metadata-1.7.0, html-1.19.0, forked-0.2
collected 6 items

baidu\test_1_baidu.py
打開首頁
打開百度頁面_session
測試用例test_01
.測試用例test_02
.測試用例test_02
.測試用例test_02
.測試用例test_02
.測試用例test_02
.

========================== 6 passed in 3.05 seconds ===========================

重復測試直到失敗

如果您正在嘗試診斷間歇性故障,那麽一遍又一遍地運行相同的測試直到失敗是有用的。您可以將pytest的-x選項與pytest-repeat結合使用,以強制測試運行器在第一次失敗時停止。例如:

py.test --count=1000 -x test_file.py

這將嘗試運行test_file.py 1000次,但一旦發生故障就會停止

UnitTest樣式測試

不幸的是,此插件不支持unittest框架的用例,pytest-repeat無法使用unittest.TestCase測試類。無論如何,這些測試將始終運行一次--count,並顯示警告
更多資料參考【官方文檔:https://pypi.org/project/pytest-repeat/】

pytest-28-重復執行用例(pytest-repeat)