pytest-csv-params: Testfall-Daten als »smarte Objekte«
Eigentlich sollte die Version 2 meines Pytest1-Plugins
pytest-csv-params keine
neuen Features mehr bekommen, da einige Ideen, die ich noch habe, sich nicht mit den derzeit unterstützten Pytest- und
Python-Versionen realisieren lassen. Entsprechend sollten sie erst mit dem nächsten Major-Release, welches als
»Breaking Change« die Einstellung des Supports für Python 3.10 und Pytest kleiner als 9 mitbringt, erscheinen.
Doch die Bereitstellung von Testfall-Daten als »smarte Objekte« lässt sich problemlos mit Python 3.10 und Pytest 8.4 realisieren. Und so ist die Funktion heute in die Version 2.3.0 eingeflossen.
Worum geht es?
Ähnlich der Bereitstellung von Testdaten als Dictionary2, ermöglicht die neue Funktion die Nutzung von Objekten zur Übergabe. Doch nicht nur das: Objekte lassen sich durch selbstdefinierte Factories erzeugen. Dieser Beitrag zeigt einige Beispiele und Use Cases.
Die Dokumentation der neuen Konfigurationsmöglichkeiten befindet sich an gewohnter Stelle .
Die gleichzeitige Nutzung der beiden Optionen parameters_as_object bzw. parameters_as_dictionary ist nicht möglich
und führt zu einer entsprechenden Exception.
Zwei grundsätzliche Konfigurationsmöglichkeiten
Für den Decorator-Parameter parameters_as_object gibt es zwei Konfigurationsmöglichkeiten:
- Einfach: Wert vom Typ
str– so wird einfach nur der Name des Parameters definiert, an den das Objekt übergeben werden soll. Das entspricht weitestgehend dem Verhalten, welches man bereits vom Parameterparameters_as_dictionarygewohnt ist. - Erweitert: Wert vom Typ
tuple[str, TestCaseDataObjectFactory]– damit wird zum einen der Name (wie oben) übergeben, zum anderen eine Factory-Methode vom TypTestCaseDataObjectFactory3, die neue Objekte vom TypTestCaseDataElementType4 erzeugt.
Die einfache Konfiguration
Bei der einfachen Konfiguration wird einfach nur der Name des Testfunktionsarguments übergeben. Der Name muss vom Typ
str sein. Ansonsten erfolgt eine entsprechende Exception.
1from typing import Any
2from pytest_csv_params.decorator import csv_params
3
4
5@csv_params(
6 data_file="/data/test-lib/cases/texts.csv",
7 parameters_as_object="test_data",
8)
9def test_texts(test_data: Any):
10 assert f"{test_data.text_a}:{test_data.text_b}" == test_data.text_c
Grundsätzlich können – wie auch bei der Nutzung von parameters_as_dictionary – alle weiteren Funktionen, wie
Data Casts5 oder Feldumbenennungen6 verwendet werden. Um das Beispiel einfach zu halten,
wurde in diesem Beispiel jedoch darauf verzichtet.
Die erweiterte Konfiguration
Die erweiterte Konfiguration ermöglicht die Verwendung von eigenen Factory-Methoden für die Erzeugung der Objekte, an denen die entsprechenden Werte registriert werden.
Die Factory-Methoden müssen Objekte liefern, die eine Instanz-Methode register_value implementieren, die zwei
Parameter key (Typ str) und value (Typ Any) akzeptiert. Diese Methode wird während der Parametrisierung
verwendet. So kann man allerlei eigene Anpassungen vornehmen. Das folgende Beispiel gibt einen Einblick anhand
dieser CSV-Datei:
1"#ID", "Animal", "Color"
2"A1", "Cat", "Blue"
3"A2", "Dog", "Green"
4"A3", "Mouse", "Yellow"
5"A4", "Bird", "Purple"
6"A5", "Cow", "Red"
Der folgende Python-Code definiert nicht nur den Test, sondern auch noch den Umgang mit Testdaten aus der
CSV-Datei. So sollen zum Beispiel String-Werte umgekehrt und in Großbuchstaben gewandelt werden, während die ID des
Testfalls sowie andere Datentypen unberührt bleiben. Außerdem soll jedem Objekt eine eindeutige UUID zugeordnet
werden. Als Factory-Methode wird direkt die Klasse TestDataObject verwendet:
1from os.path import join, dirname
2from typing import Any
3from uuid import uuid4, UUID
4
5from pytest_csv_params.decorator import csv_params
6from pytest_csv_params.object import TestCaseDataElementType
7
8
9class TestDataObject(TestCaseDataElementType):
10
11 def register_value(self, key: str, value: Any) -> None:
12 if value is not None and isinstance(value, str) and key != "tc_id":
13 setattr(self, key, (value[::-1]).upper())
14 return
15 setattr(self, key, value)
16
17 def __init__(self) -> None:
18 self._uuid = uuid4()
19 self.animal: str | None = None
20 self.color: str | None = None
21 self.tc_id: str | None = None
22
23
24@csv_params(
25 data_file=join(dirname(__file__), "test_data", "test1.csv"),
26 id_col="#ID",
27 reuse_id_col=True,
28 header_renames={
29 "#ID": "tc_id",
30 "Color": "color",
31 "Animal": "animal",
32 },
33 parameters_as_object=("tc_data_object", TestDataObject),
34)
35def test_with_object(tc_data_object: TestDataObject) -> None:
36 assert isinstance(tc_data_object._uuid, UUID)
37 assert tc_data_object.tc_id in ("A1", "A2", "A3", "A4", "A5")
38 assert isinstance(tc_data_object.color, str)
39 assert isinstance(tc_data_object.animal, str)
Entsprechend kommen in der Methode test_with_object nun solche Objekte an (hier im Beispiel für den ersten Testfall
aus der CSV-Datei):

Die zusätzlichen Felder, Umbenennungen und Werte-Anpassungen sind gut zu erkennen.
Fazit
Die Nutzung von parameters_as_object gerade in Verbindung mit dem Konfigurations-Tuple macht das Plugin
pytest-csv-params noch mächtiger. Durch die Möglichkeit, Klassen entsprechend zu definieren, kann man weit besser
von der eigenen IDE unterstützt werden, so dass bei Feldnamen werden Tippfehler vermieden werden können und man
komfortabler arbeiten kann.
Dieses Verhalten hat durchaus das Potenzial, für Version 3 die Standard-Variante zu werden.
Dieser Artikel wurde von einem Menschen geschrieben, anschließend mit Hilfe von KI korrigiert und teilweise umformuliert.
KI hat keinerlei Inhalte selbst erzeugt oder Fakten beigetragen.
-
Pytest ist ein sehr bekanntes und weit verbreitetes Test-Framework für Python. Siehe docs.pytest.org/en/stable/ . ↩︎
-
siehe Plugin-Dokumentation zum Decorator-Parameter
parameters_as_dictionary↩︎ -
Der Typ
TestCaseDataObjectFactoryentspricht einer Signatur vonCallable[[], TestCaseDataElementType]↩︎ -
Die von der Factory erzeugte Objektinstanzen müssen eine Methode
register_value(self, key: str, value: Any)implementieren ↩︎
Entwicklung Python Testing
Zuletzt geändert: 2026-10-13 21:17:12
