pytest單元測試框架中可以使用命令列
及程式碼pytest.main()
兩種方式執行測試,且可以加入各種引數來組織執行測試。接下來我們來了解常用的執行引數的含義及其用法。
pytest中的執行引數根據作用的不同大致可以分為以下幾類:
- 指定測試用例
- 控制執行過程
- 結果展示
每個示例都會以pytest.main()形式
及命令列形式
兩種方式進行說明。
指定測試用例
執行指定路徑的測試用例
# 執行當前檔案所在的同級目錄中,testcase資料夾裡的所有測試用例
pytest.main(["./testcase"])
# 也可以寫成如下形式。後續示例中都將`./`省略
pytest.main(["testcase"])
# 命令列形式
pytest
# 執行指定模組
pytest.main(["testcase/test_case.py"])
# 命令列形式
pytest testcase/test_case.py
# 執行指定模組中的測試類
pytest.main(["testcase/test_case.py::TestOrder"])
# 命令列形式
pytest testcase/test_case_1.py::TestOrder
# 執行指定類中的測試方法
pytest.main(["testcase/test_case.py::TestOrder::test_order"])
# 命令列形式
pytest testcase/test_case.py::TestOrder::test_order
-m
執行指定標記的測試用例
我們之前已經講過怎麼標記用例,可以檢視pytest-標記用例(指定執行、跳過用例、預期失敗)
# 執行被標記為smoke的用例
pytest.main(['-m smoke'])
# 命令列形式
pytest -m smoke
# 執行被標記為smoke或order的用例
pytest.main(["-m", "smoke or order"])
# 命令列形式
pytest -m "smoke or order"
-k
執行匹配指定字串的測試用例
-k
指定字串,用於匹配包名、模組名、類名、測試函式名/方法名,這些命名中包含指定的字串則匹配並執行。
# 執行包名、模組名、類名、測試函式名/方法名中包含order的測試用例
pytest.main(["-k", "order"])
# 命令列形式
pytest -k order
# 執行指定模組中的類名、測試函式名/方法名中包含order的測試用例
pytest.main(["-k", "order", "testcase/test_case.py"])
# 命令列形式
pytest -k login testcase/test_case.py
# 執行指定類中測試函式名包含order的測試用例
pytest.main(["-k", "order", "testcase/test_case.py::TestOrder"])
# 命令列形式
pytest -k order testcase/test_case.py::TestOrder
控制執行過程
用例失敗重新執行次數
用例執行時有可能會出現某些偶然因素導致用例斷言失敗但實際又不是bug的情況,如網路波動導致響應時間慢,此時用例失敗後再次去重新執行該用例就顯得很重要。
pytest提供了一個常用的外掛pytest-rerunfailures
,用於設定測試用例執行失敗後的最多重新執行次數(即重試機制)。
使用之前需要先安裝:pip install pytest-rerunfailures
,使用方式如下:
# 執行失敗後該用例重新執行最多3次
pytest.main(["--reruns", "3", "testcase/test_case.py"])
# 命令列形式
pytest --reruns=3 testcase/test_case.py
用例執行失敗則停止執行
根據需求提供一下兩種方式:
-x
或--exitfirst
,遇到用例執行失敗就停止專案的執行,只要失敗就立即停止執行--maxfail=num
,遇到多少次用例執行失敗就停止專案執行,num
表示用例執行失敗次數
# -x,遇到執行用例失敗則停止整個專案的執行
pytest.main(["-x", "testcase/test_case.py"])
# 命令列形式
pytest -x testcase/test_case.py
# --maxfail,如累計有5次用例執行失敗則停止整個專案的執行
pytest.main(["--maxfail", "5", "testcase/test_case.py"])
# 命令列形式
pytest --maxfail=5 testcase/test_case.py
執行上次失敗用例
當bug修復完成後,我們可能只需要去執行上次執行失敗的用例,在pytest中就提供了這樣的功能,需要用到一下引數:
--lf
或--last-failed
,只執行上次執行失敗的用例,若上次執行沒有失敗用例則會執行全部用例。--ff
或--failed-first
,首先執行上次執行失敗的用例,再執行專案中其他所有用例。
# --lf,只執行上次執行失敗的用例,若上次執行沒有失敗用例則會執行全部用例
pytest.main(["--lf", "testcase/test_case.py"])
# 命令列形式
pytest --lf testcase/test_case.py
# --ff,首先執行上次執行失敗的用例,再執行專案中其他所有用例
pytest.main(["--ff", "testcase/test_case.py"])
# 命令列形式
pytest --ff testcase/test_case.py
執行結果展示
與展示結果相關的常用的引數有以下幾個:
-s
,在測試結果中顯示測試用例裡print的內容(執行結果預設不顯示測試用例中print的內容)。-v
,顯示更詳細的測試結果。-q
,展示簡略的測試結果,與-v
作用剛好相反。
# -s,測試結果中顯示測試用例裡print的內容
pytest.main(["-s", "testcase/test_case.py"])
# 命令列形式
pytest -s testcase/test_case.py
# -v,設定測試結果顯示的詳細程度
pytest.main(["-v", "testcase/test_case.py"])
# 命令列形式
pytest -v testcase/test_case.py
# -q,設定測試結果顯示的詳細程度
pytest.main(["-q", "testcase/test_case.py"])
# 命令列形式
pytest -q testcase/test_case.py
示例
測試用例寫在testcase/test_case.py
中,專案執行程式碼寫在與testcase
同級目錄的run.py
中,簡單示例如下:
test_case.py
:
def test_01():
print("執行test_01")
a = "hello"
b = "hi"
assert a != b
def test_02():
print("執行test_02")
a = "hello"
b = "hi"
assert a == b
class TestOrder:
def test_order(self):
print("下單")
run.py
:
import pytest
if __name__ == '__main__':
pytest.main(["-s", "-v", "--reruns", "2", "testcase/test_case.py"])
執行run.py
或命令列pytest -s -v --reruns=2 testcase/test_case.py
,結果如下:
我們可以看出來:
- 因為
-s
,結果中列印了測試用例中print
裡面的內容。 - 因為
-v
,顯示了較為詳細的測試結果(不加-v
則只顯示執行的測試模組,不顯示測試用例而是用.
表示)。 - 因為
--reruns
2
,因為test_02
的斷言始終是失敗的,所以失敗後又執行了2
次,總共執行了3
次。
總結
這裡只列舉了一些常用的執行方法與引數,大家可以在自己的自動化專案中嘗試著使用這些方式與引數。