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
次。
總結
這里只列舉了一些常用的運行方法與參數,大家可以在自己的自動化項目中嘗試着使用這些方式與參數。