如何在測試中使用暫存目錄和檔案

tmp_path fixture

您可以使用 tmp_path fixture,它將為每個測試函數提供一個唯一的暫存目錄。

tmp_path 是一個 pathlib.Path 物件。以下是一個範例測試用法

# content of test_tmp_path.py
CONTENT = "content"


def test_create_file(tmp_path):
    d = tmp_path / "sub"
    d.mkdir()
    p = d / "hello.txt"
    p.write_text(CONTENT, encoding="utf-8")
    assert p.read_text(encoding="utf-8") == CONTENT
    assert len(list(tmp_path.iterdir())) == 1
    assert 0

執行此操作將導致測試通過,但最後一行 assert 0 除外,我們使用它來查看值

$ pytest test_tmp_path.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 1 item

test_tmp_path.py F                                                   [100%]

================================= FAILURES =================================
_____________________________ test_create_file _____________________________

tmp_path = PosixPath('PYTEST_TMPDIR/test_create_file0')

    def test_create_file(tmp_path):
        d = tmp_path / "sub"
        d.mkdir()
        p = d / "hello.txt"
        p.write_text(CONTENT, encoding="utf-8")
        assert p.read_text(encoding="utf-8") == CONTENT
        assert len(list(tmp_path.iterdir())) == 1
>       assert 0
E       assert 0

test_tmp_path.py:11: AssertionError
========================= short test summary info ==========================
FAILED test_tmp_path.py::test_create_file - assert 0
============================ 1 failed in 0.12s =============================

預設情況下,pytest 會保留最近 3 次 pytest 調用中的暫存目錄。通過配置基本暫存目錄以使每次並行運行都是唯一的,從而支援同一測試函數的並行調用。有關詳細資訊,請參閱暫存目錄位置和保留

tmp_path_factory fixture

tmp_path_factory 是一個 session 作用域的 fixture,可用於從任何其他 fixture 或測試建立任意暫存目錄。

例如,假設您的測試套件需要在磁碟上生成一個大型圖像,該圖像是以程式方式生成的。您可以為每個使用它的測試將相同的圖像計算到其自己的 tmp_path 中,而不是每個 session 生成一次以節省時間

# contents of conftest.py
import pytest


@pytest.fixture(scope="session")
def image_file(tmp_path_factory):
    img = compute_expensive_image()
    fn = tmp_path_factory.mktemp("data") / "img.png"
    img.save(fn)
    return fn


# contents of test_image.py
def test_histogram(image_file):
    img = load_image(image_file)
    # compute and test histogram

有關詳細資訊,請參閱tmp_path_factory API

tmpdirtmpdir_factory fixtures

tmpdirtmpdir_factory fixtures 類似於 tmp_pathtmp_path_factory,但使用/返回舊式的 py.path.local 物件,而不是標準的 pathlib.Path 物件。

注意

現在,建議使用 tmp_pathtmp_path_factory

為了幫助現代化舊程式碼庫,可以禁用 legacypath plugin 運行 pytest

pytest -p no:legacypath

這將觸發使用舊式路徑的測試錯誤。它也可以在配置文件中永久設定為 addopts 參數的一部分。

有關詳細資訊,請參閱tmpdir tmpdir_factory API。

暫存目錄位置和保留

tmp_path 和(現在已棄用)tmpdir fixtures 返回的暫存目錄,會自動在基本暫存目錄下建立,其結構取決於 --basetemp 選項

  • 預設情況下(當未設定 --basetemp 選項時),暫存目錄將遵循以下模板

    {temproot}/pytest-of-{user}/pytest-{num}/{testname}/
    

    其中

    自動遞增的 {num} 佔位符提供了一個基本的保留功能,並避免盲目刪除先前測試運行的現有結果。預設情況下,會保留最近 3 個暫存目錄,但可以使用 tmp_path_retention_counttmp_path_retention_policy 配置此行為。

  • 當使用 --basetemp 選項時(例如 pytest --basetemp=mydir),它將直接用作基本暫存目錄

    {basetemp}/{testname}/
    

    請注意,在這種情況下沒有保留功能:只會保留最近一次運行的結果。

    警告

    在每次測試運行之前,給定給 --basetemp 的目錄將被盲目清除,因此請確保僅將目錄用於此目的。

當使用 pytest-xdist 在本機上分發測試時,會注意自動為子進程配置 basetemp 目錄,以便所有暫存資料都落在每個測試運行的單個暫存目錄下。