Verwendung eines benutzerdefinierten Verzeichnissammlers¶
Standardmäßig sammelt pytest Verzeichnisse mit pytest.Package für Verzeichnisse mit __init__.py Dateien und pytest.Dir für andere Verzeichnisse. Wenn Sie anpassen möchten, wie ein Verzeichnis gesammelt wird, können Sie Ihren eigenen pytest.Directory Collector schreiben und pytest_collect_directory verwenden, um ihn zu verknüpfen.
Ein einfaches Beispiel für eine Verzeichnis-Manifestdatei¶
Angenommen, Sie möchten anpassen, wie die Sammlung pro Verzeichnis durchgeführt wird. Hier ist ein Beispiel für ein conftest.py Plugin, das es Verzeichnissen ermöglicht, eine manifest.json Datei zu enthalten, die definiert, wie die Sammlung für das Verzeichnis durchgeführt werden soll. In diesem Beispiel wird nur eine einfache Liste von Dateien unterstützt, Sie können sich jedoch vorstellen, andere Schlüssel wie Ausschlüsse und Globs hinzuzufügen.
# 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
Sie können eine manifest.json Datei und einige Testdateien erstellen
{
"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
Und Sie können nun die Testspezifikation ausführen
customdirectory $ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-9.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 =============================
Beachten Sie, dass test_three.py nicht ausgeführt wurde, da es nicht im Manifest aufgeführt ist.
Sie können überprüfen, ob Ihr benutzerdefinierter Collector im Sammlungsprotokoll angezeigt wird
customdirectory $ pytest --collect-only
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-9.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 ========================