使用自訂目錄收集器

預設情況下,pytest 使用 pytest.Package 收集具有 __init__.py 檔案的目錄,並使用 pytest.Dir 收集其他目錄。如果您想自訂目錄的收集方式,您可以編寫自己的 pytest.Directory 收集器,並使用 pytest_collect_directory 來掛鉤它。

目錄清單檔案的基本範例

假設您想自訂每個目錄的收集方式。這是一個 conftest.py 插件範例,允許目錄包含 manifest.json 檔案,該檔案定義了目錄的收集方式。在此範例中,僅支援簡單的檔案列表,但是您可以想像添加其他鍵,例如排除項和 globs。

# content of conftest.py
from __future__ import annotations

import json

import pytest


class ManifestDirectory(pytest.Directory):
    def collect(self):
        # The standard pytest behavior is to loop over all `test_*.py` files and
        # call `pytest_collect_file` on each file. This collector instead reads
        # the `manifest.json` file and only calls `pytest_collect_file` for the
        # files defined there.
        manifest_path = self.path / "manifest.json"
        manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
        ihook = self.ihook
        for file in manifest["files"]:
            yield from ihook.pytest_collect_file(
                file_path=self.path / file, parent=self
            )


@pytest.hookimpl
def pytest_collect_directory(path, parent):
    # Use our custom collector for directories containing a `manifest.json` file.
    if path.joinpath("manifest.json").is_file():
        return ManifestDirectory.from_parent(parent=parent, path=path)
    # Otherwise fallback to the standard behavior.
    return None

您可以創建一個 manifest.json 檔案和一些測試檔案

{
    "files": [
        "test_first.py",
        "test_second.py"
    ]
}
# content of test_first.py
from __future__ import annotations


def test_1():
    pass
# content of test_second.py
from __future__ import annotations


def test_2():
    pass
# content of test_third.py
from __future__ import annotations


def test_3():
    pass

現在您可以執行測試規範

customdirectory $ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project/customdirectory
configfile: pytest.ini
collected 2 items

tests/test_first.py .                                                [ 50%]
tests/test_second.py .                                               [100%]

============================ 2 passed in 0.12s =============================

請注意,test_three.py 沒有被執行,因為它沒有在清單中列出。

您可以驗證您的自訂收集器是否出現在收集樹中

customdirectory $ pytest --collect-only
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project/customdirectory
configfile: pytest.ini
collected 2 items

<Dir customdirectory>
  <ManifestDirectory tests>
    <Module test_first.py>
      <Function test_1>
    <Module test_second.py>
      <Function test_2>

======================== 2 tests collected in 0.12s ========================