如何呼叫 pytest

一般而言,pytest 會使用指令 pytest 呼叫 (請參閱下方 呼叫 pytest 的其他方式)。這將執行目前目錄及其子目錄中所有符合 test_*.py\*_test.py 形式命名的檔案中的所有測試。更廣泛來說,pytest 會遵循 標準測試發現規則

指定要執行哪些測試

Pytest 支援多種方式從命令列或檔案執行和選取測試 (請參閱下方 從檔案讀取引數)。

在模組中執行測試

pytest test_mod.py

在目錄中執行測試

pytest testing/

透過關鍵字表達式執行測試

pytest -k 'MyClass and not method'

這將執行包含與所提供字串表達式相符名稱的測試 (不分大小寫),其中可以包含使用檔案名稱、類別名稱和函式名稱作為變數的 Python 運算子。上述範例將執行 TestMyClass.test_something 但不會執行 TestMyClass.test_method_simple。在 Windows 上執行此操作時,請在表達式中使用 "" 取代 ''

透過收集引數執行測試

傳遞相對於工作目錄的模組檔案名稱,接著是使用 :: 字元分隔的類別名稱和函式名稱等規格,以及用 [] 括起來的參數化參數。

要在模組中執行特定測試

pytest tests/test_mod.py::test_func

執行類別中的所有測試

pytest tests/test_mod.py::TestClass

指定特定測試方法

pytest tests/test_mod.py::TestClass::test_method

指定測試的特定參數化

pytest tests/test_mod.py::test_func[x1,y2]

依據標記表達式執行測試

pytest -m slow

將執行所有以 @pytest.mark.slow 裝飾器裝飾的測試。

更多資訊請參閱 標記

從套件執行測試

pytest --pyargs pkg.testing

這將匯入 pkg.testing 並使用其檔案系統位置來尋找並執行測試。

從檔案讀取參數

已新增至第 8.2 版。

上述所有內容都可以使用 @ 前綴從檔案讀取

pytest @tests_to_run.txt

其中 tests_to_run.txt 每行包含一個項目,例如

tests/test_file.py
tests/test_mod.py::test_func[x1,y2]
tests/test_mod.py::TestClass
-m slow

此檔案也可以使用 pytest --collect-only -q 產生,並依需要修改。

取得版本、選項名稱、環境變數的說明

pytest --version   # shows where pytest was imported from
pytest --fixtures  # show available builtin function arguments
pytest -h | --help # show help on command line and config file options

分析測試執行時間

已在第 6.0 版中變更。

若要取得超過 1.0 秒的最慢 10 個測試時間清單

pytest --durations=10 --durations-min=1.0

預設情況下,除非在命令列中傳遞 -vv,否則 pytest 絕不會顯示過小的測試時間 (<0.005 秒)。

管理外掛程式載入

早期載入外掛程式

您可以使用 -p 選項在命令列中明確地提早載入外掛程式(內部和外部)。

pytest -p mypluginmodule

選項會接收 name 參數,該參數可以是

  • 完整的模組點分名稱,例如 myproject.plugins。此點分名稱必須可以匯入。

  • 外掛程式的進入點名稱。這是外掛程式在註冊時傳遞給 setuptools 的名稱。例如,若要提早載入 pytest-cov 外掛程式,可以使用

    pytest -p pytest_cov
    

停用外掛程式

若要在呼叫時停用載入特定外掛程式,請將 -p 選項與前綴 no: 一起使用。

範例:若要停用 doctest 外掛程式(負責從文字檔執行 doctest 測試),請像這樣呼叫 pytest

pytest -p no:doctest

其他呼叫 pytest 的方式

透過 python -m pytest 呼叫 pytest

你可以從命令列透過 Python 解譯器呼叫測試

python -m pytest [...]

這幾乎等同於直接呼叫命令列腳本 pytest [...],除了透過 python 呼叫也會將目前目錄加入 sys.path

從 Python 程式碼呼叫 pytest

你可以直接從 Python 程式碼呼叫 pytest

retcode = pytest.main()

這就像你從命令列呼叫「pytest」一樣。它不會引發 SystemExit,而是回傳 結束程式碼。如果你沒有傳入任何引數,main 會從程序的命令列引數 (sys.argv) 讀取引數,這可能不是你想要的。你可以明確傳入選項和引數

retcode = pytest.main(["-x", "mytestdir"])

你可以為 pytest.main 指定其他外掛程式

# content of myinvoke.py
import sys

import pytest


class MyPlugin:
    def pytest_sessionfinish(self):
        print("*** test run reporting finishing")


if __name__ == "__main__":
    sys.exit(pytest.main(["-qq"], plugins=[MyPlugin()]))

執行它會顯示 MyPlugin 已加入且其掛鉤已呼叫

$ python myinvoke.py
*** test run reporting finishing

注意

呼叫 pytest.main() 會匯入你的測試和它們匯入的任何模組。由於 Python 匯入系統的快取機制,從同一個程序後續呼叫 pytest.main() 時,不會反映呼叫之間對這些檔案的變更。因此,不建議從同一個程序多次呼叫 pytest.main()(例如,為了重新執行測試)。