テストで一時ディレクトリとファイルを使用する方法

tmp_path フィクスチャ

tmp_path フィクスチャを使用すると、各テスト関数に固有の一時ディレクトリが提供されます。

tmp_pathpathlib.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 呼び出しのために一時ディレクトリを保持します。 同じテスト関数の同時呼び出しは、各同時実行のためにベースの一時ディレクトリを一意に設定することでサポートされます。 詳細は temporary directory location and retention を参照してください。

tmp_path_factory フィクスチャ

tmp_path_factory はセッションスコープのフィクスチャで、他のフィクスチャやテストから任意の一時ディレクトリを作成するために使用できます。

例えば、テストスイートがディスク上に大きな画像を必要とし、それが手続き的に生成されるとします。 同じ画像を各テストで tmp_path に計算する代わりに、セッションごとに一度生成して時間を節約できます:

# 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 を参照してください。

tmpdir および tmpdir_factory フィクスチャ

tmpdir および tmpdir_factory フィクスチャは tmp_path および tmp_path_factory に似ていますが、標準の pathlib.Path オブジェクトではなく、レガシーな py.path.local オブジェクトを使用/返します。

注釈

最近では、tmp_path および tmp_path_factory を使用することが推奨されています。

古いコードベースを最新化するために、legacypath プラグインを無効にして pytest を実行できます:

pytest -p no:legacypath

これにより、レガシーパスを使用するテストでエラーが発生します。 また、設定ファイルの addopts パラメータの一部として永続的に設定することもできます。

詳細は tmpdir tmpdir_factory API を参照してください。

一時ディレクトリの場所と保持

tmp_path および (現在は非推奨の) tmpdir フィクスチャによって返される一時ディレクトリは、--basetemp オプションに依存する構造で、ベースの一時ディレクトリの下に自動的に作成されます:

  • デフォルトでは (--basetemp オプションが設定されていない場合) 、一時ディレクトリは次のテンプレートに従います:

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

    ここで:

    • {temproot}tempfile.gettempdir() によって決定されるシステムの一時ディレクトリです。 これは PYTEST_DEBUG_TEMPROOT 環境変数で上書きできます。

    • {user} はテストを実行しているユーザー名です。

    • {num} は各テストスイートの実行ごとに増加する番号です。

    • {testname}現在のテストの名前 のサニタイズされたバージョンです。

    自動インクリメントされる {num} プレースホルダーは基本的な保持機能を提供し、以前のテスト実行の既存の結果が盲目的に削除されるのを防ぎます。 デフォルトでは、最後の 3 つの一時ディレクトリが保持されますが、この動作は tmp_path_retention_count および tmp_path_retention_policy で構成できます。

  • --basetemp オプションが使用される場合 (例:pytest --basetemp=mydir) 、それがベースの一時ディレクトリとして直接使用されます:

    {basetemp}/{testname}/
    

    この場合、保持機能はありません。 最新の実行結果のみが保持されます。

    警告

    --basetemp に指定されたディレクトリは、各テスト実行前に盲目的にクリアされるため、その目的のみに使用するディレクトリを使用してください。

pytest-xdist を使用してローカルマシンでテストを分散する場合、すべての一時データが単一のテスト実行ごとの一時ディレクトリの下に配置されるように、サブプロセスの basetemp ディレクトリが自動的に構成されるように注意が払われます。