Verwendung temporärer Verzeichnisse und Dateien in Tests¶
Das tmp_path Fixture¶
Sie können das tmp_path Fixture verwenden, das ein für jede Testfunktion eindeutiges temporäres Verzeichnis bereitstellt.
tmp_path ist ein pathlib.Path Objekt. Hier ist ein Beispiel für die Testnutzung
# 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
Wenn Sie dies ausführen, würde der Test erfolgreich sein, mit Ausnahme der letzten Zeile assert 0, die wir verwenden, um Werte zu betrachten
$ pytest test_tmp_path.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-9.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 =============================
Standardmäßig behält pytest das temporäre Verzeichnis für die letzten 3 pytest Aufrufe bei. Gleichzeitige Aufrufe derselben Testfunktion werden durch Konfiguration des Basis-Temporärverzeichnisses, das für jeden gleichzeitigen Lauf eindeutig ist, unterstützt. Weitere Informationen finden Sie unter Temporäres Verzeichnisstandort und -aufbewahrung.
Das tmp_path_factory Fixture¶
Das tmp_path_factory ist ein Session-Scope Fixture, das verwendet werden kann, um beliebige temporäre Verzeichnisse aus jedem anderen Fixture oder Test zu erstellen.
Angenommen, Ihre Testsuite benötigt ein großes Bild auf der Festplatte, das prozedural generiert wird. Anstatt dasselbe Bild für jeden Test, der es verwendet, in sein eigenes tmp_path berechnet wird, können Sie es einmal pro Sitzung generieren, um Zeit zu sparen.
# 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
Weitere Informationen finden Sie in der tmp_path_factory API.
Die tmpdir und tmpdir_factory Fixtures¶
Die tmpdir und tmpdir_factory Fixtures sind ähnlich wie tmp_path und tmp_path_factory, verwenden jedoch/geben Legacy py.path.local Objekte anstelle von Standard pathlib.Path Objekten zurück.
Hinweis
Heutzutage ist es vorzuziehen, tmp_path und tmp_path_factory zu verwenden.
Um alte Codebasen zu modernisieren, kann man pytest mit deaktiviertem legacypath-Plugin ausführen.
pytest -p no:legacypath
Dadurch werden Fehler bei Tests mit Legacy-Pfaden ausgelöst. Dies kann auch dauerhaft als Teil des addopts Parameters in der Konfigurationsdatei festgelegt werden.
Weitere Informationen finden Sie in der tmpdir tmpdir_factory API.
Temporäres Verzeichnisstandort und -aufbewahrung¶
Die temporären Verzeichnisse, wie sie von den tmp_path und (jetzt veralteten) tmpdir Fixtures zurückgegeben werden, werden automatisch unter einem Basis-Temporärverzeichnis erstellt, in einer Struktur, die von der Option --basetemp abhängt.
Standardmäßig (wenn die Option
--basetempnicht gesetzt ist) folgen die temporären Verzeichnisse dieser Vorlage.{temproot}/pytest-of-{user}/pytest-{num}/{testname}/wobei
{temproot}das System-Temporärverzeichnis ist, wie vontempfile.gettempdir()bestimmt. Es kann durch die UmgebungsvariablePYTEST_DEBUG_TEMPROOTüberschrieben werden.{user}der Benutzername ist, der die Tests ausführt,{num}eine Zahl ist, die mit jedem Testlauf inkrementiert wird.{testname}eine bereinigte Version des Namens des aktuellen Tests ist.
Der automatisch inkrementierende Platzhalter
{num}bietet eine grundlegende Aufbewahrungsfunktion und vermeidet, dass bestehende Ergebnisse früherer Testläufe blind entfernt werden. Standardmäßig werden die letzten 3 temporären Verzeichnisse aufbewahrt, dieses Verhalten kann jedoch mittmp_path_retention_countundtmp_path_retention_policykonfiguriert werden.Wenn die Option
--basetempverwendet wird (z. B.pytest --basetemp=mydir), wird diese direkt als Basis-Temporärverzeichnis verwendet.{basetemp}/{testname}/Beachten Sie, dass in diesem Fall keine Aufbewahrungsfunktion vorhanden ist: Es werden nur die Ergebnisse des letzten Laufs beibehalten.
Warnung
Das an
--basetempübergebene Verzeichnis wird vor jedem Testlauf blind geleert. Stellen Sie daher sicher, dass Sie ein Verzeichnis nur für diesen Zweck verwenden.
Wenn Tests auf der lokalen Maschine mit pytest-xdist verteilt werden, wird darauf geachtet, automatisch ein basetemp Verzeichnis für die Unterprozesse zu konfigurieren, so dass alle temporären Daten unter einem einzigen temporären Verzeichnis pro Testlauf liegen.