Repository: bo4e/BO4E-python (language: python)

Issue:
Custom Fields aka `zusatzAttribute` für alle BO's
Für eine schnelle und kurzfristige Umsetzung spezieller Use Case sollte in allen BO's Custom Field eingeführt werden. So können Systempartner/-häuser für ein Projekt/Use Case die flexible, kurzfristige und schnelle Übergaben von Werten vereinbaren. Diese können das später in den Standard übernommen werden falls dauerhaft benötigt.


Discussion / hints:

Fix patch:
diff --git a/.vscode/settings.json b/.vscode/settings.json
index ed9af3c1d..523e5c784 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -5,6 +5,4 @@
     "python.testing.pytestArgs": [
         "tests"
     ],
-    "python.linting.pylintEnabled": true,
-    "python.formatting.provider": "black"
 }
diff --git a/docs/conf.py b/docs/conf.py
index 5c3afe211..a2a362704 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -204,8 +204,8 @@
 # ambiguous definitions of the classes. It would lead to the following error:
 #
 # docstring of bo4e.bo.angebot.Angebot.externe_referenzen:1:
-# more than one target found for cross-reference 'ExterneReferenz':
-# bo4e.ExterneReferenz, bo4e.com.externereferenz.ExterneReferenz
+# more than one target found for cross-reference 'ZusatzAttribute':
+# bo4e.ZusatzAttribute, bo4e.com.zusatzattribute.ZusatzAttribute
 #
 # This flag is not well documented.
 # https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#confval-autodoc_default_options
diff --git a/src/bo4e/__init__.py b/src/bo4e/__init__.py
index 3d132ae4a..dbd509272 100644
--- a/src/bo4e/__init__.py
+++ b/src/bo4e/__init__.py
@@ -54,7 +54,6 @@
     "Dienstleistung",
     "Energieherkunft",
     "Energiemix",
-    "ExterneReferenz",
     "Fremdkostenblock",
     "Fremdkostenposition",
     "Geokoordinaten",
@@ -182,6 +181,7 @@
     "Zaehlergroesse",
     "Zaehlertyp",
     "ZaehlertypSpezifikation",
+    "ZusatzAttribut",
     "__version__",
 ]
 
@@ -234,7 +234,6 @@
 from .com.dienstleistung import Dienstleistung
 from .com.energieherkunft import Energieherkunft
 from .com.energiemix import Energiemix
-from .com.externereferenz import ExterneReferenz
 from .com.fremdkostenblock import Fremdkostenblock
 from .com.fremdkostenposition import Fremdkostenposition
 from .com.geokoordinaten import Geokoordinaten
@@ -365,3 +364,4 @@
 from .enum.zaehlertyp import Zaehlertyp
 from .enum.zaehlertypspezifikation import ZaehlertypSpezifikation
 from .version import __version__
+from .zusatzattribut import ZusatzAttribut
diff --git a/src/bo4e/bo/ansprechpartner.py b/src/bo4e/bo/ansprechpartner.py
index 6cb8ce27c..6ae01713e 100644
--- a/src/bo4e/bo/ansprechpartner.py
+++ b/src/bo4e/bo/ansprechpartner.py
@@ -32,25 +32,30 @@ class Ansprechpartner(Geschaeftsobjekt):
     """
 
     typ: Annotated[Optional[Typ], Field(alias="_typ")] = Typ.ANSPRECHPARTNER
-    nachname: Optional[str] = None  #: Nachname (Familienname) des Ansprechpartners
-    geschaeftspartner: Optional[
-        Geschaeftspartner
-    ] = None  #: Der Geschäftspartner, für den dieser Ansprechpartner modelliert wird
 
-    anrede: Optional[Anrede] = None  #: Mögliche Anrede des Ansprechpartners
     individuelle_anrede: Optional[str] = None
     """
     Im Falle einer nicht standardisierten Anrede kann hier eine frei definierbare Anrede vorgegeben werden.
     Beispiel: "Sehr geehrte Frau Müller, sehr geehrter Herr Dr. Müller"
     """
-
+    anrede: Optional[Anrede] = None  #: Mögliche Anrede des Ansprechpartners
     titel: Optional[Titel] = None  #: Möglicher Titel des Ansprechpartners
     vorname: Optional[str] = None  #: Vorname des Ansprechpartners
+    nachname: Optional[str] = None  #: Nachname (Familienname) des Ansprechpartners
+
     e_mail_adresse: Optional[str] = None  #: E-Mail Adresse
-    kommentar: Optional[str] = None  #: Weitere Informationen zum Ansprechpartner
+
+    geschaeftspartner: Optional[
+        Geschaeftspartner
+    ] = None  #: Der Geschäftspartner, für den dieser Ansprechpartner modelliert wird
+
     #: Adresse des Ansprechpartners, falls diese von der Adresse des Geschäftspartners abweicht
     adresse: Optional[Adresse] = None
+
     #: Liste der Telefonnummern, unter denen der Ansprechpartner erreichbar ist
     rufnummer: Optional[Rufnummer] = None  # todo: make this a list and rename to rufnummern
+
+    kommentar: Optional[str] = None  #: Weitere Informationen zum Ansprechpartner
+
     #: Liste der Abteilungen und Zuständigkeiten des Ansprechpartners
     zustaendigkeit: Optional[Zustaendigkeit] = None  # todo: make this a list and rename to "zustaendigkeiten"
diff --git a/src/bo4e/bo/geschaeftsobjekt.py b/src/bo4e/bo/geschaeftsobjekt.py
index 72e33ad11..6e6832134 100644
--- a/src/bo4e/bo/geschaeftsobjekt.py
+++ b/src/bo4e/bo/geschaeftsobjekt.py
@@ -8,8 +8,8 @@
 from pydantic import BaseModel, ConfigDict, Field
 
 from bo4e.version import __version__
+from bo4e.zusatzattribut import ZusatzAttribut
 
-from ..com.externereferenz import ExterneReferenz
 from ..enum.typ import Typ
 
 # pylint: disable=too-few-public-methods
@@ -37,7 +37,8 @@ class Geschaeftsobjekt(BaseModel):
     typ: Annotated[Optional[Typ], Field(alias="_typ")] = Typ.GESCHAEFTSOBJEKT  #: Der Typ des Geschäftsobjektes
     # bo_typ is used as discriminator f.e. for databases or deserialization
 
-    externe_referenzen: Optional[list[ExterneReferenz]] = None
+    zusatz_attribute: Optional[list[ZusatzAttribut]] = None
+    # zusatz_attribute is a list of ZusatzAttribut objects which are used to store additional information
 
     # Python internal: The field is not named '_id' because leading underscores are not allowed in pydantic field names.
     # NameError: Fields must not use names with leading underscores; e.g., use 'id' instead of '_id'.
diff --git a/src/bo4e/com/com.py b/src/bo4e/com/com.py
index 7d814fca4..bd939bb83 100644
--- a/src/bo4e/com/com.py
+++ b/src/bo4e/com/com.py
@@ -11,6 +11,7 @@
 from pydantic import BaseModel, ConfigDict, Field
 
 from bo4e.version import __version__
+from bo4e.zusatzattribut import ZusatzAttribut
 
 
 # pylint: disable=too-few-public-methods
@@ -40,6 +41,8 @@ class COM(BaseModel):
     Z.B. könnten hier UUIDs aus einer Datenbank stehen oder URLs zu einem Backend-System.
     """
 
+    zusatz_attribute: Optional[list[ZusatzAttribut]] = None
+
     # pylint: disable=duplicate-code
     model_config = ConfigDict(
         alias_generator=camelize,
diff --git a/src/bo4e/com/externereferenz.py b/src/bo4e/zusatzattribut.py
similarity index 50%
rename from src/bo4e/com/externereferenz.py
rename to src/bo4e/zusatzattribut.py
index f1b62155f..b125bddbb 100644
--- a/src/bo4e/com/externereferenz.py
+++ b/src/bo4e/zusatzattribut.py
@@ -2,14 +2,14 @@
 Contains ExterenzeReferenz class
 and corresponding marshmallow schema for de-/serialization
 """
-from typing import Optional
+from typing import Any, Optional
 
-from .com import COM
+from pydantic import BaseModel
 
 
 # pylint: disable=too-few-public-methods
 #
-class ExterneReferenz(COM):
+class ZusatzAttribut(BaseModel):
     """
     Viele Datenobjekte weisen in unterschiedlichen Systemen eine eindeutige ID (Kundennummer, GP-Nummer etc.) auf.
     Beim Austausch von Datenobjekten zwischen verschiedenen Systemen ist es daher hilfreich,
@@ -17,14 +17,12 @@ class ExterneReferenz(COM):
 
     .. raw:: html
 
-        <object data="../_static/images/bo4e/com/ExterneReferenz.svg" type="image/svg+xml"></object>
+        <object data="../_static/images/bo4e/com/ZusatzAttribut.svg" type="image/svg+xml"></object>
 
     .. HINT::
-        `ExterneReferenz JSON Schema <https://json-schema.app/view/%23?url=https://raw.githubusercontent.com/Hochfrequenz/BO4E-python/main/json_schemas/com/ExterneReferenz.json>`_
+        `ZusatzAttribute JSON Schema <https://json-schema.app/view/%23?url=https://raw.githubusercontent.com/Hochfrequenz/BO4E-python/main/json_schemas/com/ZusatzAttribute.json>`_
 
     """
 
-    ex_ref_name: Optional[
-        str
-    ] = None  #: Bezeichnung der externen Referenz (z.B. "microservice xyz" oder "SAP CRM GP-Nummer")
-    ex_ref_wert: Optional[str] = None  #: Wert der externen Referenz (z.B. "123456"; "4711")
+    name: Optional[str]  #: Bezeichnung der externen Referenz (z.B. "microservice xyz" oder "SAP CRM GP-Nummer")
+    wert: Any  #: Wert der externen Referenz (z.B. "123456"; "4711")


Test patch:
diff --git a/tests/test_adresse.py b/tests/test_adresse.py
index 0d527a46e..620984e72 100644
--- a/tests/test_adresse.py
+++ b/tests/test_adresse.py
@@ -1,148 +1,17 @@
 import uuid
-from pathlib import Path
-from typing import Dict, Optional
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import Adresse, Landescode
+from tests.serialization_helper import assert_serialization_roundtrip
 from tests.utils import parse_file
 
-# import pydantic
-
-# can be imported by other tests
-example_adresse = Adresse(
-    ort="Grünwald",
-    landescode=Landescode.DE,  # type: ignore[attr-defined]
-    hausnummer="27A",
-    strasse="Nördliche Münchner Straße",
-    postleitzahl="82031",
-)
-
 
 class TestAddress:
-    def test_serialization_strasse(self) -> None:
-        """
-        Test serialization with strasse und hausnummer
-        and default value of landescode
-        """
-
-        address_test_data = parse_file(
-            Adresse, "./tests/test_data/test_data_adresse/test_data_adresse_only_required_fields.json"
-        )
-
-        address_dict = address_test_data.model_dump_json(by_alias=True)
-
-        assert "Nördliche Münchner Straße" in address_dict
-        assert "27A" in address_dict
-        assert "82031" in address_dict
-        assert "DE" in address_dict
-
-        deserialized_address = Adresse.model_validate_json(address_dict)
-
-        assert isinstance(deserialized_address, Adresse)
-        assert deserialized_address.strasse == "Nördliche Münchner Straße"
-        assert deserialized_address.hausnummer == "27A"
-        assert deserialized_address.postleitzahl == "82031"
-        assert deserialized_address.landescode == Landescode.DE  # type: ignore[attr-defined]
-
-    def test_serialization_only_postfach(self) -> None:
-        """Test serialization with postfach"""
-        address_test_data = {
-            "postleitzahl": "82031",
-            "ort": "Grünwald",
-            "postfach": "10 64 38",
-        }
-
-        a = Adresse(
-            postleitzahl=address_test_data["postleitzahl"],
-            ort=address_test_data["ort"],
-            postfach=address_test_data["postfach"],
-        )
-
-        address_json = a.model_dump_json(by_alias=True)
-
-        assert "10 64 38" in address_json
-        assert "82031" in address_json
-        assert "DE" in address_json
-
-        deserialized_address = Adresse.model_validate_json(address_json)
-
-        assert isinstance(deserialized_address, Adresse)
-        assert deserialized_address.postfach == "10 64 38"
-        assert deserialized_address.postleitzahl == "82031"
-        assert deserialized_address.landescode == Landescode.DE  # type: ignore[attr-defined]
-
-    def test_serialization_only_required_fields(self) -> None:
-        """Test serialization with just postleitzahl und ort"""
-        address_test_data = {
-            "postleitzahl": "82031",
-            "ort": "Grünwald",
-        }
-
-        a = Adresse(
-            postleitzahl=address_test_data["postleitzahl"],
-            ort=address_test_data["ort"],
-        )
-
-        address_json = a.model_dump_json(by_alias=True)
-
-        assert "Grünwald" in address_json
-        assert "82031" in address_json
-
-        deserialized_address = Adresse.model_validate_json(address_json)
-
-        assert isinstance(deserialized_address, Adresse)
-        assert deserialized_address.ort == "Grünwald"
-        assert deserialized_address.postleitzahl == "82031"
-
-    def test_serialization_only_required_fields_landescode_AT(self) -> None:
-        address_test_data = parse_file(
-            Adresse, "./tests/test_data/test_data_adresse/test_data_adresse_only_required_fields.json"
-        )
-        address_test_data.landescode = Landescode.AT  # type: ignore[attr-defined]
-
-        address_json = address_test_data.model_dump_json(by_alias=True)
-        deserialized_address = Adresse.model_validate_json(address_json)
-
-        assert deserialized_address.landescode == Landescode.AT  # type: ignore[attr-defined]
-
-    def test_deserialization(self) -> None:
-        json_string = r"""{"strasse":"Getreidegasse",
-                 "hausnummer":"9",
-                 "ort":"Salzburg",
-                 "postleitzahl":"5020",
-                 "landescode":"AT"}"""
-
-        a: Adresse = Adresse.model_validate_json(json_string)
-        assert a.landescode is Landescode.AT  # type: ignore[attr-defined]
-
-    def test_serialization_of_non_german_address(self) -> None:
-        """
-        Minimal working example
-        :return:
-        """
-        a = Adresse(
-            postleitzahl="6413", ort="Wildermieming", strasse="Gerhardhof", hausnummer="1", landescode=Landescode.AT  # type: ignore[attr-defined]
-        )
-        assert a.landescode == Landescode.AT  # type: ignore[attr-defined]
-        serialized_address = a.model_dump_json(by_alias=True)
-        assert '"AT"' in serialized_address
-        deserialized_address = Adresse.model_validate_json(serialized_address)
-        assert deserialized_address.landescode == Landescode.AT  # type: ignore[attr-defined]
-
     @pytest.mark.parametrize(
-        "address_json, adresse",
+        "adresse",
         [
             pytest.param(
-                r"""{"postleitzahl": "12345",
-                    "ort": "ISS spacestation",
-                    "strasse": "Milky Way",
-                    "hausnummer": "42",
-                    "landescode": "FR",
-                    "adresszusatz": "to whom it may concern",
-                    "co_ergaenzung": "you will find me",
-                    "ortsteil": "Mitte"}""",
                 Adresse(
                     postleitzahl="12345",
                     ort="ISS spacestation",
@@ -153,38 +22,58 @@ def test_serialization_of_non_german_address(self) -> None:
                     co_ergaenzung="you will find me",
                     ortsteil="Mitte",
                 ),
-            )
+            ),
+            pytest.param(
+                parse_file(Adresse, "./tests/test_data/test_data_adresse/test_data_adresse_only_required_fields.json")
+            ),
+            pytest.param(
+                Adresse(
+                    postleitzahl="82031",
+                    ort="Grünwald",
+                    postfach="10 64 38",
+                ),
+            ),
+            pytest.param(
+                Adresse(
+                    postleitzahl="82031",
+                    ort="Grünwald",
+                ),
+            ),
+            pytest.param(
+                parse_file(Adresse, "./tests/test_data/test_data_adresse/test_data_adresse_only_required_fields.json")
+            ),
+            pytest.param(
+                Adresse.model_validate_json(
+                    r"""{"strasse":"Getreidegasse",
+                 "hausnummer":"9",
+                 "ort":"Salzburg",
+                 "postleitzahl":"5020",
+                 "landescode":"AT"}"""
+                )
+            ),
+            pytest.param(
+                Adresse(
+                    postleitzahl="6413",
+                    ort="Wildermieming",
+                    strasse="Gerhardhof",
+                    hausnummer="1",
+                    landescode=Landescode.AT,  # type: ignore[attr-defined]
+                ),
+            ),
+            pytest.param(
+                Adresse(
+                    id=str(uuid.uuid4()),
+                    ort="Grünwald",
+                    landescode=Landescode.DE,  # type: ignore[attr-defined]
+                    hausnummer="27A",
+                    strasse="Nördliche Münchner Straße",
+                    postleitzahl="82031",
+                ),
+            ),
         ],
     )
-    def test_serialization_with_all_possible_fields(self, address_json: str, adresse: Adresse) -> None:
+    def test_serialization_roundtrip(self, adresse: Adresse) -> None:
         """
-        Test serialization with all required and optional attributes
+        Test de-/serialisation of Adresse.
         """
-
-        serialized_address = adresse.model_dump_json(by_alias=True)
-
-        assert "ISS spacestation" in serialized_address
-        assert "12345" in serialized_address
-        assert "Milky Way" in serialized_address
-        assert "42" in serialized_address
-        assert "FR" in serialized_address
-        assert "to whom it may concern" in serialized_address
-        assert "you will find me" in serialized_address
-        assert "Mitte" in serialized_address
-
-        deserialized_address = Adresse.model_validate_json(address_json)
-
-        assert deserialized_address == adresse
-
-    def test_id(self) -> None:
-        adresse = Adresse(
-            id=str(uuid.uuid4()),
-            ort="Grünwald",
-            landescode=Landescode.DE,  # type: ignore[attr-defined]
-            hausnummer="27A",
-            strasse="Nördliche Münchner Straße",
-            postleitzahl="82031",
-        )
-        adresse_json = adresse.model_dump(by_alias=True)
-        assert "_id" in adresse_json, "The json serialization shall contain the leading underscore"
-        assert Adresse.model_validate(adresse_json) == adresse
+        assert_serialization_roundtrip(adresse)
diff --git a/tests/test_angebot.py b/tests/test_angebot.py
index fd26131ae..af6cef756 100644
--- a/tests/test_angebot.py
+++ b/tests/test_angebot.py
@@ -1,12 +1,9 @@
 from datetime import datetime, timezone
 
 import pytest
-from pydantic import ValidationError
 
-from bo4e import Angebot, Ansprechpartner, Geschaeftspartner, Geschaeftspartnerrolle, Sparte
+from bo4e import Angebot, Ansprechpartner, Geschaeftspartner, Sparte
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_adresse import example_adresse
-from tests.test_angebotsvariante import example_angebotsvariante
 
 
 class TestAngebot:
@@ -20,65 +17,18 @@ class TestAngebot:
                     angebotsdatum=datetime(2020, 1, 1, tzinfo=timezone.utc),
                     sparte=Sparte.GAS,
                     bindefrist=datetime(2019, 3, 2, tzinfo=timezone.utc),
-                    angebotsgeber=Geschaeftspartner(
-                        name1="Batman",
-                        ist_gewerbe=True,
-                        geschaeftspartnerrolle=[Geschaeftspartnerrolle.LIEFERANT],
-                        partneradresse=example_adresse,
-                    ),
-                    angebotsnehmer=Geschaeftspartner(
-                        name1="Joker",
-                        ist_gewerbe=False,
-                        geschaeftspartnerrolle=[Geschaeftspartnerrolle.KUNDE],
-                        partneradresse=example_adresse,
-                    ),
-                    unterzeichner_angebotsnehmer=Ansprechpartner(
-                        nachname="Titans",
-                        geschaeftspartner=Geschaeftspartner(
-                            name1="Wonderwoman",
-                            ist_gewerbe=False,
-                            geschaeftspartnerrolle=[Geschaeftspartnerrolle.DIENSTLEISTER],
-                            partneradresse=example_adresse,
-                        ),
-                    ),
-                    unterzeichner_angebotsgeber=Ansprechpartner(
-                        nachname="Titans",
-                        geschaeftspartner=Geschaeftspartner(
-                            name1="Robin",
-                            ist_gewerbe=False,
-                            geschaeftspartnerrolle=[Geschaeftspartnerrolle.KUNDE],
-                            partneradresse=example_adresse,
-                        ),
-                    ),
-                    varianten=[example_angebotsvariante],
+                    angebotsgeber=Geschaeftspartner(),
+                    angebotsnehmer=Geschaeftspartner(),
+                    unterzeichner_angebotsnehmer=Ansprechpartner(),
+                    unterzeichner_angebotsgeber=Ansprechpartner(),
+                    varianten=[],
                 ),
-                id="required and optional attributes",
-            ),
-            pytest.param(
-                Angebot(
-                    angebotsnummer="271828",
-                    angebotsdatum=datetime(2020, 1, 1, tzinfo=timezone.utc),
-                    sparte=Sparte.GAS,
-                    angebotsgeber=Geschaeftspartner(
-                        name1="Batman",
-                        ist_gewerbe=True,
-                        geschaeftspartnerrolle=[Geschaeftspartnerrolle.LIEFERANT],
-                        partneradresse=example_adresse,
-                    ),
-                    angebotsnehmer=Geschaeftspartner(
-                        name1="Joker",
-                        ist_gewerbe=False,
-                        geschaeftspartnerrolle=[Geschaeftspartnerrolle.KUNDE],
-                        partneradresse=example_adresse,
-                    ),
-                    varianten=[example_angebotsvariante],
-                ),
-                id="required attributes",
+                id="all attributes at first level",
             ),
         ],
     )
     def test_serialization_roundtrip(self, angebot: Angebot) -> None:
         """
-        Test de-/serialisation
+        Test de-/serialisation of Angebot
         """
         assert_serialization_roundtrip(angebot)
diff --git a/tests/test_angebotsposition.py b/tests/test_angebotsposition.py
index e32b61500..f2d915cc7 100644
--- a/tests/test_angebotsposition.py
+++ b/tests/test_angebotsposition.py
@@ -1,47 +1,25 @@
-from decimal import Decimal
-from typing import Any, Dict
-
 import pytest
-from pydantic import ValidationError
 
-from bo4e import Angebotsposition, Betrag, Menge, Mengeneinheit, Preis, Waehrungscode, Waehrungseinheit
+from bo4e import Angebotsposition, Betrag, Menge, Preis
 from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestAngebotsposition:
     @pytest.mark.parametrize(
-        "ap, expected_json_dict",
+        "ap",
         [
             pytest.param(
                 Angebotsposition(
-                    positionsmenge=Menge(wert=Decimal(4000), einheit=Mengeneinheit.KWH),
-                    positionspreis=Preis(
-                        wert=Decimal(0.2456), einheit=Waehrungseinheit.EUR, bezugswert=Mengeneinheit.KWH
-                    ),
-                    positionskosten=Betrag(
-                        waehrung=Waehrungscode.EUR,
-                        wert=Decimal(98240),
-                    ),
+                    positionsmenge=Menge(),
+                    positionspreis=Preis(),
+                    positionskosten=Betrag(),
                     positionsbezeichnung="Beispielangebotsposition",
                 ),
-                {
-                    "positionsbezeichnung": "Beispielangebotsposition",
-                    "positionsmenge": {"wert": Decimal("4000"), "einheit": Mengeneinheit.KWH, "_id": None},
-                    "positionskosten": {"waehrung": Waehrungseinheit.EUR, "wert": Decimal("98240"), "_id": None},
-                    "positionspreis": {
-                        "bezugswert": Mengeneinheit.KWH,
-                        "status": None,
-                        "wert": Decimal("0.2456000000000000127453603226967970840632915496826171875"),
-                        "einheit": Waehrungseinheit.EUR,
-                        "_id": None,
-                    },
-                    "_id": None,
-                },
             ),
         ],
     )
-    def test_serialization_roundtrip(self, ap: Angebotsposition, expected_json_dict: Dict[str, Any]) -> None:
+    def test_serialization_roundtrip(self, ap: Angebotsposition) -> None:
         """
         Test de-/serialisation of Regionskriterium with minimal attributes.
         """
-        assert_serialization_roundtrip(ap, expected_json_dict)
+        assert_serialization_roundtrip(ap)
diff --git a/tests/test_angebotsteil.py b/tests/test_angebotsteil.py
index b86de39f8..841de0abc 100644
--- a/tests/test_angebotsteil.py
+++ b/tests/test_angebotsteil.py
@@ -1,202 +1,28 @@
-from datetime import datetime, timezone
-from decimal import Decimal
-from typing import Any, Dict
-
 import pytest
-from pydantic import ValidationError
 
-from bo4e import (
-    Adresse,
-    Angebotsposition,
-    Angebotsteil,
-    Betrag,
-    Bilanzierungsmethode,
-    Energierichtung,
-    Landescode,
-    Marktlokation,
-    Menge,
-    Mengeneinheit,
-    Netzebene,
-    Preis,
-    Sparte,
-    Typ,
-    Waehrungscode,
-    Waehrungseinheit,
-    Zeitraum,
-)
+from bo4e import Angebotsposition, Angebotsteil, Betrag, Marktlokation, Menge, Zeitraum
 from tests.serialization_helper import assert_serialization_roundtrip
 
-example_angebotsteil: Angebotsteil = Angebotsteil(
-    positionen=[
-        Angebotsposition(
-            positionsbezeichnung="teststring",
-            positionsmenge=Menge(wert=Decimal(4000), einheit=Mengeneinheit.KWH),
-            positionspreis=Preis(wert=Decimal(0.2456), einheit=Waehrungseinheit.EUR, bezugswert=Mengeneinheit.KWH),
-            positionskosten=Betrag(
-                waehrung=Waehrungscode.EUR,
-                wert=Decimal(98240),
-            ),
-        )
-    ],
-)
-
-example_angebotsteil_json = {
-    "positionen": [
-        {
-            "positionsbezeichnung": "teststring",
-            "positionsmenge": {"wert": Decimal("4000"), "einheit": Mengeneinheit.KWH, "_id": None},
-            "positionskosten": {"waehrung": Waehrungseinheit.EUR, "wert": Decimal("98240"), "_id": None},
-            "positionspreis": {
-                "bezugswert": Mengeneinheit.KWH,
-                "status": None,
-                "wert": Decimal("0.2456000000000000127453603226967970840632915496826171875"),
-                "einheit": Waehrungseinheit.EUR,
-                "_id": None,
-            },
-            "_id": None,
-        },
-    ],
-    "anfrageSubreferenz": None,
-    "lieferstellenangebotsteil": None,
-    "gesamtmengeangebotsteil": None,
-    "gesamtkostenangebotsteil": None,
-    "lieferzeitraum": None,
-    "_id": None,
-}
-
 
 class TestAngebotsteil:
     @pytest.mark.parametrize(
-        "angebotsteil, expected_json_dict",
+        "angebotsteil",
         [
             pytest.param(
                 Angebotsteil(
-                    positionen=[
-                        Angebotsposition(
-                            positionsbezeichnung="testtring",
-                            positionsmenge=Menge(wert=Decimal(4000), einheit=Mengeneinheit.KWH),
-                            positionspreis=Preis(
-                                wert=Decimal(0.2456), einheit=Waehrungseinheit.EUR, bezugswert=Mengeneinheit.KWH
-                            ),
-                            positionskosten=Betrag(
-                                waehrung=Waehrungscode.EUR,
-                                wert=Decimal(98240),
-                            ),
-                        )
-                    ],
+                    positionen=[Angebotsposition()],
                     anfrage_subreferenz="teststring",
-                    lieferstellenangebotsteil=[
-                        Marktlokation(
-                            marktlokations_id="51238696781",
-                            sparte=Sparte.GAS,
-                            lokationsadresse=Adresse(
-                                postleitzahl="82031",
-                                ort="Grünwald",
-                                hausnummer="27A",
-                                strasse="Nördliche Münchner Straße",
-                            ),
-                            energierichtung=Energierichtung.EINSP,
-                            bilanzierungsmethode=Bilanzierungsmethode.PAUSCHAL,
-                            ist_unterbrechbar=True,
-                            netzebene=Netzebene.NSP,
-                        )
-                    ],
-                    gesamtmengeangebotsteil=Menge(wert=Decimal(4000), einheit=Mengeneinheit.KWH),
-                    gesamtkostenangebotsteil=Betrag(
-                        waehrung=Waehrungscode.EUR,
-                        wert=Decimal(98240),
-                    ),
-                    lieferzeitraum=Zeitraum(
-                        startdatum=datetime(2020, 1, 1, tzinfo=timezone.utc),
-                        enddatum=datetime(2020, 4, 1, tzinfo=timezone.utc),
-                    ),
+                    lieferstellenangebotsteil=[Marktlokation()],
+                    gesamtmengeangebotsteil=Menge(),
+                    gesamtkostenangebotsteil=Betrag(),
+                    lieferzeitraum=Zeitraum(),
                 ),
-                {
-                    "positionen": [
-                        {
-                            "positionsbezeichnung": "testtring",
-                            "positionsmenge": {"wert": Decimal("4000"), "einheit": Mengeneinheit.KWH, "_id": None},
-                            "positionskosten": {
-                                "waehrung": Waehrungseinheit.EUR,
-                                "wert": Decimal("98240"),
-                                "_id": None,
-                            },
-                            "positionspreis": {
-                                "bezugswert": Mengeneinheit.KWH,
-                                "status": None,
-                                "wert": Decimal("0.2456000000000000127453603226967970840632915496826171875"),
-                                "einheit": Waehrungseinheit.EUR,
-                                "_id": None,
-                            },
-                            "_id": None,
-                        },
-                    ],
-                    "lieferstellenangebotsteil": [
-                        {
-                            "marktlokationsId": "51238696781",
-                            "sparte": Sparte.GAS,
-                            "lokationsadresse": {
-                                "postleitzahl": "82031",
-                                "ort": "Grünwald",
-                                "hausnummer": "27A",
-                                "strasse": "Nördliche Münchner Straße",
-                                "adresszusatz": None,
-                                "postfach": None,
-                                "coErgaenzung": None,
-                                "ortsteil": None,
-                                "landescode": Landescode.DE,  # type: ignore[attr-defined]
-                                "_id": None,
-                            },
-                            "energierichtung": Energierichtung.EINSP,
-                            "bilanzierungsmethode": Bilanzierungsmethode.PAUSCHAL,
-                            "istUnterbrechbar": True,
-                            "netzebene": Netzebene.NSP,
-                            "netzgebietsnr": None,
-                            "katasterinformation": None,
-                            "bilanzierungsgebiet": None,
-                            "grundversorgercodenr": None,
-                            "endkunde": None,
-                            "geoadresse": None,
-                            "verbrauchsart": None,
-                            "netzbetreibercodenr": None,
-                            "gebietstyp": None,
-                            "gasqualitaet": None,
-                            "zugehoerigeMesslokation": None,
-                            "kundengruppen": None,
-                            "externeReferenzen": None,
-                            "_typ": Typ.MARKTLOKATION,
-                            "_id": None,
-                        }
-                    ],
-                    "gesamtmengeangebotsteil": {"wert": Decimal("4000"), "einheit": Mengeneinheit.KWH, "_id": None},
-                    "gesamtkostenangebotsteil": {
-                        "waehrung": Waehrungseinheit.EUR,
-                        "wert": Decimal("98240"),
-                        "_id": None,
-                    },
-                    "anfrageSubreferenz": "teststring",
-                    "lieferzeitraum": {
-                        "startdatum": datetime(2020, 1, 1, tzinfo=timezone.utc),
-                        "endzeitpunkt": None,
-                        "einheit": None,
-                        "enddatum": datetime(2020, 4, 1, tzinfo=timezone.utc),
-                        "startzeitpunkt": None,
-                        "dauer": None,
-                        "_id": None,
-                    },
-                    "_id": None,
-                },
-                id="maximal attributes",
-            ),
-            pytest.param(
-                example_angebotsteil,
-                example_angebotsteil_json,
-                id="minimal attributes",
+                id="all attributes at first level",
             ),
         ],
     )
-    def test_serialization_roundtrip(self, angebotsteil: Angebotsteil, expected_json_dict: Dict[str, Any]) -> None:
+    def test_serialization_roundtrip(self, angebotsteil: Angebotsteil) -> None:
         """
         Test de-/serialisation of Angebotsteil with minimal attributes.
         """
-        assert_serialization_roundtrip(angebotsteil, expected_json_dict)
+        assert_serialization_roundtrip(angebotsteil)
diff --git a/tests/test_angebotsvariante.py b/tests/test_angebotsvariante.py
index b7474993e..a8733c5ed 100644
--- a/tests/test_angebotsvariante.py
+++ b/tests/test_angebotsvariante.py
@@ -1,74 +1,30 @@
 from datetime import datetime, timezone
-from decimal import Decimal
-from typing import Any, Dict
 
 import pytest
-from pydantic import ValidationError
 
-from bo4e import Angebotsstatus, Angebotsvariante, Mengeneinheit
+from bo4e import Angebotsstatus, Angebotsteil, Angebotsvariante, Betrag, Menge
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_angebotsteil import example_angebotsteil, example_angebotsteil_json
-from tests.test_betrag import example_betrag, example_betrag_json
-from tests.test_menge import example_menge
-
-# can be imported by other tests
-example_angebotsvariante = Angebotsvariante(
-    angebotsstatus=Angebotsstatus.NACHGEFASST,
-    bindefrist=datetime(2022, 2, 1, 0, 0, 0, tzinfo=timezone.utc),
-    erstellungsdatum=datetime(2021, 12, 22, 0, 0, 0, tzinfo=timezone.utc),
-    teile=[example_angebotsteil],
-)
 
 
 class TestAngebotsvariante:
     @pytest.mark.parametrize(
-        "angebotsvariante, expected_json_dict",
+        "angebotsvariante",
         [
-            pytest.param(
-                example_angebotsvariante,
-                {
-                    "gesamtmenge": None,
-                    "angebotsstatus": Angebotsstatus.NACHGEFASST,
-                    "erstellungsdatum": datetime(2021, 12, 22, 0, 0, tzinfo=timezone.utc),
-                    "gesamtkosten": None,
-                    "bindefrist": datetime(2022, 2, 1, 0, 0, tzinfo=timezone.utc),
-                    "teile": [example_angebotsteil_json],
-                    "_id": None,
-                },
-                id="minimal attributes",
-            ),
             pytest.param(
                 Angebotsvariante(
                     angebotsstatus=Angebotsstatus.NACHGEFASST,
                     bindefrist=datetime(2022, 2, 1, 0, 0, 0, tzinfo=timezone.utc),
                     erstellungsdatum=datetime(2021, 12, 22, 0, 0, 0, tzinfo=timezone.utc),
-                    teile=[example_angebotsteil],
-                    gesamtmenge=example_menge,
-                    gesamtkosten=example_betrag,
+                    teile=[Angebotsteil()],
+                    gesamtmenge=Menge(),
+                    gesamtkosten=Betrag(),
                 ),
-                {
-                    "gesamtmenge": {
-                        "einheit": Mengeneinheit.MWH,
-                        "wert": Decimal("3.410000000000000142108547152020037174224853515625"),
-                        "_id": None,
-                    },
-                    # this is a problem for https://github.com/Hochfrequenz/BO4E-python/issues/249
-                    # I just reused the example_menge but don't attempt to fix it in the context of the Angebotsvariante
-                    "angebotsstatus": Angebotsstatus.NACHGEFASST,
-                    "erstellungsdatum": datetime(2021, 12, 22, 0, 0, tzinfo=timezone.utc),
-                    "gesamtkosten": example_betrag_json,
-                    "bindefrist": datetime(2022, 2, 1, 0, 0, tzinfo=timezone.utc),
-                    "teile": [example_angebotsteil_json],
-                    "_id": None,
-                },
-                id="max attributes",  # = min + menge and betrag
+                id="all attributes at first level",  # = min + menge and betrag
             ),
         ],
     )
-    def test_serialization_roundtrip(
-        self, angebotsvariante: Angebotsvariante, expected_json_dict: Dict[str, Any]
-    ) -> None:
+    def test_serialization_roundtrip(self, angebotsvariante: Angebotsvariante) -> None:
         """
         Test de-/serialisation roundtrip.
         """
-        assert_serialization_roundtrip(angebotsvariante, expected_json_dict)
+        assert_serialization_roundtrip(angebotsvariante)
diff --git a/tests/test_ansprechpartner.py b/tests/test_ansprechpartner.py
index e83efb74b..526315900 100644
--- a/tests/test_ansprechpartner.py
+++ b/tests/test_ansprechpartner.py
@@ -1,119 +1,33 @@
-from bo4e import (
-    Adresse,
-    Anrede,
-    Ansprechpartner,
-    Geschaeftspartner,
-    Geschaeftspartnerrolle,
-    Kontaktart,
-    Rufnummer,
-    Rufnummernart,
-    Themengebiet,
-    Titel,
-    Typ,
-    Zustaendigkeit,
-)
+import pytest
+
+from bo4e import Adresse, Anrede, Ansprechpartner, Geschaeftspartner, Rufnummer, Titel, Zustaendigkeit
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestAnsprechpartner:
-    def test_de_serialisation_minimal_attributes(self) -> None:
-        """
-        Test de-/serialisation of Ansprechpartner only with required attributes
-        """
-        ansprechpartner = Ansprechpartner(
-            nachname="Müller-Schmidt",
-            geschaeftspartner=Geschaeftspartner(
-                anrede=Anrede.FRAU,
-                name1="von Sinnen",
-                name2="Helga",
-                name3=None,
-                ist_gewerbe=True,
-                hrnummer="HRB 254466",
-                amtsgericht="Amtsgericht München",
-                kontaktweg=[Kontaktart.E_MAIL],
-                umsatzsteuer_id="DE267311963",
-                glaeubiger_id="DE98ZZZ09999999999",
-                e_mail_adresse="test@bo4e.de",
-                website="bo4e.de",
-                geschaeftspartnerrolle=[Geschaeftspartnerrolle.DIENSTLEISTER],
-                partneradresse=Adresse(
-                    postleitzahl="12345",
-                    ort="Sankt Musterweiler",
-                    strasse="Mühlenweg",
-                    hausnummer="540a",
+    @pytest.mark.parametrize(
+        "ansprechpartner",
+        [
+            pytest.param(
+                Ansprechpartner(
+                    nachname="Müller-Schmidt",
+                    geschaeftspartner=Geschaeftspartner(),
+                    anrede=Anrede.EHELEUTE,
+                    individuelle_anrede="Künstler",
+                    titel=Titel.PROF_DR,
+                    vorname="Hans",
+                    e_mail_adresse="hans.müller@getrei.de",
+                    kommentar="does this thing work?",
+                    adresse=Adresse(),
+                    rufnummer=Rufnummer(),
+                    zustaendigkeit=Zustaendigkeit(),
                 ),
+                id="all attributes at first level",  # = min + menge and betrag
             ),
-        )
-        assert ansprechpartner.version is not None, "versionstruktur was not automatically set"
-        assert ansprechpartner.typ is Typ.ANSPRECHPARTNER, "_typ was not automatically set"
-
-        json_string = ansprechpartner.model_dump_json(by_alias=True)
-        assert "Müller-Schmidt" in json_string
-        assert "Mühlenweg" in json_string
-        assert '"FRAU"' in json_string
-
-        deserialized_ansprechpartner = Ansprechpartner.model_validate_json(json_string)
-
-        assert isinstance(deserialized_ansprechpartner, Ansprechpartner)
-        assert isinstance(deserialized_ansprechpartner.geschaeftspartner, Geschaeftspartner)
-        assert deserialized_ansprechpartner == ansprechpartner
-
-    def test_de_serialisation_maximal_attributes(self) -> None:
+        ],
+    )
+    def test_serialization_roundtrip(self, ansprechpartner: Ansprechpartner) -> None:
         """
-        Test de-/serialisation of Ansprechpartner only with required attributes
+        Test Test de-/serialisation roundtrip of Ansprechpartner
         """
-        ansprechpartner = Ansprechpartner(
-            nachname="Müller-Schmidt",
-            geschaeftspartner=Geschaeftspartner(
-                anrede=Anrede.FRAU,
-                name1="von Sinnen",
-                name2="Helga",
-                name3=None,
-                ist_gewerbe=True,
-                hrnummer="HRB 254466",
-                amtsgericht="Amtsgericht München",
-                kontaktweg=[Kontaktart.E_MAIL],
-                umsatzsteuer_id="DE267311963",
-                glaeubiger_id="DE98ZZZ09999999999",
-                e_mail_adresse="test@bo4e.de",
-                website="bo4e.de",
-                geschaeftspartnerrolle=[Geschaeftspartnerrolle.DIENSTLEISTER],
-                partneradresse=Adresse(
-                    postleitzahl="12345",
-                    ort="Sankt Musterweiler",
-                    strasse="Mühlenweg",
-                    hausnummer="540a",
-                ),
-            ),
-            anrede=Anrede.EHELEUTE,
-            individuelle_anrede="Künstler",
-            titel=Titel.PROF_DR,
-            vorname="Hans",
-            e_mail_adresse="hans.müller@getrei.de",
-            kommentar="does this thing work?",
-            adresse=Adresse(
-                postleitzahl="12345",
-                ort="Sankt Musterweiler",
-                strasse="Mühlenweg",
-                hausnummer="540a",
-            ),
-            rufnummer=Rufnummer(nummerntyp=Rufnummernart.RUF_DURCHWAHL, rufnummer="112358132134"),
-            zustaendigkeit=Zustaendigkeit(
-                themengebiet=Themengebiet.MARKTKOMMUNIKATION, jobtitel="Schatzmeister", abteilung="unten rechts"
-            ),
-        )
-        assert ansprechpartner.version is not None, "versionstruktur was not automatically set"
-        assert ansprechpartner.typ is Typ.ANSPRECHPARTNER, "_typ was not automatically set"
-
-        json_string = ansprechpartner.model_dump_json(by_alias=True)
-        assert "Müller-Schmidt" in json_string
-        assert "Mühlenweg" in json_string
-        assert "PROF_DR" in json_string
-
-        deserialized_ansprechpartner = Ansprechpartner.model_validate_json(json_string)
-
-        assert isinstance(deserialized_ansprechpartner, Ansprechpartner)
-        assert isinstance(deserialized_ansprechpartner.geschaeftspartner, Geschaeftspartner)
-        assert isinstance(deserialized_ansprechpartner.adresse, Adresse)
-        assert isinstance(deserialized_ansprechpartner.rufnummer, Rufnummer)
-        assert isinstance(deserialized_ansprechpartner.zustaendigkeit, Zustaendigkeit)
-        assert deserialized_ansprechpartner == ansprechpartner
+        assert_serialization_roundtrip(ansprechpartner)
diff --git a/tests/test_aufabschlag.py b/tests/test_aufabschlag.py
index 93b7220f5..1d7f3ca27 100644
--- a/tests/test_aufabschlag.py
+++ b/tests/test_aufabschlag.py
@@ -1,29 +1,12 @@
-from datetime import datetime, timezone
-from decimal import Decimal
-from typing import Any, Dict
-
 import pytest
-from pydantic import ValidationError
 
 from bo4e import AufAbschlag, AufAbschlagstyp, AufAbschlagsziel, Preisstaffel, Waehrungseinheit, Zeitraum
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_sigmoidparameter import example_sigmoidparameter
-
-example_aufabschlag = AufAbschlag(
-    bezeichnung="foo",
-    staffeln=[
-        Preisstaffel(
-            einheitspreis=Decimal(15.0),
-            staffelgrenze_von=Decimal(2.5),
-            staffelgrenze_bis=Decimal(40.5),
-        ),
-    ],
-)
 
 
 class TestAufAbschlag:
     @pytest.mark.parametrize(
-        "aufabschlag, expected_json_dict",
+        "aufabschlag",
         [
             pytest.param(
                 AufAbschlag(
@@ -33,93 +16,15 @@ class TestAufAbschlag:
                     auf_abschlagsziel=AufAbschlagsziel.GESAMTPREIS,
                     einheit=Waehrungseinheit.EUR,
                     website="foo.bar",
-                    gueltigkeitszeitraum=Zeitraum(
-                        startdatum=datetime(2020, 1, 1, tzinfo=timezone.utc),
-                        enddatum=datetime(2020, 4, 1, tzinfo=timezone.utc),
-                    ),
-                    staffeln=[
-                        Preisstaffel(
-                            einheitspreis=Decimal(40.0),
-                            staffelgrenze_von=Decimal(12.5),
-                            staffelgrenze_bis=Decimal(25.0),
-                            sigmoidparameter=example_sigmoidparameter,
-                        ),
-                        Preisstaffel(
-                            einheitspreis=Decimal(15.0),
-                            staffelgrenze_von=Decimal(2.5),
-                            staffelgrenze_bis=Decimal(40.5),
-                        ),
-                    ],
+                    gueltigkeitszeitraum=Zeitraum(),
+                    staffeln=[Preisstaffel()],
                 ),
-                {
-                    "bezeichnung": "foo",
-                    "beschreibung": "bar",
-                    "aufAbschlagstyp": AufAbschlagstyp.ABSOLUT,
-                    "aufAbschlagsziel": AufAbschlagsziel.GESAMTPREIS,
-                    "einheit": Waehrungseinheit.EUR,
-                    "website": "foo.bar",
-                    "gueltigkeitszeitraum": {
-                        "startdatum": datetime(2020, 1, 1, 0, 0, tzinfo=timezone.utc),
-                        "endzeitpunkt": None,
-                        "einheit": None,
-                        "enddatum": datetime(2020, 4, 1, 0, 0, tzinfo=timezone.utc),
-                        "startzeitpunkt": None,
-                        "dauer": None,
-                        "_id": None,
-                    },
-                    "staffeln": [
-                        {
-                            "einheitspreis": Decimal("40"),
-                            "sigmoidparameter": {
-                                "A": Decimal("1"),
-                                "B": Decimal("2"),
-                                "C": Decimal("3"),
-                                "D": Decimal("4"),
-                                "_id": None,
-                            },
-                            "staffelgrenzeVon": Decimal("12.5"),
-                            "staffelgrenzeBis": Decimal("25"),
-                            "_id": None,
-                        },
-                        {
-                            "einheitspreis": Decimal("15"),
-                            "sigmoidparameter": None,
-                            "staffelgrenzeVon": Decimal("2.5"),
-                            "staffelgrenzeBis": Decimal("40.5"),
-                            "_id": None,
-                        },
-                    ],
-                    "_id": None,
-                },
-                id="maximal attributes",
-            ),
-            pytest.param(
-                example_aufabschlag,
-                {
-                    "bezeichnung": "foo",
-                    "beschreibung": None,
-                    "aufAbschlagstyp": None,
-                    "aufAbschlagsziel": None,
-                    "einheit": None,
-                    "website": None,
-                    "gueltigkeitszeitraum": None,
-                    "staffeln": [
-                        {
-                            "einheitspreis": Decimal("15"),
-                            "sigmoidparameter": None,
-                            "staffelgrenzeVon": Decimal("2.5"),
-                            "staffelgrenzeBis": Decimal("40.5"),
-                            "_id": None,
-                        },
-                    ],
-                    "_id": None,
-                },
-                id="minimal attributes",
+                id="all attributes at first level",
             ),
         ],
     )
-    def test_serialization_roundtrip(self, aufabschlag: AufAbschlag, expected_json_dict: Dict[str, Any]) -> None:
+    def test_serialization_roundtrip(self, aufabschlag: AufAbschlag) -> None:
         """
         Test de-/serialisation of AufAbschlag with minimal attributes.
         """
-        assert_serialization_roundtrip(aufabschlag, expected_json_dict)
+        assert_serialization_roundtrip(aufabschlag)
diff --git a/tests/test_aufabschlagproort.py b/tests/test_aufabschlagproort.py
index 5e15fbd23..bc5def60a 100644
--- a/tests/test_aufabschlagproort.py
+++ b/tests/test_aufabschlagproort.py
@@ -1,8 +1,4 @@
-from decimal import Decimal
-from typing import Any, Dict
-
 import pytest
-from pydantic import ValidationError
 
 from bo4e import AufAbschlagProOrt, AufAbschlagstaffelProOrt
 from tests.serialization_helper import assert_serialization_roundtrip
@@ -10,42 +6,23 @@
 
 class TestAufAbschlagProOrt:
     @pytest.mark.parametrize(
-        "aufabschlagproort, expected_json_dict",
+        "aufabschlagproort",
         [
             pytest.param(
                 AufAbschlagProOrt(
                     postleitzahl="01187",
                     ort="Dresden",
                     netznr="2",
-                    staffeln=[
-                        AufAbschlagstaffelProOrt(
-                            wert=Decimal(2.5),
-                            staffelgrenze_von=Decimal(1),
-                            staffelgrenze_bis=Decimal(5),
-                        )
-                    ],
+                    staffeln=[AufAbschlagstaffelProOrt()],
                 ),
-                {
-                    "postleitzahl": "01187",
-                    "ort": "Dresden",
-                    "netznr": "2",
-                    "staffeln": [
-                        {
-                            "wert": Decimal("2.5"),
-                            "staffelgrenzeVon": Decimal("1"),
-                            "staffelgrenzeBis": Decimal("5"),
-                            "_id": None,
-                        }
-                    ],
-                    "_id": None,
-                },
             )
         ],
     )
     def test_serialization_roundtrip(
-        self, aufabschlagproort: AufAbschlagProOrt, expected_json_dict: Dict[str, Any]
+        self,
+        aufabschlagproort: AufAbschlagProOrt,
     ) -> None:
         """
-        Test de-/serialisation of AufAbschlagProOrt with minimal attributes.
+        Test de-/serialisation of AufAbschlagProOrt.
         """
-        assert_serialization_roundtrip(aufabschlagproort, expected_json_dict)
+        assert_serialization_roundtrip(aufabschlagproort)
diff --git a/tests/test_aufabschlagregional.py b/tests/test_aufabschlagregional.py
index 6ccea0b3f..fec3a5c73 100644
--- a/tests/test_aufabschlagregional.py
+++ b/tests/test_aufabschlagregional.py
@@ -1,22 +1,12 @@
-from datetime import datetime, timezone
-from decimal import Decimal
-from typing import Any, Dict
-
 import pytest
-from pydantic import ValidationError
 
 from bo4e import (
     AufAbschlagProOrt,
     AufAbschlagRegional,
-    AufAbschlagstaffelProOrt,
     AufAbschlagstyp,
     AufAbschlagsziel,
-    Energieherkunft,
     Energiemix,
-    Erzeugungsart,
     Preisgarantie,
-    Preisgarantietyp,
-    Sparte,
     Tarifeinschraenkung,
     Vertragskonditionen,
     Waehrungseinheit,
@@ -24,83 +14,15 @@
 )
 from tests.serialization_helper import assert_serialization_roundtrip
 
-example_aufabschlagregional = AufAbschlagRegional(
-    bezeichnung="foo",
-    betraege=[
-        AufAbschlagProOrt(
-            postleitzahl="01187",
-            ort="Dresden",
-            netznr="2",
-            staffeln=[
-                AufAbschlagstaffelProOrt(
-                    wert=Decimal(2.5),
-                    staffelgrenze_von=Decimal(1),
-                    staffelgrenze_bis=Decimal(5),
-                )
-            ],
-        ),
-    ],
-)
-
 
 class TestAufAbschlagRegional:
     @pytest.mark.parametrize(
-        "aufabschlagregional, expected_json_dict",
+        "aufabschlagregional",
         [
-            pytest.param(
-                example_aufabschlagregional,
-                {
-                    "bezeichnung": "foo",
-                    "betraege": [
-                        {
-                            "postleitzahl": "01187",
-                            "ort": "Dresden",
-                            "netznr": "2",
-                            "staffeln": [
-                                {
-                                    "wert": Decimal("2.5"),
-                                    "staffelgrenzeVon": Decimal("1"),
-                                    "staffelgrenzeBis": Decimal("5"),
-                                    "_id": None,
-                                }
-                            ],
-                            "_id": None,
-                        },
-                    ],
-                    "beschreibung": None,
-                    "aufAbschlagstyp": None,
-                    "aufAbschlagsziel": None,
-                    "einheit": None,
-                    "website": None,
-                    "zusatzprodukte": None,
-                    "voraussetzungen": None,
-                    "tarifnamensaenderungen": None,
-                    "gueltigkeitszeitraum": None,
-                    "energiemixaenderung": None,
-                    "vertagskonditionsaenderung": None,
-                    "garantieaenderung": None,
-                    "einschraenkungsaenderung": None,
-                    "_id": None,
-                },
-                id="only required attributes",
-            ),
             pytest.param(
                 AufAbschlagRegional(
                     bezeichnung="foo",
-                    betraege=[
-                        AufAbschlagProOrt(
-                            postleitzahl="01187",
-                            ort="Dresden",
-                            netznr="2",
-                            staffeln=[
-                                AufAbschlagstaffelProOrt(
-                                    wert=Decimal(2.5),
-                                    staffelgrenze_von=Decimal(1),
-                                    staffelgrenze_bis=Decimal(5),
-                                )
-                            ],
-                        ),
-                    ],
+                    betraege=[AufAbschlagProOrt()],
                     beschreibung="bar",
                     auf_abschlagstyp=AufAbschlagstyp.RELATIV,
                     auf_abschlagsziel=AufAbschlagsziel.ARBEITSPREIS_HT,
@@ -109,124 +31,18 @@ class TestAufAbschlagRegional:
                     zusatzprodukte=["Asterix", "Obelix"],
                     voraussetzungen=["Petterson", "Findus"],
                     tarifnamensaenderungen="foobar",
-                    gueltigkeitszeitraum=Zeitraum(
-                        startdatum=datetime(2020, 1, 1, tzinfo=timezone.utc),
-                        enddatum=datetime(2020, 4, 1, tzinfo=timezone.utc),
-                    ),
-                    energiemixaenderung=Energiemix(
-                        energiemixnummer=2,
-                        energieart=Sparte.STROM,
-                        bezeichnung="foo",
-                        gueltigkeitsjahr=2021,
-                        anteil=[
-                            Energieherkunft(
-                                erzeugungsart=Erzeugungsart.BIOGAS,
-                                anteil_prozent=Decimal(40),
-                            ),
-                        ],
-                    ),
+                    gueltigkeitszeitraum=Zeitraum(),
+                    energiemixaenderung=Energiemix(),
                     vertagskonditionsaenderung=Vertragskonditionen(),
-                    garantieaenderung=Preisgarantie(
-                        preisgarantietyp=Preisgarantietyp.ALLE_PREISBESTANDTEILE_BRUTTO,
-                        zeitliche_gueltigkeit=Zeitraum(
-                            startdatum=datetime(2020, 1, 1, tzinfo=timezone.utc),
-                            enddatum=datetime(2020, 4, 1, tzinfo=timezone.utc),
-                        ),
-                    ),
+                    garantieaenderung=Preisgarantie(),
                     einschraenkungsaenderung=Tarifeinschraenkung(),
                 ),
-                {
-                    "bezeichnung": "foo",
-                    "betraege": [
-                        {
-                            "postleitzahl": "01187",
-                            "ort": "Dresden",
-                            "netznr": "2",
-                            "staffeln": [
-                                {
-                                    "wert": Decimal("2.5"),
-                                    "staffelgrenzeVon": Decimal("1"),
-                                    "staffelgrenzeBis": Decimal("5"),
-                                    "_id": None,
-                                }
-                            ],
-                            "_id": None,
-                        },
-                    ],
-                    "beschreibung": "bar",
-                    "aufAbschlagstyp": AufAbschlagstyp.RELATIV,
-                    "aufAbschlagsziel": "ARBEITSPREIS_HT",
-                    "einheit": Waehrungseinheit.EUR,
-                    "website": "foo.bar",
-                    "zusatzprodukte": ["Asterix", "Obelix"],
-                    "voraussetzungen": ["Petterson", "Findus"],
-                    "tarifnamensaenderungen": "foobar",
-                    "gueltigkeitszeitraum": {
-                        "startdatum": datetime(2020, 1, 1, 0, 0, tzinfo=timezone.utc),
-                        "endzeitpunkt": None,
-                        "einheit": None,
-                        "enddatum": datetime(2020, 4, 1, 0, 0, tzinfo=timezone.utc),
-                        "startzeitpunkt": None,
-                        "dauer": None,
-                        "_id": None,
-                    },
-                    "energiemixaenderung": {
-                        "energiemixnummer": 2,
-                        "energieart": Sparte.STROM,
-                        "bezeichnung": "foo",
-                        "gueltigkeitsjahr": 2021,
-                        "anteil": [
-                            {"erzeugungsart": Erzeugungsart.BIOGAS, "anteilProzent": Decimal("40"), "_id": None}
-                        ],
-                        "oekolabel": None,
-                        "bemerkung": None,
-                        "co2Emission": None,
-                        "atommuell": None,
-                        "website": None,
-                        "oekozertifikate": None,
-                        "istInOekoTopTen": None,
-                        "_id": None,
-                    },
-                    "vertagskonditionsaenderung": {
-                        "beschreibung": None,
-                        "anzahlAbschlaege": None,
-                        "vertragslaufzeit": None,
-                        "kuendigungsfrist": None,
-                        "vertragsverlaengerung": None,
-                        "abschlagszyklus": None,
-                        "_id": None,
-                    },
-                    "garantieaenderung": {
-                        "beschreibung": None,
-                        "preisgarantietyp": "ALLE_PREISBESTANDTEILE_BRUTTO",
-                        "zeitlicheGueltigkeit": {
-                            "startdatum": datetime(2020, 1, 1, 0, 0, tzinfo=timezone.utc),
-                            "endzeitpunkt": None,
-                            "einheit": None,
-                            "enddatum": datetime(2020, 4, 1, 0, 0, tzinfo=timezone.utc),
-                            "startzeitpunkt": None,
-                            "dauer": None,
-                            "_id": None,
-                        },
-                        "_id": None,
-                    },
-                    "einschraenkungsaenderung": {
-                        "zusatzprodukte": None,
-                        "voraussetzungen": None,
-                        "einschraenkungzaehler": None,
-                        "einschraenkungleistung": None,
-                        "_id": None,
-                    },
-                    "_id": None,
-                },
-                id="required and optional attributes",
+                id="all attributes at first level",
             ),
         ],
     )
-    def test_serialization_roundtrip(
-        self, aufabschlagregional: AufAbschlagRegional, expected_json_dict: Dict[str, Any]
-    ) -> None:
+    def test_serialization_roundtrip(self, aufabschlagregional: AufAbschlagRegional) -> None:
         """
         Test de-/serialisation of AufAbschlagRegional with minimal attributes.
         """
-        assert_serialization_roundtrip(aufabschlagregional, expected_json_dict)
+        assert_serialization_roundtrip(aufabschlagregional)
diff --git a/tests/test_aufabschlagstaffelproort.py b/tests/test_aufabschlagstaffelproort.py
index 91b79f821..099da290d 100644
--- a/tests/test_aufabschlagstaffelproort.py
+++ b/tests/test_aufabschlagstaffelproort.py
@@ -1,8 +1,6 @@
 from decimal import Decimal
-from typing import Any, Dict
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import AufAbschlagstaffelProOrt
 from tests.serialization_helper import assert_serialization_roundtrip
@@ -10,7 +8,7 @@
 
 class TestAufAbschlagstaffelProOrt:
     @pytest.mark.parametrize(
-        "aufabschlagstaffelproort, expected_json_dict",
+        "aufabschlagstaffelproort",
         [
             pytest.param(
                 AufAbschlagstaffelProOrt(
@@ -18,19 +16,13 @@ class TestAufAbschlagstaffelProOrt:
                     staffelgrenze_von=Decimal(1),
                     staffelgrenze_bis=Decimal(5),
                 ),
-                {
-                    "wert": Decimal("2.5"),
-                    "staffelgrenzeVon": Decimal("1"),
-                    "staffelgrenzeBis": Decimal("5"),
-                    "_id": None,
-                },
             ),
         ],
     )
     def test_aufabschlagstaffelproort_required_attributes(
-        self, aufabschlagstaffelproort: AufAbschlagstaffelProOrt, expected_json_dict: Dict[str, Any]
+        self, aufabschlagstaffelproort: AufAbschlagstaffelProOrt
     ) -> None:
         """
-        Test de-/serialisation of AufAbschlagstaffelProOrt with minimal attributes.
+        Test de-/serialisation of AufAbschlagstaffelProOrt.
         """
-        assert_serialization_roundtrip(aufabschlagstaffelproort, expected_json_dict)
+        assert_serialization_roundtrip(aufabschlagstaffelproort)
diff --git a/tests/test_ausschreibung.py b/tests/test_ausschreibung.py
index a0178149a..799aaa7ac 100644
--- a/tests/test_ausschreibung.py
+++ b/tests/test_ausschreibung.py
@@ -1,20 +1,17 @@
 from datetime import datetime, timezone
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import (
     Ausschreibung,
+    Ausschreibungslos,
     Ausschreibungsportal,
     Ausschreibungsstatus,
     Ausschreibungstyp,
     Geschaeftspartner,
-    Geschaeftspartnerrolle,
+    Zeitraum,
 )
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_adresse import example_adresse
-from tests.test_ausschreibungslos import example_ausschreibungslos
-from tests.test_zeitraum import example_zeitraum
 
 
 class TestAusschreibung:
@@ -30,38 +27,17 @@ class TestAusschreibung:
                     ausschreibungportal=Ausschreibungsportal.BMWI,
                     webseite="https://meineausschreibungswebsite.inv/",
                     veroeffentlichungszeitpunkt=datetime(2022, 1, 1, 0, 0, 0, tzinfo=timezone.utc),
-                    abgabefrist=example_zeitraum,
-                    bindefrist=example_zeitraum,
-                    ausschreibender=Geschaeftspartner(
-                        name1="Batman",
-                        ist_gewerbe=True,
-                        geschaeftspartnerrolle=[Geschaeftspartnerrolle.LIEFERANT],
-                        partneradresse=example_adresse,
-                    ),
-                    lose=[example_ausschreibungslos],
+                    abgabefrist=Zeitraum(),
+                    bindefrist=Zeitraum(),
+                    ausschreibender=Geschaeftspartner(),
+                    lose=[Ausschreibungslos()],
                 ),
-                id="maximal attributes",
-            ),
-            pytest.param(
-                Ausschreibung(
-                    ausschreibungsnummer="239230",
-                    ausschreibungstyp=Ausschreibungstyp.PRIVATRECHTLICH,
-                    ausschreibungsstatus=Ausschreibungsstatus.PHASE3,
-                    ist_kostenpflichtig=True,
-                    veroeffentlichungszeitpunkt=datetime(2022, 1, 1, 0, 0, 0, tzinfo=timezone.utc),
-                    abgabefrist=example_zeitraum,
-                    bindefrist=example_zeitraum,
-                    ausschreibender=Geschaeftspartner(
-                        name1="Batman",
-                        ist_gewerbe=True,
-                        geschaeftspartnerrolle=[Geschaeftspartnerrolle.LIEFERANT],
-                        partneradresse=example_adresse,
-                    ),
-                    lose=[example_ausschreibungslos],
-                ),
-                id="minimal attributes",
+                id="all attributes at first level",
             ),
         ],
     )
     def test_serialization_roundtrip(self, ausschreibung: Ausschreibung) -> None:
+        """
+        Test de-/serialisation of Ausschreibung.
+        """
         assert_serialization_roundtrip(ausschreibung)
diff --git a/tests/test_ausschreibungsdetail.py b/tests/test_ausschreibungsdetail.py
index be9f340d8..8523783e4 100644
--- a/tests/test_ausschreibungsdetail.py
+++ b/tests/test_ausschreibungsdetail.py
@@ -1,154 +1,37 @@
-from decimal import Decimal
-from typing import Any, Dict
-
 import pytest
-from pydantic import ValidationError
 
-from bo4e import Ausschreibungsdetail, Landescode, Menge, Mengeneinheit, Netzebene, Zaehlertyp
+from bo4e import Adresse, Ausschreibungsdetail, Menge, Netzebene, Zaehlertyp, Zeitraum
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_adresse import example_adresse
-from tests.test_zeitraum import example_zeitraum
-
-example_ausschreibungsdetail = Ausschreibungsdetail(
-    marktlokations_id="56789012345",
-    netzebene_lieferung=Netzebene.MSP,
-    netzebene_messung=Netzebene.NSP,
-    marktlokationsadresse=example_adresse,
-    lieferzeitraum=example_zeitraum,
-    rechnungsadresse=example_adresse,
-)
-example_ausschreibungsdetail_dict = {
-    "zaehlernummer": None,
-    "zaehlertechnik": None,
-    "kunde": None,
-    "marktlokationsbezeichnung": None,
-    "lieferzeitraum": {
-        "dauer": Decimal("5"),
-        "startdatum": None,
-        "endzeitpunkt": None,
-        "enddatum": None,
-        "einheit": Mengeneinheit.TAG,
-        "startzeitpunkt": None,
-        "_id": None,
-    },
-    "marktlokationsadresse": {
-        "landescode": Landescode.DE,  # type: ignore[attr-defined]
-        "hausnummer": "27A",
-        "strasse": "Nördliche Münchner Straße",
-        "postleitzahl": "82031",
-        "ort": "Grünwald",
-        "adresszusatz": None,
-        "postfach": None,
-        "coErgaenzung": None,
-        "ortsteil": None,
-        "_id": None,
-    },
-    "rechnungsadresse": {
-        "landescode": Landescode.DE,  # type: ignore[attr-defined]
-        "hausnummer": "27A",
-        "strasse": "Nördliche Münchner Straße",
-        "postleitzahl": "82031",
-        "ort": "Grünwald",
-        "adresszusatz": None,
-        "postfach": None,
-        "coErgaenzung": None,
-        "ortsteil": None,
-        "_id": None,
-    },
-    "netzbetreiber": None,
-    "netzebeneLieferung": Netzebene.MSP,
-    "prognoseArbeitLieferzeitraum": None,
-    "netzebeneMessung": Netzebene.NSP,
-    "prognoseLeistung": None,
-    "istLastgangVorhanden": None,
-    "prognoseJahresarbeit": None,
-    "marktlokationsId": "56789012345",
-    "_id": None,
-}
 
 
 class TestAusschreibungsdetail:
     @pytest.mark.parametrize(
-        "ausschreibungsdetail, expected_json_dict",
+        "ausschreibungsdetail",
         [
             pytest.param(
                 Ausschreibungsdetail(
                     marktlokations_id="56789012345",
                     netzebene_lieferung=Netzebene.MSP,
                     netzebene_messung=Netzebene.NSP,
-                    marktlokationsadresse=example_adresse,
-                    lieferzeitraum=example_zeitraum,
+                    marktlokationsadresse=Adresse(),
+                    lieferzeitraum=Zeitraum(),
                     netzbetreiber="Stromnetz Hamburg GmbH",
                     kunde="Dei Mudder ihr Kunde",
                     zaehlernummer="1YSK4234092304",
                     marktlokationsbezeichnung="Zentraler Einkauf, Hamburg",
                     zaehlertechnik=Zaehlertyp.LEISTUNGSZAEHLER,
                     ist_lastgang_vorhanden=True,
-                    prognose_leistung=Menge(wert=Decimal(40), einheit=Mengeneinheit.KW),
-                    prognose_arbeit_lieferzeitraum=Menge(wert=Decimal(2500), einheit=Mengeneinheit.KWH),
-                    prognose_jahresarbeit=Menge(wert=Decimal(2500), einheit=Mengeneinheit.KWH),
-                    rechnungsadresse=example_adresse,
+                    prognose_jahresarbeit=Menge(),
+                    prognose_arbeit_lieferzeitraum=Menge(),
+                    prognose_leistung=Menge(),
+                    rechnungsadresse=Adresse(),
                 ),
-                {
-                    "netzbetreiber": "Stromnetz Hamburg GmbH",
-                    "lieferzeitraum": {
-                        "enddatum": None,
-                        "startdatum": None,
-                        "einheit": Mengeneinheit.TAG,
-                        "endzeitpunkt": None,
-                        "dauer": Decimal("5"),
-                        "startzeitpunkt": None,
-                        "_id": None,
-                    },
-                    "zaehlertechnik": Zaehlertyp.LEISTUNGSZAEHLER,
-                    "kunde": "Dei Mudder ihr Kunde",
-                    "marktlokationsbezeichnung": "Zentraler Einkauf, Hamburg",
-                    "marktlokationsadresse": {
-                        "hausnummer": "27A",
-                        "adresszusatz": None,
-                        "postfach": None,
-                        "postleitzahl": "82031",
-                        "landescode": Landescode.DE,  # type: ignore[attr-defined]
-                        "ort": "Grünwald",
-                        "strasse": "Nördliche Münchner Straße",
-                        "coErgaenzung": None,
-                        "ortsteil": None,
-                        "_id": None,
-                    },
-                    "rechnungsadresse": {
-                        "hausnummer": "27A",
-                        "adresszusatz": None,
-                        "postfach": None,
-                        "postleitzahl": "82031",
-                        "landescode": Landescode.DE,  # type: ignore[attr-defined]
-                        "ort": "Grünwald",
-                        "strasse": "Nördliche Münchner Straße",
-                        "coErgaenzung": None,
-                        "ortsteil": None,
-                        "_id": None,
-                    },
-                    "zaehlernummer": "1YSK4234092304",
-                    "prognoseJahresarbeit": {"wert": Decimal("2500"), "einheit": Mengeneinheit.KWH, "_id": None},
-                    "netzebeneLieferung": Netzebene.MSP,
-                    "marktlokationsId": "56789012345",
-                    "prognoseLeistung": {"wert": Decimal("40"), "einheit": Mengeneinheit.KW, "_id": None},
-                    "istLastgangVorhanden": True,
-                    "netzebeneMessung": Netzebene.NSP,
-                    "prognoseArbeitLieferzeitraum": {
-                        "wert": Decimal("2500"),
-                        "einheit": Mengeneinheit.KWH,
-                        "_id": None,
-                    },
-                    "_id": None,
-                },
+                id="all attributes at first level",
             ),
-            pytest.param(example_ausschreibungsdetail, example_ausschreibungsdetail_dict),
         ],
     )
-    def test_serialization_roundtrip(
-        self, ausschreibungsdetail: Ausschreibungsdetail, expected_json_dict: Dict[str, Any]
-    ) -> None:
+    def test_serialization_roundtrip(self, ausschreibungsdetail: Ausschreibungsdetail) -> None:
         """
         Test de-/serialisation of Ausschreibungsdetail
         """
-        assert_serialization_roundtrip(ausschreibungsdetail, expected_json_dict)
+        assert_serialization_roundtrip(ausschreibungsdetail)
diff --git a/tests/test_ausschreibungslos.py b/tests/test_ausschreibungslos.py
index 44f307ca3..6e7d67f8e 100644
--- a/tests/test_ausschreibungslos.py
+++ b/tests/test_ausschreibungslos.py
@@ -1,69 +1,48 @@
-from typing import Any, Dict
-
 import pytest
-from pydantic import ValidationError
-
-from bo4e import Ausschreibungslos, Preismodell, Rechnungslegung, Sparte, Vertragsform
-from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_ausschreibungsdetail import example_ausschreibungsdetail, example_ausschreibungsdetail_dict
-from tests.test_menge import example_menge, example_menge_dict
-from tests.test_zeitraum import example_zeitraum, example_zeitraum_dict
 
-example_ausschreibungslos = Ausschreibungslos(
-    losnummer="foo",
-    bezeichnung="bar",
-    bemerkung="asd",
-    preismodell=Preismodell.FESTPREIS,
-    energieart=Sparte.STROM,
-    wunsch_rechnungslegung=Rechnungslegung.MONATSRECHN,
-    wunsch_vertragsform=Vertragsform.DIREKT,
-    betreut_durch="Max Mustermann",
-    anzahl_lieferstellen=17,
-    lieferstellen=[example_ausschreibungsdetail],
-    gesamt_menge=example_menge,
-    wunsch_mindestmenge=example_menge,
-    wunsch_maximalmenge=example_menge,
-    lieferzeitraum=example_zeitraum,
-    wunsch_kuendingungsfrist=example_zeitraum,
-    wunsch_zahlungsziel=example_zeitraum,
-    wiederholungsintervall=example_zeitraum,
+from bo4e import (
+    Ausschreibungsdetail,
+    Ausschreibungslos,
+    Menge,
+    Preismodell,
+    Rechnungslegung,
+    Sparte,
+    Vertragsform,
+    Zeitraum,
 )
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestAusschreibungslos:
     @pytest.mark.parametrize(
-        "ausschreibungslos, expected_json_dict",
+        "ausschreibungslos",
         [
             pytest.param(
-                example_ausschreibungslos,
-                {
-                    "lieferzeitraum": example_zeitraum_dict,
-                    "preismodell": Preismodell.FESTPREIS,
-                    "energieart": Sparte.STROM,
-                    "wiederholungsintervall": example_zeitraum_dict,
-                    "bemerkung": "asd",
-                    "bezeichnung": "bar",
-                    "losnummer": "foo",
-                    "anzahlLieferstellen": 17,
-                    "lieferstellen": [example_ausschreibungsdetail_dict],
-                    "wunschKuendingungsfrist": example_zeitraum_dict,
-                    "wunschZahlungsziel": example_zeitraum_dict,
-                    "gesamtMenge": example_menge_dict,
-                    "wunschVertragsform": Vertragsform.DIREKT,
-                    "wunschMaximalmenge": example_menge_dict,
-                    "wunschRechnungslegung": Rechnungslegung.MONATSRECHN,
-                    "wunschMindestmenge": example_menge_dict,
-                    "betreutDurch": "Max Mustermann",
-                    "_id": None,
-                },
+                Ausschreibungslos(
+                    losnummer="foo",
+                    bezeichnung="bar",
+                    bemerkung="asd",
+                    preismodell=Preismodell.FESTPREIS,
+                    energieart=Sparte.STROM,
+                    wunsch_rechnungslegung=Rechnungslegung.MONATSRECHN,
+                    wunsch_vertragsform=Vertragsform.DIREKT,
+                    betreut_durch="Max Mustermann",
+                    anzahl_lieferstellen=17,
+                    lieferstellen=[Ausschreibungsdetail()],
+                    gesamt_menge=Menge(),
+                    wunsch_mindestmenge=Menge(),
+                    wunsch_maximalmenge=Menge(),
+                    lieferzeitraum=Zeitraum(),
+                    wunsch_kuendingungsfrist=Zeitraum(),
+                    wunsch_zahlungsziel=Zeitraum(),
+                    wiederholungsintervall=Zeitraum(),
+                ),
                 id="maximal attributes",
             ),
         ],
     )
-    def test_serialization_roundtrip(
-        self, ausschreibungslos: Ausschreibungslos, expected_json_dict: Dict[str, Any]
-    ) -> None:
+    def test_serialization_roundtrip(self, ausschreibungslos: Ausschreibungslos) -> None:
         """
         Test de-/serialisation of Ausschreibungslos
         """
-        assert_serialization_roundtrip(ausschreibungslos, expected_json_dict)
+        assert_serialization_roundtrip(ausschreibungslos)
diff --git a/tests/test_betrag.py b/tests/test_betrag.py
index 709f3a53d..13061f4b5 100644
--- a/tests/test_betrag.py
+++ b/tests/test_betrag.py
@@ -1,29 +1,25 @@
 from decimal import Decimal
-from typing import Any, Dict
 
 import pytest
-from pydantic import ValidationError
 
-from bo4e import Betrag, Waehrungscode, Waehrungseinheit
+from bo4e import Betrag, Waehrungscode
 from tests.serialization_helper import assert_serialization_roundtrip
 
-example_betrag = Betrag(
-    waehrung=Waehrungscode.EUR,
-    wert=Decimal(12.5),
-)
-
-example_betrag_json = {"wert": Decimal("12.5"), "waehrung": Waehrungseinheit.EUR, "_id": None}
-
 
 class TestBetrag:
     @pytest.mark.parametrize(
-        "betrag, expected_json_dict",
+        "betrag",
         [
-            pytest.param(example_betrag, example_betrag_json),
+            pytest.param(
+                Betrag(
+                    waehrung=Waehrungscode.EUR,
+                    wert=Decimal(12.5),
+                ),
+            ),
         ],
     )
-    def test_regionskriterium_serialization_roundtrip(self, betrag: Betrag, expected_json_dict: Dict[str, Any]) -> None:
+    def test_regionskriterium_serialization_roundtrip(self, betrag: Betrag) -> None:
         """
         Test de-/serialisation of Regionskriterium with minimal attributes.
         """
-        assert_serialization_roundtrip(betrag, expected_json_dict)
+        assert_serialization_roundtrip(betrag)
diff --git a/tests/test_buendelvertrag.py b/tests/test_buendelvertrag.py
index b4fc2f722..5fa42d90d 100644
--- a/tests/test_buendelvertrag.py
+++ b/tests/test_buendelvertrag.py
@@ -1,123 +1,23 @@
 from datetime import datetime, timezone
-from typing import Any, Dict
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import (
-    Adresse,
-    Anrede,
     Buendelvertrag,
     Geschaeftspartner,
-    Geschaeftspartnerrolle,
-    Kontaktart,
-    Landescode,
     Sparte,
-    Typ,
     Unterschrift,
+    Vertrag,
     Vertragsart,
     Vertragskonditionen,
     Vertragsstatus,
 )
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_vertrag import TestVertrag
 
 
 class TestBuendelvertrag:
-    _vertragspartner1 = Geschaeftspartner(
-        anrede=Anrede.FRAU,
-        name1="van der Waal",
-        name2="Helga",
-        name3=None,
-        ist_gewerbe=True,
-        kontaktweg=[Kontaktart.SMS],
-        umsatzsteuer_id="DE267311963",
-        glaeubiger_id="DE98ZZZ09999999999",
-        e_mail_adresse="helga.waal@bo4e.de",
-        website="bo4e.de",
-        geschaeftspartnerrolle=[Geschaeftspartnerrolle.DIENSTLEISTER],
-        partneradresse=Adresse(
-            postleitzahl="33333",
-            ort="Quadrat-Ichendorf",
-            strasse="Kubikstraße",
-            hausnummer="4",
-        ),
-    )
-    _vertragspartner2 = Geschaeftspartner(
-        name1="Eckart",
-        name2="Björn",
-        ist_gewerbe=False,
-        geschaeftspartnerrolle=[Geschaeftspartnerrolle.DIENSTLEISTER],
-        partneradresse=Adresse(
-            postleitzahl="24211",
-            ort="Preetz",
-            strasse="Am Markt",
-            hausnummer="67",
-        ),
-    )
-    _vertragspartner1_dict: Dict[str, Any] = {
-        "anrede": Anrede.FRAU,
-        "name1": "van der Waal",
-        "name2": "Helga",
-        "name3": None,
-        "istGewerbe": True,
-        "kontaktweg": [Kontaktart.SMS],
-        "umsatzsteuerId": "DE267311963",
-        "glaeubigerId": "DE98ZZZ09999999999",
-        "eMailAdresse": "helga.waal@bo4e.de",
-        "website": "bo4e.de",
-        "geschaeftspartnerrolle": [Geschaeftspartnerrolle.DIENSTLEISTER],
-        "partneradresse": {
-            "postleitzahl": "33333",
-            "ort": "Quadrat-Ichendorf",
-            "strasse": "Kubikstraße",
-            "hausnummer": "4",
-            "postfach": None,
-            "adresszusatz": None,
-            "coErgaenzung": None,
-            "landescode": Landescode.DE,  # type:ignore[attr-defined]
-            "ortsteil": None,
-            "_id": None,
-        },
-        "_typ": Typ.GESCHAEFTSPARTNER,
-        "externeReferenzen": None,
-        "hrnummer": None,
-        "amtsgericht": None,
-        "_id": None,
-    }
-    _vertragspartner2_dict: Dict[str, Any] = {
-        "name1": "Eckart",
-        "name2": "Björn",
-        "istGewerbe": False,
-        "geschaeftspartnerrolle": [Geschaeftspartnerrolle.DIENSTLEISTER],
-        "partneradresse": {
-            "postleitzahl": "24211",
-            "ort": "Preetz",
-            "strasse": "Am Markt",
-            "hausnummer": "67",
-            "postfach": None,
-            "adresszusatz": None,
-            "coErgaenzung": None,
-            "landescode": Landescode.DE,  # type:ignore[attr-defined]
-            "ortsteil": None,
-            "_id": None,
-        },
-        "_typ": Typ.GESCHAEFTSPARTNER,
-        "externeReferenzen": None,
-        "anrede": None,
-        "name3": None,
-        "hrnummer": None,
-        "amtsgericht": None,
-        "kontaktweg": None,
-        "umsatzsteuerId": None,
-        "glaeubigerId": None,
-        "eMailAdresse": None,
-        "website": None,
-        "_id": None,
-    }
-
     @pytest.mark.parametrize(
-        "buendelvertrag, expected_dict",
+        "buendelvertrag",
         [
             pytest.param(
                 Buendelvertrag(
@@ -127,79 +27,17 @@ class TestBuendelvertrag:
                     sparte=Sparte.STROM,
                     vertragsbeginn=datetime(2021, 4, 30, 13, 45, tzinfo=timezone.utc),
                     vertragsende=datetime(2200, 4, 30, 13, 45, tzinfo=timezone.utc),
-                    vertragspartner1=_vertragspartner1,
-                    vertragspartner2=_vertragspartner2,
-                ),
-                {
-                    "vertragsnummer": "1234567890",
-                    "vertragsart": Vertragsart.NETZNUTZUNGSVERTRAG,
-                    "vertragsstatus": Vertragsstatus.AKTIV,
-                    "sparte": Sparte.STROM,
-                    "vertragsbeginn": datetime(2021, 4, 30, 13, 45, tzinfo=timezone.utc),
-                    "vertragsende": datetime(2200, 4, 30, 13, 45, tzinfo=timezone.utc),
-                    "vertragspartner1": _vertragspartner1_dict,
-                    "vertragspartner2": _vertragspartner2_dict,
-                    "_typ": Typ.BUENDELVERTRAG,
-                    "externeReferenzen": None,
-                    "einzelvertraege": None,
-                    "vertragskonditionen": None,
-                    "unterzeichnervp1": None,
-                    "unterzeichnervp2": None,
-                    "beschreibung": None,
-                    "_id": None,
-                },
-                id="minimal fields",
-            ),
-            pytest.param(
-                Buendelvertrag(
-                    vertragsnummer="1234567890",
-                    vertragsart=Vertragsart.NETZNUTZUNGSVERTRAG,
-                    vertragsstatus=Vertragsstatus.AKTIV,
-                    sparte=Sparte.STROM,
-                    vertragsbeginn=datetime(2021, 4, 30, 13, 45, tzinfo=timezone.utc),
-                    vertragsende=datetime(2200, 4, 30, 13, 45, tzinfo=timezone.utc),
-                    vertragspartner1=_vertragspartner1,
-                    vertragspartner2=_vertragspartner2,
-                    einzelvertraege=[TestVertrag().get_example_vertrag()],
-                    vertragskonditionen=[Vertragskonditionen(beschreibung="Hello World")],
-                    unterzeichnervp1=[Unterschrift(name="Helga van der Waal")],
-                    unterzeichnervp2=[Unterschrift(name="Björn oder so"), Unterschrift(name="Zweiter Typ")],
+                    vertragspartner1=Geschaeftspartner(),
+                    vertragspartner2=Geschaeftspartner(),
+                    einzelvertraege=[Vertrag()],
+                    vertragskonditionen=[Vertragskonditionen()],
+                    unterzeichnervp1=[Unterschrift()],
+                    unterzeichnervp2=[Unterschrift(), Unterschrift()],
                     beschreibung="Das ist ein Bündelvertrag mit allen optionalen Feldern ausgefüllt.",
                 ),
-                {
-                    "_typ": Typ.BUENDELVERTRAG,
-                    "externeReferenzen": None,
-                    "vertragsnummer": "1234567890",
-                    "vertragsart": Vertragsart.NETZNUTZUNGSVERTRAG,
-                    "vertragsstatus": Vertragsstatus.AKTIV,
-                    "sparte": Sparte.STROM,
-                    "vertragsbeginn": datetime(2021, 4, 30, 13, 45, tzinfo=timezone.utc),
-                    "vertragsende": datetime(2200, 4, 30, 13, 45, tzinfo=timezone.utc),
-                    "vertragspartner1": _vertragspartner1_dict,
-                    "vertragspartner2": _vertragspartner2_dict,
-                    "einzelvertraege": [TestVertrag().get_example_vertrag_expected_dict()],
-                    "vertragskonditionen": [
-                        {
-                            "beschreibung": "Hello World",
-                            "anzahlAbschlaege": None,
-                            "vertragslaufzeit": None,
-                            "kuendigungsfrist": None,
-                            "vertragsverlaengerung": None,
-                            "abschlagszyklus": None,
-                            "_id": None,
-                        }
-                    ],
-                    "unterzeichnervp1": [{"name": "Helga van der Waal", "ort": None, "datum": None, "_id": None}],
-                    "unterzeichnervp2": [
-                        {"name": "Björn oder so", "ort": None, "datum": None, "_id": None},
-                        {"name": "Zweiter Typ", "ort": None, "datum": None, "_id": None},
-                    ],
-                    "beschreibung": "Das ist ein Bündelvertrag mit allen optionalen Feldern ausgefüllt.",
-                    "_id": None,
-                },
-                id="maximal fields",
+                id="all attributes at first level",
             ),
         ],
     )
-    def test_serialization_roundtrip(self, buendelvertrag: Buendelvertrag, expected_dict: Dict[str, Any]) -> None:
-        assert_serialization_roundtrip(buendelvertrag, expected_dict)
+    def test_serialization_roundtrip(self, buendelvertrag: Buendelvertrag) -> None:
+        assert_serialization_roundtrip(buendelvertrag)
diff --git a/tests/test_energieherkunft.py b/tests/test_energieherkunft.py
index 1531e3ad0..e9792a33a 100644
--- a/tests/test_energieherkunft.py
+++ b/tests/test_energieherkunft.py
@@ -1,30 +1,28 @@
 from decimal import Decimal
-from typing import Any, Dict
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import Energieherkunft, Erzeugungsart
 from tests.serialization_helper import assert_serialization_roundtrip
 
-# this can be imported by other tests
-example_energieherkunft = Energieherkunft(erzeugungsart=Erzeugungsart.BIOMASSE, anteil_prozent=Decimal(25.5))
-
 
 class TestEnergieherkunft:
     @pytest.mark.parametrize(
-        "energieherkunft, expected_json_dict",
+        "energieherkunft",
         [
             pytest.param(
-                example_energieherkunft,
-                {"erzeugungsart": Erzeugungsart.BIOMASSE, "anteilProzent": Decimal("25.5"), "_id": None},
+                Energieherkunft(
+                    erzeugungsart=Erzeugungsart.BIOMASSE,
+                    anteil_prozent=Decimal(25.5),
+                ),
             ),
         ],
     )
-    def test_energieherkunft_required_attributes(
-        self, energieherkunft: Energieherkunft, expected_json_dict: Dict[str, Any]
+    def test_serialization_roundtrip(
+        self,
+        energieherkunft: Energieherkunft,
     ) -> None:
         """
         Test de-/serialisation of Energieherkunft with minimal attributes.
         """
-        assert_serialization_roundtrip(energieherkunft, expected_json_dict)
+        assert_serialization_roundtrip(energieherkunft)
diff --git a/tests/test_energiemenge.py b/tests/test_energiemenge.py
index 2619d692f..09d1a0903 100644
--- a/tests/test_energiemenge.py
+++ b/tests/test_energiemenge.py
@@ -1,9 +1,7 @@
 import pytest
-from pydantic import ValidationError
 
-from bo4e import Energiemenge, Lokationstyp
+from bo4e import Energiemenge, Lokationstyp, Verbrauch
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_verbrauch import example_verbrauch
 
 
 class TestEnergiemenge:
@@ -14,8 +12,9 @@ class TestEnergiemenge:
                 Energiemenge(
                     lokations_id="DE0123456789012345678901234567890",
                     lokationstyp=Lokationstyp.MELO,
-                    energieverbrauch=[example_verbrauch],
-                )
+                    energieverbrauch=[Verbrauch()],
+                ),
+                id="all attributes at first level",
             ),
         ],
     )
diff --git a/tests/test_energiemix.py b/tests/test_energiemix.py
index c37ba5e9a..f67bb43b3 100644
--- a/tests/test_energiemix.py
+++ b/tests/test_energiemix.py
@@ -1,49 +1,15 @@
 from decimal import Decimal
-from typing import Any, Dict
 
 import pytest
-from pydantic import ValidationError
 
-from bo4e import Energieherkunft, Energiemix, Erzeugungsart, Oekolabel, Oekozertifikat, Sparte
+from bo4e import Energieherkunft, Energiemix, Oekolabel, Oekozertifikat, Sparte
 from tests.serialization_helper import assert_serialization_roundtrip
 
-example_energiemix = Energiemix(
-    energiemixnummer=2,
-    energieart=Sparte.STROM,
-    bezeichnung="foo",
-    gueltigkeitsjahr=2021,
-    anteil=[
-        Energieherkunft(
-            erzeugungsart=Erzeugungsart.BIOGAS,
-            anteil_prozent=Decimal(40),
-        ),
-    ],
-)
-
 
 class TestEnergiemix:
     @pytest.mark.parametrize(
-        "energiemix, expected_json_dict",
+        "energiemix",
         [
-            pytest.param(
-                example_energiemix,
-                {
-                    "energiemixnummer": 2,
-                    "energieart": Sparte.STROM,
-                    "bezeichnung": "foo",
-                    "gueltigkeitsjahr": 2021,
-                    "anteil": [{"erzeugungsart": Erzeugungsart.BIOGAS, "anteilProzent": Decimal("40"), "_id": None}],
-                    "oekolabel": None,
-                    "bemerkung": None,
-                    "co2Emission": None,
-                    "atommuell": None,
-                    "website": None,
-                    "oekozertifikate": None,
-                    "istInOekoTopTen": None,
-                    "_id": None,
-                },
-                id="only required attributes",
-            ),
             pytest.param(
                 Energiemix(
                     energiemixnummer=2,
@@ -51,14 +17,8 @@ class TestEnergiemix:
                     bezeichnung="foo",
                     gueltigkeitsjahr=2021,
                     anteil=[
-                        Energieherkunft(
-                            erzeugungsart=Erzeugungsart.BIOGAS,
-                            anteil_prozent=Decimal(40),
-                        ),
-                        Energieherkunft(
-                            erzeugungsart=Erzeugungsart.GEOTHERMIE,
-                            anteil_prozent=Decimal(60),
-                        ),
+                        Energieherkunft(),
+                        Energieherkunft(),
                     ],
                     oekolabel=[
                         Oekolabel.GASGREEN,
@@ -71,32 +31,12 @@ class TestEnergiemix:
                     oekozertifikate=[Oekozertifikat.FRAUNHOFER, Oekozertifikat.FREIBERG],
                     ist_in_oeko_top_ten=True,
                 ),
-                {
-                    "energiemixnummer": 2,
-                    "energieart": Sparte.STROM,
-                    "bezeichnung": "foo",
-                    "gueltigkeitsjahr": 2021,
-                    "anteil": [
-                        {"erzeugungsart": Erzeugungsart.BIOGAS, "anteilProzent": Decimal("40"), "_id": None},
-                        {"erzeugungsart": Erzeugungsart.GEOTHERMIE, "anteilProzent": Decimal("60"), "_id": None},
-                    ],
-                    "oekolabel": ["GASGREEN", "GRUENER_STROM_GOLD"],
-                    "bemerkung": "bar",
-                    "co2Emission": Decimal("40"),
-                    "atommuell": Decimal("5"),
-                    "website": "foobar.de",
-                    "oekozertifikate": ["FRAUNHOFER", "FREIBERG"],
-                    "istInOekoTopTen": True,
-                    "_id": None,
-                },
-                id="required and optional attributes",
+                id="all attributes at first level",
             ),
         ],
     )
-    def test_energiemix_serialization_roundtrip(
-        self, energiemix: Energiemix, expected_json_dict: Dict[str, Any]
-    ) -> None:
+    def test_energiemix_serialization_roundtrip(self, energiemix: Energiemix) -> None:
         """
         Test de-/serialisation of Energiehermix with minimal attributes.
         """
-        assert_serialization_roundtrip(energiemix, expected_json_dict)
+        assert_serialization_roundtrip(energiemix)
diff --git a/tests/test_enums.py b/tests/test_enums.py
index f9318e750..7a1c7cd8c 100644
--- a/tests/test_enums.py
+++ b/tests/test_enums.py
@@ -3,8 +3,6 @@
 from pathlib import Path
 from typing import List, Optional, TypeVar
 
-import pytest
-
 from bo4e import StrEnum
 from bo4e.enum import anrede
 
diff --git a/tests/test_externe_referenz.py b/tests/test_externe_referenz.py
deleted file mode 100644
index 1b4257abf..000000000
--- a/tests/test_externe_referenz.py
+++ /dev/null
@@ -1,73 +0,0 @@
-from typing import Any, Dict
-
-from bo4e import Adresse, ExterneReferenz, Geschaeftspartner, Geschaeftspartnerrolle
-
-
-class TestExterneReferenz:
-    def test_serialization(self) -> None:
-        er = ExterneReferenz(ex_ref_name="HOCHFREQUENZ_HFSAP_100", ex_ref_wert="12345")
-
-        er_json = er.model_dump_json(by_alias=True)
-
-        assert "exRefName" in er_json
-
-        deserialized_er: ExterneReferenz = ExterneReferenz.model_validate_json(er_json)
-        assert isinstance(deserialized_er, ExterneReferenz)
-        assert deserialized_er == er
-
-    def test_list_of_externe_referenz(self) -> None:
-        gp = Geschaeftspartner(
-            externe_referenzen=[
-                ExterneReferenz(ex_ref_name="SAP GP Nummer", ex_ref_wert="0123456789"),
-                ExterneReferenz(ex_ref_name="Schufa-ID", ex_ref_wert="aksdlakoeuhn"),
-            ],
-            # just some dummy data to make the GP valid
-            name1="Duck",
-            name2="Donald",
-            ist_gewerbe=False,
-            geschaeftspartnerrolle=[Geschaeftspartnerrolle.KUNDE],
-            partneradresse=Adresse(
-                strasse="Am Geldspeicher",
-                hausnummer="17",
-                postleitzahl="88101",
-                ort="Entenhausen",
-            ),
-        )
-
-        gp_json = gp.model_dump_json(by_alias=True)
-
-        deserialized_gp: Geschaeftspartner = Geschaeftspartner.model_validate_json(gp_json)
-        assert len(deserialized_gp.externe_referenzen) == 2
-        assert deserialized_gp.externe_referenzen[0].ex_ref_name == "SAP GP Nummer"
-
-    def test_geschaeftspartner_with_no_externe_referenz(self) -> None:
-        gp = Geschaeftspartner(
-            # just some dummy data to make the GP valid
-            name1="Duck",
-            name2="Donald",
-            ist_gewerbe=False,
-            geschaeftspartnerrolle=[Geschaeftspartnerrolle.KUNDE],
-            partneradresse=Adresse(
-                strasse="Am Geldspeicher",
-                hausnummer="17",
-                postleitzahl="88101",
-                ort="Entenhausen",
-            ),
-        )
-
-        gp_json = gp.model_dump_json(by_alias=True)
-
-        deserialized_gp: Geschaeftspartner = Geschaeftspartner.model_validate_json(gp_json)
-
-        assert deserialized_gp.externe_referenzen is None
-
-    def test_extension_data(self) -> None:
-        """
-        tests the behaviour of the json extension data (`extra="allow"`)
-        """
-        er = ExterneReferenz(ex_ref_name="foo.bar", ex_ref_wert="12345")
-        er_json: Dict[str, Any] = er.model_dump()
-        er_json["additional_key"] = "additional_value"
-        deserialized_er: ExterneReferenz = ExterneReferenz.model_validate(er_json)
-        assert isinstance(deserialized_er, ExterneReferenz)
-        assert deserialized_er.additional_key == "additional_value"  # type:ignore[attr-defined]
diff --git a/tests/test_fremdkosten.py b/tests/test_fremdkosten.py
index 02d571e5c..f893be58a 100644
--- a/tests/test_fremdkosten.py
+++ b/tests/test_fremdkosten.py
@@ -1,10 +1,7 @@
 import pytest
-from pydantic import ValidationError
 
-from bo4e import Fremdkosten, Fremdkostenblock
+from bo4e import Betrag, Fremdkosten, Fremdkostenblock, Zeitraum
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_betrag import example_betrag
-from tests.test_zeitraum import example_zeitraum
 
 
 class TestFremdkosten:
@@ -13,10 +10,11 @@ class TestFremdkosten:
         [
             pytest.param(
                 Fremdkosten(
-                    gueltigkeit=example_zeitraum,
-                    summe_kosten=example_betrag,
-                    kostenbloecke=[Fremdkostenblock(kostenblockbezeichnung="teststring")],
-                )
+                    gueltigkeit=Zeitraum(),
+                    summe_kosten=Betrag(),
+                    kostenbloecke=[Fremdkostenblock()],
+                ),
+                id="all attributes at first level",
             ),
         ],
     )
diff --git a/tests/test_fremdkostenblock.py b/tests/test_fremdkostenblock.py
index 75fc2f9ab..27f1630cd 100644
--- a/tests/test_fremdkostenblock.py
+++ b/tests/test_fremdkostenblock.py
@@ -1,101 +1,25 @@
-from decimal import Decimal
-from typing import Any, Dict
-
 import pytest
-from pydantic import ValidationError
 
-from bo4e import (
-    Betrag,
-    Fremdkostenblock,
-    Fremdkostenposition,
-    Mengeneinheit,
-    Preis,
-    Preisstatus,
-    Waehrungscode,
-    Waehrungseinheit,
-)
+from bo4e import Betrag, Fremdkostenblock, Fremdkostenposition
 from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestFremdkostenblock:
     @pytest.mark.parametrize(
-        "fremdkostenblock, expected_json_dict",
+        "fremdkostenblock",
         [
             pytest.param(
                 Fremdkostenblock(
                     kostenblockbezeichnung="teststring",
-                    kostenpositionen=[
-                        Fremdkostenposition(
-                            positionstitel="fremdkostenblocktitel",
-                            artikelbezeichnung="bsp",
-                            einzelpreis=Preis(
-                                wert=Decimal(3.50),
-                                einheit=Waehrungseinheit.EUR,
-                                bezugswert=Mengeneinheit.KWH,
-                                status=Preisstatus.ENDGUELTIG,
-                            ),
-                            betrag_kostenposition=Betrag(
-                                waehrung=Waehrungscode.EUR,
-                                wert=Decimal(12.5),
-                            ),
-                        )
-                    ],
-                    summe_kostenblock=Betrag(
-                        waehrung=Waehrungscode.EUR,
-                        wert=Decimal(98240),
-                    ),
+                    kostenpositionen=[Fremdkostenposition()],
+                    summe_kostenblock=Betrag(),
                 ),
-                {
-                    "kostenblockbezeichnung": "teststring",
-                    "kostenpositionen": [
-                        {
-                            "marktpartnercode": None,
-                            "positionstitel": "fremdkostenblocktitel",
-                            "einzelpreis": {
-                                "wert": Decimal("3.5"),
-                                "einheit": Waehrungseinheit.EUR,
-                                "bezugswert": Mengeneinheit.KWH,
-                                "status": Preisstatus.ENDGUELTIG,
-                                "_id": None,
-                            },
-                            "bis": None,
-                            "menge": None,
-                            "zeitmenge": None,
-                            "artikelbezeichnung": "bsp",
-                            "marktpartnername": None,
-                            "artikeldetail": None,
-                            "von": None,
-                            "linkPreisblatt": None,
-                            "betragKostenposition": {
-                                "wert": Decimal("12.5"),
-                                "waehrung": Waehrungseinheit.EUR,
-                                "_id": None,
-                            },
-                            "gebietcodeEic": None,
-                            "_id": None,
-                        }
-                    ],
-                    "summeKostenblock": {"wert": Decimal("98240"), "waehrung": Waehrungseinheit.EUR, "_id": None},
-                    "_id": None,
-                },
-                id="maximal attributes",
-            ),
-            pytest.param(
-                Fremdkostenblock(kostenblockbezeichnung="teststring"),
-                {
-                    "kostenblockbezeichnung": "teststring",
-                    "kostenpositionen": None,
-                    "summeKostenblock": None,
-                    "_id": None,
-                },
-                id="minimal attributes",
+                id="all attributes at first level",
             ),
         ],
     )
-    def test_serialization_roundtrip(
-        self, fremdkostenblock: Fremdkostenblock, expected_json_dict: Dict[str, Any]
-    ) -> None:
+    def test_serialization_roundtrip(self, fremdkostenblock: Fremdkostenblock) -> None:
         """
         Test de-/serialisation of Fremdkostenblock
         """
-        assert_serialization_roundtrip(fremdkostenblock, expected_json_dict)
+        assert_serialization_roundtrip(fremdkostenblock)
diff --git a/tests/test_fremdkostenposition.py b/tests/test_fremdkostenposition.py
index b973f9c65..06ceca684 100644
--- a/tests/test_fremdkostenposition.py
+++ b/tests/test_fremdkostenposition.py
@@ -1,59 +1,15 @@
 from datetime import datetime, timezone
-from decimal import Decimal
-from typing import Any, Dict
 
 import pytest
-from pydantic import ValidationError
 
-from bo4e import Betrag, Fremdkostenposition, Mengeneinheit, Preis, Preisstatus, Waehrungscode, Waehrungseinheit
+from bo4e import Betrag, Fremdkostenposition, Menge, Preis
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_menge import example_menge
-from tests.test_sigmoidparameter import example_sigmoidparameter
 
 
 class TestFremdkostenposition:
     @pytest.mark.parametrize(
-        "fremdkostenposition, expected_json_dict",
+        "fremdkostenposition",
         [
-            pytest.param(
-                Fremdkostenposition(
-                    positionstitel="Mudders Preisstaffel",
-                    artikelbezeichnung="Dei Mudder ihr Preisstaffel",
-                    einzelpreis=Preis(
-                        wert=Decimal(3.50),
-                        einheit=Waehrungseinheit.EUR,
-                        bezugswert=Mengeneinheit.KWH,
-                        status=Preisstatus.ENDGUELTIG,
-                    ),
-                    betrag_kostenposition=Betrag(
-                        waehrung=Waehrungscode.EUR,
-                        wert=Decimal(12.5),
-                    ),
-                ),
-                {
-                    "marktpartnercode": None,
-                    "positionstitel": "Mudders Preisstaffel",
-                    "einzelpreis": {
-                        "wert": Decimal("3.5"),
-                        "einheit": Waehrungseinheit.EUR,
-                        "bezugswert": Mengeneinheit.KWH,
-                        "status": Preisstatus.ENDGUELTIG,
-                        "_id": None,
-                    },
-                    "bis": None,
-                    "menge": None,
-                    "zeitmenge": None,
-                    "artikelbezeichnung": "Dei Mudder ihr Preisstaffel",
-                    "marktpartnername": None,
-                    "artikeldetail": None,
-                    "von": None,
-                    "linkPreisblatt": None,
-                    "betragKostenposition": {"wert": Decimal("12.5"), "waehrung": Waehrungseinheit.EUR, "_id": None},
-                    "gebietcodeEic": None,
-                    "_id": None,
-                },
-                id="only required attributes",
-            ),
             pytest.param(
                 Fremdkostenposition(
                     positionstitel="Vadders Preisstaffel",
@@ -61,61 +17,21 @@ class TestFremdkostenposition:
                     bis=datetime(2014, 5, 1, tzinfo=timezone.utc),
                     artikelbezeichnung="Deim Vadder sei Preisstaffel",
                     link_preisblatt="http://foo.bar/",
-                    zeitmenge=example_menge,
-                    einzelpreis=Preis(
-                        wert=Decimal(3.50),
-                        einheit=Waehrungseinheit.EUR,
-                        bezugswert=Mengeneinheit.KWH,
-                        status=Preisstatus.ENDGUELTIG,
-                    ),
-                    betrag_kostenposition=Betrag(
-                        waehrung=Waehrungscode.EUR,
-                        wert=Decimal(12.5),
-                    ),
-                    menge=example_menge,
+                    zeitmenge=Menge(),
+                    einzelpreis=Preis(),
+                    betrag_kostenposition=Betrag(),
+                    menge=Menge(),
                     artikeldetail="foo",
                     marktpartnercode="986543210123",
                     marktpartnername="Mein MP",
                     gebietcode_eic="not an eic code but validation will follow in ticket 146",
                 ),
-                {
-                    "artikelbezeichnung": "Deim Vadder sei Preisstaffel",
-                    "artikeldetail": "foo",
-                    "marktpartnername": "Mein MP",
-                    "einzelpreis": {
-                        "bezugswert": Mengeneinheit.KWH,
-                        "status": Preisstatus.ENDGUELTIG,
-                        "wert": Decimal("3.5"),
-                        "einheit": Waehrungseinheit.EUR,
-                        "_id": None,
-                    },
-                    "menge": {
-                        "wert": Decimal("3.410000000000000142108547152020037174224853515625"),
-                        "einheit": Mengeneinheit.MWH,
-                        "_id": None,
-                    },
-                    "zeitmenge": {
-                        "wert": Decimal("3.410000000000000142108547152020037174224853515625"),
-                        "einheit": Mengeneinheit.MWH,
-                        "_id": None,
-                    },
-                    "marktpartnercode": "986543210123",
-                    "bis": datetime(2014, 5, 1, 0, 0, tzinfo=timezone.utc),
-                    "positionstitel": "Vadders Preisstaffel",
-                    "von": datetime(2013, 5, 1, 0, 0, tzinfo=timezone.utc),
-                    "betragKostenposition": {"wert": Decimal("12.5"), "waehrung": Waehrungseinheit.EUR, "_id": None},
-                    "gebietcodeEic": "not an eic code but validation will follow in ticket 146",
-                    "linkPreisblatt": "http://foo.bar/",
-                    "_id": None,
-                },
-                id="required and optional attributes",
+                id="all attributes at first level",
             ),
         ],
     )
-    def test_serialization_roundtrip(
-        self, fremdkostenposition: Fremdkostenposition, expected_json_dict: Dict[str, Any]
-    ) -> None:
+    def test_serialization_roundtrip(self, fremdkostenposition: Fremdkostenposition) -> None:
         """
         Test de-/serialisation of Fremdkostenposition.
         """
-        assert_serialization_roundtrip(fremdkostenposition, expected_json_dict)
+        assert_serialization_roundtrip(fremdkostenposition)
diff --git a/tests/test_geokoordinaten.py b/tests/test_geokoordinaten.py
index 2f163a232..13a4b9eb0 100644
--- a/tests/test_geokoordinaten.py
+++ b/tests/test_geokoordinaten.py
@@ -4,25 +4,24 @@
 from pydantic import ValidationError
 
 from bo4e import Geokoordinaten
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestGeokoordinaten:
-    def test_serialization(self) -> None:
-        geo = Geokoordinaten(
-            breitengrad=Decimal(52.52149200439453),
-            laengengrad=Decimal(13.404866218566895),
-        )
-
-        json_string = geo.model_dump_json(by_alias=True)
-
-        assert "breitengrad" in json_string
-        assert str(geo.breitengrad) in json_string
-
-        deserialized_geo: Geokoordinaten = Geokoordinaten.model_validate_json(json_string)
-
-        assert isinstance(deserialized_geo.breitengrad, Decimal)
-        assert isinstance(deserialized_geo.laengengrad, Decimal)
-        assert geo.breitengrad == deserialized_geo.breitengrad
+    @pytest.mark.parametrize(
+        "geokoordinaten",
+        [
+            pytest.param(
+                Geokoordinaten(
+                    breitengrad=Decimal(52.52149200439453),
+                    laengengrad=Decimal(13.404866218566895),
+                ),
+                id="all attributes at first level",
+            ),
+        ],
+    )
+    def test_serialization_roundtrip(self, geokoordinaten: Geokoordinaten) -> None:
+        assert_serialization_roundtrip(geokoordinaten)
 
     def test_wrong_datatype(self) -> None:
         with pytest.raises(ValidationError) as excinfo:
diff --git a/tests/test_geraet.py b/tests/test_geraet.py
index 92a8d977a..3a62f895f 100644
--- a/tests/test_geraet.py
+++ b/tests/test_geraet.py
@@ -16,12 +16,13 @@ class TestGeraet:
         "geraet",
         [
             pytest.param(
-                Geraet(),
-                id="Minimal attributes",
-            ),
-            pytest.param(
-                example_geraet,
-                id="Maximal attributes",
+                Geraet(
+                    geraetenummer="0815",
+                    bezeichnung="56k Modem",
+                    geraeteklasse=Geraeteklasse.WANDLER,
+                    geraetetyp=Geraetetyp.BLOCKSTROMWANDLER,
+                ),
+                id="all attributes at first level",
             ),
         ],
     )
diff --git a/tests/test_geschaeftsobjekt.py b/tests/test_geschaeftsobjekt.py
index 53589c4ae..bd9aa0f49 100644
--- a/tests/test_geschaeftsobjekt.py
+++ b/tests/test_geschaeftsobjekt.py
@@ -1,61 +1,42 @@
-from typing import List, Optional
-
 import pytest
 from pydantic import ValidationError
 
-from bo4e import ExterneReferenz, Geschaeftsobjekt, Typ
+from bo4e import Geschaeftsobjekt, Typ
+from bo4e.zusatzattribut import ZusatzAttribut
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestGeschaeftsobjekt:
     @pytest.mark.parametrize(
-        "typ, version, externe_referenzen",
+        "geschaeftsobjekt",
         [
-            (
-                Typ.ENERGIEMENGE,
-                "2",
-                [
-                    ExterneReferenz(ex_ref_name="HOCHFREQUENZ_HFSAP_100", ex_ref_wert="12345"),
-                    ExterneReferenz(ex_ref_name="Schufa-ID", ex_ref_wert="aksdlakoeuhn"),
+            Geschaeftsobjekt(
+                typ=Typ.ENERGIEMENGE,
+                version="2",
+                zusatz_attribute=[
+                    ZusatzAttribut(name="HOCHFREQUENZ_HFSAP_100", wert="12345"),
+                    ZusatzAttribut(name="Schufa-ID", wert="aksdlakoeuhn"),
                 ],
             ),
-            (
-                Typ.ENERGIEMENGE,
-                "2",
-                [ExterneReferenz(ex_ref_name="HOCHFREQUENZ_HFSAP_100", ex_ref_wert="12345")],
+            Geschaeftsobjekt(
+                typ=Typ.ENERGIEMENGE,
+                version="2",
+                zusatz_attribute=[],
             ),
-            (Typ.ENERGIEMENGE, "2", []),
         ],
     )
-    def test_serialisation(self, typ: Typ, version: str, externe_referenzen: Optional[List[ExterneReferenz]]) -> None:
-        go = Geschaeftsobjekt(
-            typ=typ,
-            version=version,
-            externe_referenzen=externe_referenzen,
-        )
-        assert isinstance(go, Geschaeftsobjekt)
-
-        go_json = go.model_dump_json(by_alias=True)
-
-        assert str(version) in go_json
-
-        go_deserialized = Geschaeftsobjekt.model_validate_json(go_json)
-
-        assert go_deserialized.typ is typ
-        assert go_deserialized.version == version
-        assert go_deserialized.externe_referenzen == externe_referenzen
-
-    def test_initialization_with_minimal_attributs(self) -> None:
-        go = Geschaeftsobjekt(typ=Typ.ANSPRECHPARTNER)
-
-        assert go.externe_referenzen is None
-        assert go.version is not None
+    def test_serialization_roundtrip(self, geschaeftsobjekt: Geschaeftsobjekt) -> None:
+        """
+        Test de-/serialisation of Geschaeftsobjekt
+        """
+        assert_serialization_roundtrip(geschaeftsobjekt)
 
     def test_no_list_in_externen_referenzen(self) -> None:
         with pytest.raises(ValidationError) as excinfo:
             _ = Geschaeftsobjekt(
                 typ=Typ.ENERGIEMENGE,
-                externe_referenzen=ExterneReferenz(ex_ref_name="Schufa-ID", ex_ref_wert="aksdlakoeuhn"),  # type: ignore[arg-type]
+                zusatz_attribute=ZusatzAttribut(name="Schufa-ID", wert="aksdlakoeuhn"),  # type: ignore[arg-type]
             )
         # The error message is completely broken, but who cares
-        assert "4 validation error" in str(excinfo.value)
+        assert "2 validation error" in str(excinfo.value)
         assert "type=model_type" in str(excinfo.value)
diff --git a/tests/test_geschaeftspartner.py b/tests/test_geschaeftspartner.py
index 44b7fc9de..597257c13 100644
--- a/tests/test_geschaeftspartner.py
+++ b/tests/test_geschaeftspartner.py
@@ -1,135 +1,55 @@
-import json
-from pathlib import Path
-
 import pytest
-from pydantic import ValidationError
 
-from bo4e import Adresse, Anrede, Geschaeftspartner, Geschaeftspartnerrolle, Kontaktart, Landescode, Typ
+from bo4e import Adresse, Anrede, Geschaeftspartner, Geschaeftspartnerrolle, Kontaktart, Landescode
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestGeschaeftspartner:
-    @pytest.mark.datafiles("./tests/test_data/test_data_adresse/test_data_adresse_only_required_fields.json")
-    def test_serializable(self, datafiles: Path) -> None:
-        with open(datafiles / "test_data_adresse_only_required_fields.json", encoding="utf-8") as json_file:
-            address_test_data = json.load(json_file)
-
-        gp = Geschaeftspartner(
-            anrede=Anrede.FRAU,
-            name1="von Sinnen",
-            name2="Helga",
-            name3=None,
-            ist_gewerbe=True,
-            hrnummer="HRB 254466",
-            amtsgericht="Amtsgericht München",
-            kontaktweg=[Kontaktart.E_MAIL],
-            umsatzsteuer_id="DE267311963",
-            glaeubiger_id="DE98ZZZ09999999999",
-            e_mail_adresse="test@bo4e.de",
-            website="bo4e.de",
-            geschaeftspartnerrolle=[Geschaeftspartnerrolle.DIENSTLEISTER],
-            partneradresse=Adresse(
-                postleitzahl=address_test_data["postleitzahl"],
-                ort=address_test_data["ort"],
-                strasse=address_test_data["strasse"],
-                hausnummer=address_test_data["hausnummer"],
+    @pytest.mark.parametrize(
+        "geschaeftspartner",
+        [
+            pytest.param(
+                Geschaeftspartner(
+                    anrede=Anrede.FRAU,
+                    name1="von Sinnen",
+                    name2="Helga",
+                    name3=None,
+                    ist_gewerbe=True,
+                    hrnummer="HRB 254466",
+                    amtsgericht="Amtsgericht München",
+                    kontaktweg=[Kontaktart.E_MAIL],
+                    umsatzsteuer_id="DE267311963",
+                    glaeubiger_id="DE98ZZZ09999999999",
+                    e_mail_adresse="test@bo4e.de",
+                    website="bo4e.de",
+                    geschaeftspartnerrolle=[Geschaeftspartnerrolle.DIENSTLEISTER],
+                    partneradresse=Adresse(),
+                ),
+                id="all attributes at first level",
             ),
-        )
-
-        # test default value for typ in Geschaeftspartner
-        assert gp.typ == Typ.GESCHAEFTSPARTNER
-
-        gp_json = gp.model_dump_json(by_alias=True)
-
-        assert "Helga" in gp_json
-
-        gp_deserialized = Geschaeftspartner.model_validate_json(gp_json)
-
-        assert gp_deserialized.typ == gp.typ
-        assert type(gp_deserialized.partneradresse) == Adresse
-
-    def test_optional_attribute_partneradresse(self) -> None:
-        """
-        The BO4E standard does not yet define whether the partneradresse is mandatory or not.
-        We will set this as an optional argument until the standard is clear about it.
-
-        This test checks whether the Geschaeftspartner can also be initialized without a partneradresse.
-        """
-
-        gp = Geschaeftspartner(
-            anrede=Anrede.FRAU,
-            name1="von Sinnen",
-            name2="Helga",
-            name3=None,
-            ist_gewerbe=True,
-            hrnummer="HRB 254466",
-            amtsgericht="Amtsgericht München",
-            kontaktweg=[Kontaktart.E_MAIL],
-            umsatzsteuer_id="DE267311963",
-            glaeubiger_id="DE98ZZZ09999999999",
-            e_mail_adresse="test@bo4e.de",
-            website="bo4e.de",
-            geschaeftspartnerrolle=[Geschaeftspartnerrolle.DIENSTLEISTER],
-        )
-
-        gp_json = gp.model_dump_json(by_alias=True)
-        gp_deserialized = Geschaeftspartner.model_validate_json(gp_json)
-
-        assert gp_deserialized.partneradresse is None
-
-    def test_list_validation_of_geschaeftspartnerrolle(self) -> None:
-        """
-        Tests that if the geschaeftspartnerrolle of Geschaeftspartner is not a list, an error is raised.
-
-        The attribute geschaeftspartnerrolle of Geschaeftspartner must be a list type.
-        Therefore the list validator checks the type of geschaeftspartnerrolle
-        during the initialization of Geschaeftspartner.
-        """
-
-        with pytest.raises(ValidationError) as excinfo:
-            _ = Geschaeftspartner(
-                anrede=Anrede.FRAU,
-                name1="von Sinnen",
-                name2="Helga",
-                name3=None,
-                ist_gewerbe=True,
-                hrnummer="HRB 254466",
-                amtsgericht="Amtsgericht München",
-                kontaktweg=[Kontaktart.E_MAIL],
-                umsatzsteuer_id="DE267311963",
-                glaeubiger_id="DE98ZZZ09999999999",
-                e_mail_adresse="test@bo4e.de",
-                website="bo4e.de",
-                geschaeftspartnerrolle=Geschaeftspartnerrolle.DIENSTLEISTER,  # type: ignore[arg-type]
-                partneradresse=Adresse(
-                    postleitzahl="01069",
-                    ort="Dresden",
-                    strasse="Goethestraße",
-                    hausnummer="1",
+            pytest.param(
+                Geschaeftspartner(
+                    anrede=Anrede.FRAU,
+                    name1="Kurz",
+                    name2="Sebastian",
+                    name3=None,
+                    ist_gewerbe=True,
+                    hrnummer="HRB 254466",
+                    amtsgericht="Amtsgericht Ibiza",
+                    kontaktweg=[Kontaktart.E_MAIL],
+                    umsatzsteuer_id="AT12345",
+                    geschaeftspartnerrolle=[Geschaeftspartnerrolle.DIENSTLEISTER],
+                    partneradresse=Adresse(
+                        postleitzahl="1014", ort="Wien 1", strasse="Ballhausplatz", hausnummer="2", landescode=Landescode.AT  # type: ignore[attr-defined]
+                    ),
                 ),
-            )
-
-        assert "1 validation error" in str(excinfo.value)
-        assert "type=list_type" in str(excinfo.value)
-
-    def test_serialization_of_non_german_address(self) -> None:
+                id="Landescode!=DE, DE is default",
+            ),
+        ],
+    )
+    def test_serialization_roundtrip(self, geschaeftspartner: Geschaeftspartner) -> None:
         """
-        Test that partneradresses with a Landescode!=DE (default) are (de)serialized correctly.
+        Test de-/serialisation of Geschaeftspartner.
         """
-        gp = Geschaeftspartner(
-            anrede=Anrede.FRAU,
-            name1="Kurz",
-            name2="Sebastian",
-            name3=None,
-            ist_gewerbe=True,
-            hrnummer="HRB 254466",
-            amtsgericht="Amtsgericht Ibiza",
-            kontaktweg=[Kontaktart.E_MAIL],
-            umsatzsteuer_id="AT12345",
-            geschaeftspartnerrolle=[Geschaeftspartnerrolle.DIENSTLEISTER],
-            partneradresse=Adresse(
-                postleitzahl="1014", ort="Wien 1", strasse="Ballhausplatz", hausnummer="2", landescode=Landescode.AT  # type: ignore[attr-defined]
-            ),
-        )
-        gp_json = gp.model_dump_json(by_alias=True)
-        gp_deserialized = Geschaeftspartner.model_validate_json(gp_json)
-        assert gp_deserialized.partneradresse.landescode == Landescode.AT  # type: ignore[attr-defined, union-attr]
+
+        assert_serialization_roundtrip(geschaeftspartner)
diff --git a/tests/test_katasteradresse.py b/tests/test_katasteradresse.py
index dcdbb7be6..7375a9f18 100644
--- a/tests/test_katasteradresse.py
+++ b/tests/test_katasteradresse.py
@@ -1,14 +1,21 @@
+import pytest
+
 from bo4e import Katasteradresse
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestKatasteradresse:
-    def test_serialization(self) -> None:
-        ka = Katasteradresse(gemarkung_flur="hello", flurstueck="world")
-
-        json_string = ka.model_dump_json(by_alias=True)
-
-        assert "gemarkungFlur" in json_string, "No camel case serialization"
-
-        deserialized_ka: Katasteradresse = Katasteradresse.model_validate_json(json_string)
+    @pytest.mark.parametrize(
+        "katasteradresse",
+        [
+            pytest.param(
+                Katasteradresse(gemarkung_flur="hello", flurstueck="world"), id="all attributes at first level"
+            ),
+        ],
+    )
+    def test_serialization_roundtrip(self, katasteradresse: Katasteradresse) -> None:
+        """
+        Test de-/serialisation of Katasteradresse.
+        """
 
-        assert ka.gemarkung_flur == deserialized_ka.gemarkung_flur
+        assert_serialization_roundtrip(katasteradresse)
diff --git a/tests/test_kosten.py b/tests/test_kosten.py
index 45c3b6a54..a6591de40 100644
--- a/tests/test_kosten.py
+++ b/tests/test_kosten.py
@@ -1,21 +1,7 @@
 import pytest
-from pydantic import ValidationError
 
-from bo4e import Kosten, Kostenblock, Kostenklasse
+from bo4e import Betrag, Kosten, Kostenblock, Kostenklasse, Zeitraum
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_betrag import example_betrag
-from tests.test_zeitraum import example_zeitraum
-
-example_kosten = Kosten(
-    kostenklasse=Kostenklasse.FREMDKOSTEN,
-    gueltigkeit=example_zeitraum,
-    kostenbloecke=[
-        Kostenblock(
-            kostenblockbezeichnung="Mein Kostenblock",
-        )
-    ],
-    summe_kosten=[example_betrag],
-)
 
 
 class TestKosten:
@@ -23,13 +9,18 @@ class TestKosten:
         "kosten",
         [
             pytest.param(
-                example_kosten,
-                id="maximal attributes",
+                Kosten(
+                    kostenklasse=Kostenklasse.FREMDKOSTEN,
+                    gueltigkeit=Zeitraum(),
+                    kostenbloecke=[Kostenblock()],
+                    summe_kosten=[Betrag()],
+                ),
+                id="all attributes at first level",
             )
         ],
     )
     def test_serialization_roundtrip(self, kosten: Kosten) -> None:
         """
-        Test de-/serialisation
+        Test de-/serialisation of Kosten.
         """
         assert_serialization_roundtrip(kosten)
diff --git a/tests/test_kostenblock.py b/tests/test_kostenblock.py
index 98f5a360f..68d49361a 100644
--- a/tests/test_kostenblock.py
+++ b/tests/test_kostenblock.py
@@ -1,30 +1,15 @@
 from decimal import Decimal
-from typing import Any, Dict
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import Betrag, Kostenblock, Kostenposition, Mengeneinheit, Preis, Preisstatus, Waehrungscode, Waehrungseinheit
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_sigmoidparameter import example_sigmoidparameter
 
 
 class TestKostenblock:
     @pytest.mark.parametrize(
-        "kostenblock, expected_json_dict",
+        "kostenblock",
         [
-            pytest.param(
-                Kostenblock(
-                    kostenblockbezeichnung="Mein Kostenblock",
-                ),
-                {
-                    "kostenblockbezeichnung": "Mein Kostenblock",
-                    "summeKostenblock": None,
-                    "kostenpositionen": None,
-                    "_id": None,
-                },
-                id="minimal",
-            ),
             pytest.param(
                 Kostenblock(
                     kostenblockbezeichnung="Mein Kostenblock",
@@ -49,41 +34,12 @@ class TestKostenblock:
                         ),
                     ],
                 ),
-                {
-                    "kostenblockbezeichnung": "Mein Kostenblock",
-                    "kostenpositionen": [
-                        {
-                            "positionstitel": "Mudders kostenposition",
-                            "einzelpreis": {
-                                "einheit": Waehrungseinheit.EUR,
-                                "status": Preisstatus.ENDGUELTIG,
-                                "bezugswert": Mengeneinheit.KWH,
-                                "wert": Decimal("3.5"),
-                                "_id": None,
-                            },
-                            "menge": None,
-                            "zeitmenge": None,
-                            "von": None,
-                            "artikelbezeichnung": "Dei Mudder ihr kostenposition",
-                            "artikeldetail": None,
-                            "bis": None,
-                            "betragKostenposition": {
-                                "waehrung": Waehrungseinheit.EUR,
-                                "wert": Decimal("12.5"),
-                                "_id": None,
-                            },
-                            "_id": None,
-                        }
-                    ],
-                    "summeKostenblock": {"waehrung": Waehrungseinheit.EUR, "wert": Decimal("12.5"), "_id": None},
-                    "_id": None,
-                },
-                id="maximal",
+                id="all attributes at first level",
             ),
         ],
     )
-    def test_serialization_roundtrip(self, kostenblock: Kostenblock, expected_json_dict: Dict[str, Any]) -> None:
+    def test_serialization_roundtrip(self, kostenblock: Kostenblock) -> None:
         """
         Test de-/serialisation of kostenblock.
         """
-        assert_serialization_roundtrip(kostenblock, expected_json_dict)
+        assert_serialization_roundtrip(kostenblock)
diff --git a/tests/test_kostenposition.py b/tests/test_kostenposition.py
index 879bdb2ce..d8d030329 100644
--- a/tests/test_kostenposition.py
+++ b/tests/test_kostenposition.py
@@ -1,62 +1,23 @@
 from datetime import datetime, timezone
 from decimal import Decimal
-from typing import Any, Dict
 
 import pytest
-from pydantic import ValidationError
 
-from bo4e import Betrag, Kostenposition, Mengeneinheit, Preis, Preisstatus, Waehrungscode, Waehrungseinheit
+from bo4e import Betrag, Kostenposition, Menge, Mengeneinheit, Preis, Preisstatus, Waehrungscode, Waehrungseinheit
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_menge import example_menge
-from tests.test_sigmoidparameter import example_sigmoidparameter
 
 
 class TestKostenposition:
     @pytest.mark.parametrize(
-        "kostenposition, expected_json_dict",
+        "kostenposition",
         [
-            pytest.param(
-                Kostenposition(
-                    positionstitel="Mudders Preisstaffel",
-                    artikelbezeichnung="Dei Mudder ihr Preisstaffel",
-                    einzelpreis=Preis(
-                        wert=Decimal(3.50),
-                        einheit=Waehrungseinheit.EUR,
-                        bezugswert=Mengeneinheit.KWH,
-                        status=Preisstatus.ENDGUELTIG,
-                    ),
-                    betrag_kostenposition=Betrag(
-                        waehrung=Waehrungscode.EUR,
-                        wert=Decimal(12.5),
-                    ),
-                ),
-                {
-                    "positionstitel": "Mudders Preisstaffel",
-                    "einzelpreis": {
-                        "status": Preisstatus.ENDGUELTIG,
-                        "einheit": Waehrungseinheit.EUR,
-                        "wert": Decimal("3.5"),
-                        "bezugswert": Mengeneinheit.KWH,
-                        "_id": None,
-                    },
-                    "bis": None,
-                    "von": None,
-                    "menge": None,
-                    "zeitmenge": None,
-                    "artikelbezeichnung": "Dei Mudder ihr Preisstaffel",
-                    "artikeldetail": None,
-                    "betragKostenposition": {"waehrung": Waehrungseinheit.EUR, "wert": Decimal("12.5"), "_id": None},
-                    "_id": None,
-                },
-                id="only required attributes",
-            ),
             pytest.param(
                 Kostenposition(
                     positionstitel="Vadders Kostenposition",
                     von=datetime(2013, 5, 1, tzinfo=timezone.utc),
                     bis=datetime(2014, 5, 1, tzinfo=timezone.utc),
                     artikelbezeichnung="Deim Vadder sei Kostenposition",
-                    zeitmenge=example_menge,
+                    zeitmenge=Menge(),
                     einzelpreis=Preis(
                         wert=Decimal(3.50),
                         einheit=Waehrungseinheit.EUR,
@@ -67,41 +28,15 @@ class TestKostenposition:
                         waehrung=Waehrungscode.EUR,
                         wert=Decimal(12.5),
                     ),
-                    menge=example_menge,
+                    menge=Menge(),
                     artikeldetail="foo",
                 ),
-                {
-                    "artikelbezeichnung": "Deim Vadder sei Kostenposition",
-                    "positionstitel": "Vadders Kostenposition",
-                    "menge": {
-                        "wert": Decimal("3.410000000000000142108547152020037174224853515625"),
-                        "einheit": Mengeneinheit.MWH,
-                        "_id": None,
-                    },
-                    "artikeldetail": "foo",
-                    "einzelpreis": {
-                        "bezugswert": Mengeneinheit.KWH,
-                        "status": Preisstatus.ENDGUELTIG,
-                        "wert": Decimal("3.5"),
-                        "einheit": Waehrungseinheit.EUR,
-                        "_id": None,
-                    },
-                    "von": datetime(2013, 5, 1, 0, 0, tzinfo=timezone.utc),
-                    "zeitmenge": {
-                        "wert": Decimal("3.410000000000000142108547152020037174224853515625"),
-                        "einheit": Mengeneinheit.MWH,
-                        "_id": None,
-                    },
-                    "bis": datetime(2014, 5, 1, 0, 0, tzinfo=timezone.utc),
-                    "betragKostenposition": {"wert": Decimal("12.5"), "waehrung": Waehrungseinheit.EUR, "_id": None},
-                    "_id": None,
-                },
-                id="required and optional attributes",
+                id="all attributes at first level",
             ),
         ],
     )
-    def test_serialization_roundtrip(self, kostenposition: Kostenposition, expected_json_dict: Dict[str, Any]) -> None:
+    def test_serialization_roundtrip(self, kostenposition: Kostenposition) -> None:
         """
-        Test de-/serialisation of Kostenposition
+        Test de-/serialisation of Kostenposition.
         """
-        assert_serialization_roundtrip(kostenposition, expected_json_dict)
+        assert_serialization_roundtrip(kostenposition)
diff --git a/tests/test_kriteriumswert.py b/tests/test_kriteriumswert.py
index ce9ad2810..825e429ea 100644
--- a/tests/test_kriteriumswert.py
+++ b/tests/test_kriteriumswert.py
@@ -1,7 +1,4 @@
-from typing import Any, Dict
-
 import pytest
-from pydantic import ValidationError
 
 from bo4e import KriteriumWert, Tarifregionskriterium
 from tests.serialization_helper import assert_serialization_roundtrip
@@ -9,21 +6,18 @@
 
 class TestKriteriumWert:
     @pytest.mark.parametrize(
-        "kriteriumwert, expected_json_dict",
+        "kriteriumwert",
         [
             pytest.param(
                 KriteriumWert(
                     kriterium=Tarifregionskriterium.ORT,
                     wert="Grünwald",
                 ),
-                {"kriterium": Tarifregionskriterium.ORT, "wert": "Grünwald", "_id": None},
             ),
         ],
     )
-    def test_kriteriumwert_serialization_roundtrip(
-        self, kriteriumwert: KriteriumWert, expected_json_dict: Dict[str, Any]
-    ) -> None:
+    def test_kriteriumwert_serialization_roundtrip(self, kriteriumwert: KriteriumWert) -> None:
         """
-        Test de-/serialisation of KriteriumWert with minimal attributes.
+        Test de-/serialisation of KriteriumWert.
         """
-        assert_serialization_roundtrip(kriteriumwert, expected_json_dict)
+        assert_serialization_roundtrip(kriteriumwert)
diff --git a/tests/test_lastgang.py b/tests/test_lastgang.py
index 85881bea7..260ffb88d 100644
--- a/tests/test_lastgang.py
+++ b/tests/test_lastgang.py
@@ -1,25 +1,25 @@
 import pytest
 from _decimal import Decimal
-from pydantic import ValidationError
 
-from bo4e.bo.lastgang import Lastgang
-from bo4e.bo.marktlokation import Marktlokation
-from bo4e.bo.messlokation import Messlokation
-from bo4e.com.adresse import Adresse
-from bo4e.com.menge import Menge
-from bo4e.enum.bilanzierungsmethode import Bilanzierungsmethode
-from bo4e.enum.energierichtung import Energierichtung
-from bo4e.enum.lokationstyp import Lokationstyp
-from bo4e.enum.mengeneinheit import Mengeneinheit
-from bo4e.enum.netzebene import Netzebene
-from bo4e.enum.sparte import Sparte
+from bo4e import (
+    Adresse,
+    Bilanzierungsmethode,
+    Energierichtung,
+    Lastgang,
+    Marktlokation,
+    Menge,
+    Mengeneinheit,
+    Messlokation,
+    Netzebene,
+    Sparte,
+    Zeitreihenwert,
+)
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_zeitreihenwert import example_zeitreihenwert
 
 
 class TestLastgang:
     @pytest.mark.parametrize(
-        "lastgang_kompakt",
+        "lastgang",
         [
             pytest.param(
                 Lastgang(
@@ -27,7 +27,7 @@ class TestLastgang:
                     sparte=Sparte.STROM,
                     obis_kennzahl="1-0:1.8.1",
                     messgroesse=Mengeneinheit.KWH,
-                    werte=[example_zeitreihenwert],
+                    werte=[Zeitreihenwert()],
                     marktlokation=Marktlokation(
                         marktlokations_id="51238696781",
                         sparte=Sparte.GAS,
@@ -47,8 +47,8 @@ class TestLastgang:
             ),
         ],
     )
-    def test_serialization_roundtrip(self, lastgang_kompakt: Lastgang) -> None:
+    def test_serialization_roundtrip(self, lastgang: Lastgang) -> None:
         """
-        Test de-/serialisation
+        Test de-/serialisation of Lastgang.
         """
-        assert_serialization_roundtrip(lastgang_kompakt)
+        assert_serialization_roundtrip(lastgang)
diff --git a/tests/test_marktgebietinfo.py b/tests/test_marktgebietinfo.py
index 5cc4659be..a2adc44ac 100644
--- a/tests/test_marktgebietinfo.py
+++ b/tests/test_marktgebietinfo.py
@@ -1,14 +1,21 @@
+import pytest
+
 from bo4e import MarktgebietInfo
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestMarktgebietinfo:
-    def test_serialization(self) -> None:
-        mgi = MarktgebietInfo(marktgebiet="Gaspool", marktgebietcode="37Z701133MH0000B")
-
-        json_string = mgi.model_dump_json(by_alias=True)
-
-        assert "marktgebiet" in json_string, "No camel case serialization"
-
-        deserialized_mgi: MarktgebietInfo = MarktgebietInfo.model_validate_json(json_string)
+    @pytest.mark.parametrize(
+        "marktgebietinfo",
+        [
+            pytest.param(
+                MarktgebietInfo(marktgebiet="Gaspool", marktgebietcode="37Z701133MH0000B"),
+            ),
+        ],
+    )
+    def test_serialization(self, marktgebietinfo: MarktgebietInfo) -> None:
+        """
+        Test de-/serialisation of Marktgebietinfo.
+        """
 
-        assert mgi == deserialized_mgi
+        assert_serialization_roundtrip(marktgebietinfo)
diff --git a/tests/test_marktlokation.py b/tests/test_marktlokation.py
index e59324ddb..161b18de0 100644
--- a/tests/test_marktlokation.py
+++ b/tests/test_marktlokation.py
@@ -1,102 +1,40 @@
-from decimal import Decimal
-from typing import Tuple
-
 import pytest
-from pydantic import ValidationError
 
 from bo4e import (
     Adresse,
-    Anrede,
     Bilanzierungsmethode,
     Energierichtung,
-    Geokoordinaten,
     Geschaeftspartner,
-    Geschaeftspartnerrolle,
-    Kontaktart,
     Kundentyp,
     Marktlokation,
     Netzebene,
     Sparte,
-    Typ,
 )
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestMaLo:
-    def test_serialisation_only_required_attributes(self) -> None:
+    @pytest.mark.parametrize(
+        "marktlokation",
+        [
+            pytest.param(
+                Marktlokation(
+                    marktlokations_id="51238696781",
+                    sparte=Sparte.GAS,
+                    lokationsadresse=Adresse(),
+                    energierichtung=Energierichtung.EINSP,
+                    bilanzierungsmethode=Bilanzierungsmethode.PAUSCHAL,
+                    ist_unterbrechbar=True,  # optional attribute
+                    netzebene=Netzebene.NSP,
+                    endkunde=Geschaeftspartner(),
+                    kundengruppen=[Kundentyp.GEWERBE, Kundentyp.PRIVAT],
+                )
+            )
+        ],
+    )
+    def test_serialization_roundtrip(self, marktlokation: Marktlokation) -> None:
         """
-        Test serialisation of Marktlokation only with required attributes
+        Test de-/serialisation of Marktlokation.
         """
-        malo = Marktlokation(
-            marktlokations_id="51238696781",
-            sparte=Sparte.GAS,
-            lokationsadresse=Adresse(postleitzahl="04177", ort="Leipzig", hausnummer="1", strasse="Jahnalle"),
-            energierichtung=Energierichtung.EINSP,
-            bilanzierungsmethode=Bilanzierungsmethode.PAUSCHAL,
-            netzebene=Netzebene.NSP,
-        )
-        assert malo.version is not None, "versionstruktur was not automatically set"
-        assert malo.typ is Typ.MARKTLOKATION, "_typ was not automatically set"
-
-        json_string = malo.model_dump_json(by_alias=True)
-
-        assert "_typ" in json_string, "No camel case serialization"
-        assert "marktlokationsId" in json_string, "No camel case serialization"
-
-        deserialized_malo: Marktlokation = Marktlokation.model_validate_json(json_string)
-
-        # check that `deserialized_malo.marktlokations_id` and `malo.marktlokations_id` have the same value
-        # but are **not** the same object.
-        assert deserialized_malo.marktlokations_id == malo.marktlokations_id
-        assert deserialized_malo.marktlokations_id is not malo.marktlokations_id
-        assert deserialized_malo.typ is Typ.MARKTLOKATION
-
-    def test_serialization_required_and_optional_attributes(self) -> None:
-        """
-        Test serialisation of Marktlokation with required attributes and optional attributes
-        """
-        gp = Geschaeftspartner(
-            anrede=Anrede.FRAU,
-            name1="von Sinnen",
-            name2="Helga",
-            name3=None,
-            ist_gewerbe=True,
-            hrnummer="HRB 254466",
-            amtsgericht="Amtsgericht München",
-            kontaktweg=[Kontaktart.E_MAIL],
-            umsatzsteuer_id="DE267311963",
-            glaeubiger_id="DE98ZZZ09999999999",
-            e_mail_adresse="test@bo4e.de",
-            website="bo4e.de",
-            geschaeftspartnerrolle=[Geschaeftspartnerrolle.DIENSTLEISTER],
-            partneradresse=Adresse(
-                postleitzahl="82031",
-                ort="Grünwald",
-                strasse="Nördliche Münchner Straße",
-                hausnummer="27A",
-            ),
-        )
-        malo = Marktlokation(
-            marktlokations_id="51238696781",
-            sparte=Sparte.GAS,
-            lokationsadresse=Adresse(postleitzahl="04177", ort="Leipzig", hausnummer="1", strasse="Jahnalle"),
-            energierichtung=Energierichtung.EINSP,
-            bilanzierungsmethode=Bilanzierungsmethode.PAUSCHAL,
-            ist_unterbrechbar=True,  # optional attribute
-            netzebene=Netzebene.NSP,
-            endkunde=gp,
-            kundengruppen=[Kundentyp.GEWERBE, Kundentyp.PRIVAT],
-        )
-        assert malo.version is not None, "versionstruktur was not automatically set"
-        assert malo.typ == Typ.MARKTLOKATION, "_typ was not automatically set"
-
-        json_string = malo.model_dump_json(by_alias=True)
-
-        assert "_typ" in json_string, "No camel case serialization"
-        assert "marktlokationsId" in json_string, "No camel case serialization"
-
-        deserialized_malo: Marktlokation = Marktlokation.model_validate_json(json_string)
 
-        assert deserialized_malo.marktlokations_id == malo.marktlokations_id
-        assert deserialized_malo.marktlokations_id is not malo.marktlokations_id
-        assert deserialized_malo.typ is Typ.MARKTLOKATION
-        assert deserialized_malo.endkunde == gp
+        assert_serialization_roundtrip(marktlokation)
diff --git a/tests/test_marktteilnehmer.py b/tests/test_marktteilnehmer.py
index 238d33d61..086a80ef8 100644
--- a/tests/test_marktteilnehmer.py
+++ b/tests/test_marktteilnehmer.py
@@ -1,42 +1,30 @@
-import json
+import pytest
 
-from bo4e import Adresse, Geschaeftspartnerrolle, Marktrolle, Marktteilnehmer, Rollencodetyp, Sparte, Typ
-
-example_marktteilnehmer = Marktteilnehmer(
-    # required attributes of Marktteilnehmer only
-    marktrolle=Marktrolle.DL,
-    rollencodenummer="9903916000000",
-    rollencodetyp=Rollencodetyp.BDEW,
-    sparte=Sparte.STROM,
-    # required attributes inherited from Geschaeftspartner
-    name1="Netze BW GmbH",
-    ist_gewerbe=True,
-    geschaeftspartnerrolle=[Geschaeftspartnerrolle.DIENSTLEISTER],
-    partneradresse=Adresse(
-        strasse="Schelmenwasenstraße",
-        hausnummer="15",
-        postleitzahl="70567",
-        ort="Stuttgart",
-    ),
-)
+from bo4e import Adresse, Geschaeftspartnerrolle, Marktrolle, Marktteilnehmer, Rollencodetyp, Sparte
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestMarktteilnehmer:
-    def test_serialization(self) -> None:
-        mt = example_marktteilnehmer
-
-        assert mt.version is not None, "versionstruktur was not automatically set"
-        assert mt.typ == Typ.MARKTTEILNEHMER, "_typ was not automatically set"
-
-        json_string = mt.model_dump_json(by_alias=True)
-        json_dict = json.loads(json_string)
-
-        # Test camelcase
-        assert "_typ" in json_dict
-        assert "marktrolle" in json_dict
-
-        deserialized_mt: Marktteilnehmer = Marktteilnehmer.model_validate_json(json_string)
-
-        assert mt.marktrolle is deserialized_mt.marktrolle
-        # Test snakecase
-        assert deserialized_mt.typ is Typ.MARKTTEILNEHMER
+    @pytest.mark.parametrize(
+        "marktteilnehmer",
+        [
+            pytest.param(
+                Marktteilnehmer(
+                    marktrolle=Marktrolle.DL,
+                    rollencodenummer="9903916000000",
+                    rollencodetyp=Rollencodetyp.BDEW,
+                    sparte=Sparte.STROM,
+                    name1="Netze BW GmbH",
+                    ist_gewerbe=True,
+                    geschaeftspartnerrolle=[Geschaeftspartnerrolle.DIENSTLEISTER],
+                    partneradresse=Adresse(),
+                )
+            )
+        ],
+    )
+    def test_serialization_roundtrip(self, marktteilnehmer: Marktteilnehmer) -> None:
+        """
+        Test de-/serialisation of Marktteilnehmer.
+        """
+
+        assert_serialization_roundtrip(marktteilnehmer)
diff --git a/tests/test_menge.py b/tests/test_menge.py
index b9b4c4fb1..2fb62082d 100644
--- a/tests/test_menge.py
+++ b/tests/test_menge.py
@@ -4,33 +4,24 @@
 from pydantic import ValidationError
 
 from bo4e import Menge, Mengeneinheit
-
-example_menge = Menge(wert=Decimal(3.41), einheit=Mengeneinheit.MWH)
-# see issue https://github.com/Hochfrequenz/BO4E-python/issues/249
-example_menge_dict = {
-    "wert": Decimal("3.410000000000000142108547152020037174224853515625"),
-    "einheit": Mengeneinheit.MWH,
-    "_id": None,
-}
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestMenge:
-    def test_menge(self) -> None:
+    @pytest.mark.parametrize(
+        "menge",
+        [
+            pytest.param(
+                Menge(wert=Decimal(3.41), einheit=Mengeneinheit.MWH),
+            )
+        ],
+    )
+    def test_serialization_roundtrip(self, menge: Menge) -> None:
         """
-        Test de-/serialisation of Menge (only has required attributes).
+        Test de-/serialisation of Menge.
         """
 
-        json_string = example_menge.model_dump_json(by_alias=True)
-
-        assert "3.41" in json_string
-        assert "MWH" in json_string
-
-        menge_deserialized = Menge.model_validate_json(json_string)
-
-        assert isinstance(menge_deserialized.wert, Decimal)
-        assert menge_deserialized.wert == Decimal(3.41)
-        assert isinstance(menge_deserialized.einheit, Mengeneinheit)
-        assert menge_deserialized.einheit == Mengeneinheit.MWH
+        assert_serialization_roundtrip(menge)
 
     def test_wrong_datatype(self) -> None:
         """
diff --git a/tests/test_messlokation.py b/tests/test_messlokation.py
index 66c6ffeab..a939090cf 100644
--- a/tests/test_messlokation.py
+++ b/tests/test_messlokation.py
@@ -1,143 +1,37 @@
-import json
-from datetime import datetime
-from decimal import Decimal
-from typing import Any, Dict
-
 import pytest
-from pydantic import ValidationError
 
-from bo4e import (
-    Adresse,
-    Dienstleistung,
-    Dienstleistungstyp,
-    Energierichtung,
-    ExterneReferenz,
-    Geraet,
-    Geraeteklasse,
-    Geraetetyp,
-    Mengeneinheit,
-    Messlokation,
-    Netzebene,
-    Registeranzahl,
-    Sparte,
-    Typ,
-    Zaehler,
-    Zaehlerauspraegung,
-    Zaehlertyp,
-    Zaehlwerk,
-)
+from bo4e import Adresse, Dienstleistung, Geraet, Messlokation, Netzebene, Sparte, Zaehler
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestMeLo:
-    def test_serialisation_only_required_attributes(self) -> None:
-        """
-        Test serialisation of Messlokation only with required attributes
-        """
-        melo = Messlokation(
-            messlokations_id="DE00056266802AO6G56M11SN51G21M24S",
-            sparte=Sparte.STROM,
-        )
-        assert melo.version is not None, "versionstruktur was not automatically set"
-        assert melo.typ is Typ.MESSLOKATION, "_typ was not automatically set"
-
-        json_string = melo.model_dump_json(by_alias=True)
-        json_dict = json.loads(json_string)
-
-        assert "_typ" in json_dict, "No camel case serialization"
-        assert "messlokationsId" in json_dict, "No camel case serialization"
-
-        deserialized_melo: Messlokation = Messlokation.model_validate_json(json_string)
-
-        # check that `deserialized_malo.marktlokations_id` and `malo.marktlokations_id` have the same value
-        # but are **not** the same object.
-        assert deserialized_melo.messlokations_id == melo.messlokations_id
-        assert deserialized_melo.messlokations_id is not melo.messlokations_id
-        assert deserialized_melo.typ is Typ.MESSLOKATION
-
-    def test_serialization_required_and_optional_attributes(self) -> None:
-        """
-        Test serialisation of Messlokation with required attributes and optional attributes
-        """
-
-        melo = Messlokation(
-            messlokations_id="DE00056266802AO6G56M11SN51G21M24S",
-            sparte=Sparte.STROM,
-            netzebene_messung=Netzebene.MSP,
-            messgebietnr="664073",
-            geraete=[
-                Geraet(
-                    geraetetyp=Geraetetyp.INTELLIGENTES_MESSYSTEM,
-                    bezeichnung="intelligentes Messsystem",
-                    geraetenummer="123",
-                ),
-                Geraet(
-                    geraeteklasse=Geraeteklasse.WANDLER,
-                    geraetetyp=Geraetetyp.BLOCKSTROMWANDLER,
-                    bezeichnung="56k Modem",
-                    geraetenummer="456",
-                ),
-            ],
-            messdienstleistung=[
-                Dienstleistung(
-                    dienstleistungstyp=Dienstleistungstyp.AUSLESUNG_TAEGLICH_FERNAUSLESUNG,
-                    bezeichnung="fernauslesung_taeglich",
-                ),
-                Dienstleistung(
-                    dienstleistungstyp=Dienstleistungstyp.ENTSPERRUNG,
-                    bezeichnung="entsperrung",
-                ),
-            ],
-            messlokationszaehler=[
-                Zaehler(
-                    zaehlernummer="000111222",
+    @pytest.mark.parametrize(
+        "melo",
+        [
+            pytest.param(
+                Messlokation(
+                    messlokations_id="DE00056266802AO6G56M11SN51G21M24S",
                     sparte=Sparte.STROM,
-                    zaehlerauspraegung=Zaehlerauspraegung.EINRICHTUNGSZAEHLER,
-                    zaehlwerke=[
-                        Zaehlwerk(
-                            zaehlwerk_id="98765",
-                            einheit=Mengeneinheit.KW,
-                            richtung=Energierichtung.EINSP,
-                            bezeichnung="my zaehlwerk",
-                            obis_kennzahl="1-0:1.8.1",
-                            wandlerfaktor=Decimal(0.95),
-                        )
+                    netzebene_messung=Netzebene.MSP,
+                    messgebietnr="664073",
+                    geraete=[
+                        Geraet(),
+                        Geraet(),
+                    ],
+                    messdienstleistung=[
+                        Dienstleistung(),
+                        Dienstleistung(),
                     ],
-                    zaehlertyp=Zaehlertyp.DREHSTROMZAEHLER,
-                    registeranzahl=Registeranzahl.ZWEITARIF,
-                    zaehlerkonstante=Decimal(0.9),
-                    eichung_bis=datetime(2022, 1, 1, 0, 0, 0),
-                    externe_referenzen=[ExterneReferenz(ex_ref_name="zaehler im anderen system", ex_ref_wert="7890")],
-                    letzte_eichung=datetime(2019, 6, 30, 0, 0, 0),
+                    messlokationszaehler=[Zaehler()],
+                    grundzustaendiger_msb_codenr="9910125000002",
+                    messadresse=Adresse(),
                 )
-            ],
-            grundzustaendiger_msb_codenr="9910125000002",
-            messadresse=Adresse(postleitzahl="04177", ort="Leipzig", hausnummer="1", strasse="Jahnalle"),
-        )
-        assert melo.version is not None, "versionstruktur was not automatically set"
-        assert melo.typ == Typ.MESSLOKATION, "_typ was not automatically set"
-
-        json_string = melo.model_dump_json(by_alias=True)
-        json_dict = json.loads(json_string)
-
-        assert "_typ" in json_dict, "No camel case serialization"
-        assert "messlokationsId" in json_dict, "No camel case serialization"
-
-        deserialized_melo: Messlokation = Messlokation.model_validate_json(json_string)
-
-        assert deserialized_melo.messlokations_id == melo.messlokations_id
-        assert deserialized_melo.messlokations_id is not melo.messlokations_id
-        assert deserialized_melo.typ is Typ.MESSLOKATION
-
-    def test_extension_data(self) -> None:
+            )
+        ],
+    )
+    def test_serialization_roundtrip(self, melo: Messlokation) -> None:
         """
-        tests the behaviour of the json extension data (`extra="allow"`)
+        Test de-/serialisation of Messlokation.
         """
-        melo = Messlokation(
-            messlokations_id="DE00056266802AO6G56M11SN51G21M24S",
-            sparte=Sparte.STROM,
-        )
-        melo_json: Dict[str, Any] = melo.model_dump()
-        melo_json["additional_key"] = "additional_value"
-        deserialized_melo: Messlokation = Messlokation.model_validate(melo_json)
-        assert isinstance(deserialized_melo, Messlokation)
-        assert deserialized_melo.additional_key == "additional_value"  # type:ignore[attr-defined]
+
+        assert_serialization_roundtrip(melo)
diff --git a/tests/test_messlokationszuordnung.py b/tests/test_messlokationszuordnung.py
index 1b3431a0a..a6c5a9e42 100644
--- a/tests/test_messlokationszuordnung.py
+++ b/tests/test_messlokationszuordnung.py
@@ -1,57 +1,28 @@
 from datetime import datetime
 
+import pytest
+
 from bo4e import ArithmetischeOperation, Messlokationszuordnung
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestMesslokationszuordnung:
-    def test_serialisation_only_required_attributes(self) -> None:
+    @pytest.mark.parametrize(
+        "messlokationszuordnung",
+        [
+            pytest.param(
+                Messlokationszuordnung(
+                    messlokations_id="DE0010688516810000000000000012345",
+                    arithmetik=ArithmetischeOperation.ADDITION,
+                    gueltig_seit=datetime(year=2021, month=1, day=13),
+                    gueltig_bis=datetime(year=2021, month=5, day=4),
+                )
+            )
+        ],
+    )
+    def test_serialization_roundtrip(self, messlokationszuordnung: Messlokationszuordnung) -> None:
         """
-        Test serialisation of Messlokationszuordnung with required attributes only
+        Test de-/serialisation of Messlokationszuordnung.
         """
-        messlokations_id = "DE0010688516810000000000000012345"
-
-        mlz = Messlokationszuordnung(
-            messlokations_id=messlokations_id,
-            arithmetik=ArithmetischeOperation.ADDITION,
-        )
-
-        json_string = mlz.model_dump_json(by_alias=True)
-
-        assert messlokations_id in json_string
-        assert "ADDITION" in json_string
-
-        mlz_deserialized = Messlokationszuordnung.model_validate_json(json_string)
-
-        assert mlz_deserialized.messlokations_id == messlokations_id
-        assert mlz_deserialized.arithmetik == ArithmetischeOperation.ADDITION
-
-    def test_serialisation_required_and_optional_attributes(self) -> None:
-        """
-        Test serialisation of Messlokationszuordnung with required and optional attributes
-        """
-        messlokations_id = "DE0010688516810000000000000012345"
-
-        mlz = Messlokationszuordnung(
-            messlokations_id=messlokations_id,
-            arithmetik=ArithmetischeOperation.ADDITION,
-            gueltig_seit=datetime(year=2021, month=1, day=13),
-            gueltig_bis=datetime(year=2021, month=5, day=4),
-        )
-
-        mlz_json = mlz.model_dump_json(by_alias=True)
-
-        # CamelCase keys are made because they will put into JSON strings
-        # to send them to the frontend (= JavaScript land)
-        assert "messlokationsId" in mlz_json
-        assert messlokations_id in mlz_json
-        assert "arithmetik" in mlz_json
-        assert "ADDITION" in mlz_json
-        assert "gueltigSeit" in mlz_json
-        assert "2021-01-13T00:00:00" in mlz_json
-
-        mlz_deserialized = Messlokationszuordnung.model_validate_json(mlz_json)
 
-        assert mlz_deserialized.messlokations_id == messlokations_id
-        assert mlz_deserialized.arithmetik == ArithmetischeOperation.ADDITION
-        assert mlz_deserialized.gueltig_seit == datetime(year=2021, month=1, day=13)
-        assert mlz_deserialized.gueltig_bis == datetime(year=2021, month=5, day=4)
+        assert_serialization_roundtrip(messlokationszuordnung)
diff --git a/tests/test_positionsaufabschlag.py b/tests/test_positionsaufabschlag.py
index 21223124a..c00aba6d3 100644
--- a/tests/test_positionsaufabschlag.py
+++ b/tests/test_positionsaufabschlag.py
@@ -1,8 +1,6 @@
 from decimal import Decimal
-from typing import Any, Dict
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import AufAbschlagstyp, PositionsAufAbschlag, Waehrungseinheit
 from tests.serialization_helper import assert_serialization_roundtrip
@@ -10,7 +8,7 @@
 
 class TestPositionsAufAbschlag:
     @pytest.mark.parametrize(
-        "positionsaufabschlag, expected_json_dict",
+        "positionsaufabschlag",
         [
             pytest.param(
                 PositionsAufAbschlag(
@@ -20,21 +18,11 @@ class TestPositionsAufAbschlag:
                     auf_abschlagswert=Decimal(4.25),
                     auf_abschlagswaehrung=Waehrungseinheit.EUR,
                 ),
-                {
-                    "bezeichnung": "foo",
-                    "beschreibung": "bar",
-                    "aufAbschlagstyp": AufAbschlagstyp.ABSOLUT,
-                    "aufAbschlagswert": Decimal("4.25"),
-                    "aufAbschlagswaehrung": Waehrungseinheit.EUR,
-                    "_id": None,
-                },
             ),
         ],
     )
-    def test_serialization_roundtrip(
-        self, positionsaufabschlag: PositionsAufAbschlag, expected_json_dict: Dict[str, Any]
-    ) -> None:
+    def test_serialization_roundtrip(self, positionsaufabschlag: PositionsAufAbschlag) -> None:
         """
-        Test de-/serialisation of PositionsAufAbschlag
+        Test de-/serialisation of PositionsAufAbschlag.
         """
-        assert_serialization_roundtrip(positionsaufabschlag, expected_json_dict)
+        assert_serialization_roundtrip(positionsaufabschlag)
diff --git a/tests/test_preis.py b/tests/test_preis.py
index f3f9154a9..b5d9c99f1 100644
--- a/tests/test_preis.py
+++ b/tests/test_preis.py
@@ -4,31 +4,10 @@
 from pydantic import ValidationError
 
 from bo4e import Mengeneinheit, Preis, Preisstatus, Waehrungseinheit
-
-example_preis = Preis(wert=Decimal(12.5), einheit=Waehrungseinheit.EUR, bezugswert=Mengeneinheit.KWH)
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestPreis:
-    def test_preis_only_required(self) -> None:
-        """
-        Test de-/serialisation of Preis (only has required attributes).
-        """
-        preis = example_preis
-
-        json_string = preis.model_dump_json(by_alias=True)
-
-        assert "KWH" in json_string
-        assert "EUR" in json_string
-        assert "null" in json_string
-
-        preis_deserialized = Preis.model_validate_json(json_string)
-
-        assert isinstance(preis_deserialized.wert, Decimal)
-        assert isinstance(preis_deserialized.einheit, Waehrungseinheit)
-        assert isinstance(preis_deserialized.bezugswert, Mengeneinheit)
-        assert preis_deserialized.status is None
-        assert preis == preis_deserialized
-
     def test_wrong_datatype(self) -> None:
         with pytest.raises(ValidationError) as excinfo:
             _ = Preis(wert="lululululu", einheit=Waehrungseinheit.EUR, bezugswert=Mengeneinheit.KWH)  # type: ignore[arg-type]
@@ -37,18 +16,21 @@ def test_wrong_datatype(self) -> None:
         assert "wert" in str(excinfo.value)
         assert "type=decimal_parsing" in str(excinfo.value)
 
-    def test_optional_attribute(self) -> None:
-        preis = Preis(
-            wert=Decimal(3.50),
-            einheit=Waehrungseinheit.EUR,
-            bezugswert=Mengeneinheit.KWH,
-            status=Preisstatus.ENDGUELTIG,
-        )
-
-        json_string = preis.model_dump_json(by_alias=True)
-
-        assert "ENDGUELTIG" in json_string
-
-        preis_deserialized = Preis.model_validate_json(json_string)
-
-        assert isinstance(preis_deserialized.status, Preisstatus)
+    @pytest.mark.parametrize(
+        "preis",
+        [
+            pytest.param(
+                Preis(
+                    wert=Decimal(3.50),
+                    einheit=Waehrungseinheit.EUR,
+                    bezugswert=Mengeneinheit.KWH,
+                    status=Preisstatus.ENDGUELTIG,
+                ),
+            ),
+        ],
+    )
+    def test_serialization_roundtrip(self, preis: Preis) -> None:
+        """
+        Test de-/serialisation of Preis.
+        """
+        assert_serialization_roundtrip(preis)
diff --git a/tests/test_preisblatt.py b/tests/test_preisblatt.py
index e33fb7ef0..7537e7966 100644
--- a/tests/test_preisblatt.py
+++ b/tests/test_preisblatt.py
@@ -1,11 +1,7 @@
 import pytest
-from pydantic import ValidationError
 
-from bo4e import Preisblatt, Preisstatus, Sparte
+from bo4e import Marktteilnehmer, Preisblatt, Preisposition, Preisstatus, Sparte, Zeitraum
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_marktteilnehmer import example_marktteilnehmer
-from tests.test_preisposition import example_preisposition
-from tests.test_zeitraum import example_zeitraum
 
 
 class TestPreisblatt:
@@ -17,15 +13,15 @@ class TestPreisblatt:
                     bezeichnung="foo",
                     sparte=Sparte.STROM,
                     preisstatus=Preisstatus.ENDGUELTIG,
-                    preispositionen=[example_preisposition],
-                    gueltigkeit=example_zeitraum,
-                    herausgeber=example_marktteilnehmer,
+                    preispositionen=[Preisposition()],
+                    gueltigkeit=Zeitraum(),
+                    herausgeber=Marktteilnehmer(),
                 )
             ),
         ],
     )
     def test_serialization_roundtrip(self, preisblatt: Preisblatt) -> None:
         """
-        Test de-/serialisation
+        Test de-/serialisation of Preisblatt.
         """
         assert_serialization_roundtrip(preisblatt)
diff --git a/tests/test_preisblatt_dienstleistung.py b/tests/test_preisblatt_dienstleistung.py
index 951c46b5a..be5e1b20b 100644
--- a/tests/test_preisblatt_dienstleistung.py
+++ b/tests/test_preisblatt_dienstleistung.py
@@ -1,11 +1,17 @@
 import pytest
 
-from bo4e import Bilanzierungsmethode, Dienstleistungstyp, PreisblattDienstleistung, Preisstatus, Sparte
+from bo4e import (
+    Bilanzierungsmethode,
+    Dienstleistungstyp,
+    Geraet,
+    Marktteilnehmer,
+    PreisblattDienstleistung,
+    Preisposition,
+    Preisstatus,
+    Sparte,
+    Zeitraum,
+)
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_geraet import example_geraet
-from tests.test_marktteilnehmer import example_marktteilnehmer
-from tests.test_preisposition import example_preisposition
-from tests.test_zeitraum import example_zeitraum
 
 
 class TestPreisblattDienstleistung:
@@ -17,19 +23,19 @@ class TestPreisblattDienstleistung:
                     bezeichnung="foo",
                     sparte=Sparte.STROM,
                     preisstatus=Preisstatus.ENDGUELTIG,
-                    preispositionen=[example_preisposition],
-                    gueltigkeit=example_zeitraum,
-                    herausgeber=example_marktteilnehmer,
+                    preispositionen=[Preisposition()],
+                    gueltigkeit=Zeitraum(),
+                    herausgeber=Marktteilnehmer(),
                     bilanzierungsmethode=Bilanzierungsmethode.TLP_GEMEINSAM,
                     basisdienstleistung=Dienstleistungstyp.ABLESUNG_MONATLICH,
                     inklusive_dienstleistungen=[Dienstleistungstyp.AUSLESUNG_FERNAUSLESUNG_ZUSAETZLICH_MSB],
-                    geraetedetails=example_geraet,
+                    geraetedetails=Geraet(),
                 )
             ),
         ],
     )
     def test_serialization_roundtrip(self, preisblatt_dienstleistung: PreisblattDienstleistung) -> None:
         """
-        Test de-/serialisation
+        Test de-/serialisation Preisblatt-Dienstleistung.
         """
         assert_serialization_roundtrip(preisblatt_dienstleistung)
diff --git a/tests/test_preisblatt_hardware.py b/tests/test_preisblatt_hardware.py
index b79d6ff8d..6d35d043c 100644
--- a/tests/test_preisblatt_hardware.py
+++ b/tests/test_preisblatt_hardware.py
@@ -1,11 +1,18 @@
 import pytest
 
-from bo4e import Bilanzierungsmethode, Dienstleistungstyp, Netzebene, PreisblattHardware, Preisstatus, Sparte
+from bo4e import (
+    Bilanzierungsmethode,
+    Dienstleistungstyp,
+    Geraet,
+    Marktteilnehmer,
+    Netzebene,
+    PreisblattHardware,
+    Preisposition,
+    Preisstatus,
+    Sparte,
+    Zeitraum,
+)
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_geraet import example_geraet
-from tests.test_marktteilnehmer import example_marktteilnehmer
-from tests.test_preisposition import example_preisposition
-from tests.test_zeitraum import example_zeitraum
 
 
 class TestPreisblattHardware:
@@ -17,20 +24,20 @@ class TestPreisblattHardware:
                     bezeichnung="foo",
                     sparte=Sparte.STROM,
                     preisstatus=Preisstatus.ENDGUELTIG,
-                    preispositionen=[example_preisposition],
-                    gueltigkeit=example_zeitraum,
-                    herausgeber=example_marktteilnehmer,
+                    preispositionen=[Preisposition()],
+                    gueltigkeit=Zeitraum(),
+                    herausgeber=Marktteilnehmer(),
                     bilanzierungsmethode=Bilanzierungsmethode.TLP_GEMEINSAM,
                     messebene=Netzebene.MSP,
                     inklusive_dienstleistungen=[Dienstleistungstyp.AUSLESUNG_FERNAUSLESUNG_ZUSAETZLICH_MSB],
-                    basisgeraet=example_geraet,
-                    inklusive_geraete=[example_geraet],
+                    basisgeraet=Geraet(),
+                    inklusive_geraete=[Geraet()],
                 )
             ),
         ],
     )
     def test_serialization_roundtrip(self, preisblatt_hardware: PreisblattHardware) -> None:
         """
-        Test de-/serialisation
+        Test de-/serialisation Preisblatt-Hardware.
         """
         assert_serialization_roundtrip(preisblatt_hardware)
diff --git a/tests/test_preisblatt_konzessionsabgabe.py b/tests/test_preisblatt_konzessionsabgabe.py
index 9f8d1cd14..3beaa3796 100644
--- a/tests/test_preisblatt_konzessionsabgabe.py
+++ b/tests/test_preisblatt_konzessionsabgabe.py
@@ -1,11 +1,15 @@
 import pytest
-from pydantic import ValidationError
 
-from bo4e import KundengruppeKA, PreisblattKonzessionsabgabe, Preisstatus, Sparte
+from bo4e import (
+    KundengruppeKA,
+    Marktteilnehmer,
+    PreisblattKonzessionsabgabe,
+    Preisposition,
+    Preisstatus,
+    Sparte,
+    Zeitraum,
+)
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_marktteilnehmer import example_marktteilnehmer
-from tests.test_preisposition import example_preisposition
-from tests.test_zeitraum import example_zeitraum
 
 
 class TestPreisblatt:
@@ -17,9 +21,9 @@ class TestPreisblatt:
                     bezeichnung="foo",
                     sparte=Sparte.STROM,
                     preisstatus=Preisstatus.ENDGUELTIG,
-                    preispositionen=[example_preisposition],
-                    gueltigkeit=example_zeitraum,
-                    herausgeber=example_marktteilnehmer,
+                    preispositionen=[Preisposition()],
+                    gueltigkeit=Zeitraum(),
+                    herausgeber=Marktteilnehmer(),
                     kundengruppe_k_a=KundengruppeKA.G_SONDERKUNDE,
                 )
             ),
@@ -27,6 +31,6 @@ class TestPreisblatt:
     )
     def test_serialization_roundtrip(self, preisblatt_ka: PreisblattKonzessionsabgabe) -> None:
         """
-        Test de-/serialisation
+        Test de-/serialisation Preisblatt-Konzessionsabgabe.
         """
         assert_serialization_roundtrip(preisblatt_ka)
diff --git a/tests/test_preisblatt_messung.py b/tests/test_preisblatt_messung.py
index aadeeb17c..219686df9 100644
--- a/tests/test_preisblatt_messung.py
+++ b/tests/test_preisblatt_messung.py
@@ -1,12 +1,19 @@
 import pytest
 
-from bo4e import Bilanzierungsmethode, Dienstleistungstyp, Netzebene, PreisblattMessung, Preisstatus, Sparte
+from bo4e import (
+    Bilanzierungsmethode,
+    Dienstleistungstyp,
+    Geraet,
+    Marktteilnehmer,
+    Netzebene,
+    PreisblattMessung,
+    Preisposition,
+    Preisstatus,
+    Sparte,
+    Zaehler,
+    Zeitraum,
+)
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_geraet import example_geraet
-from tests.test_marktteilnehmer import example_marktteilnehmer
-from tests.test_preisposition import example_preisposition
-from tests.test_zaehler import example_zaehler
-from tests.test_zeitraum import example_zeitraum
 
 
 class TestPreisblattMessung:
@@ -18,14 +25,14 @@ class TestPreisblattMessung:
                     bezeichnung="foo",
                     sparte=Sparte.STROM,
                     preisstatus=Preisstatus.ENDGUELTIG,
-                    preispositionen=[example_preisposition],
-                    gueltigkeit=example_zeitraum,
-                    herausgeber=example_marktteilnehmer,
+                    preispositionen=[Preisposition()],
+                    gueltigkeit=Zeitraum(),
+                    herausgeber=Marktteilnehmer(),
                     bilanzierungsmethode=Bilanzierungsmethode.TLP_GEMEINSAM,
                     messebene=Netzebene.MSP,
                     inklusive_dienstleistungen=[Dienstleistungstyp.AUSLESUNG_FERNAUSLESUNG_ZUSAETZLICH_MSB],
-                    zaehler=example_zaehler,
-                    inklusive_geraete=[example_geraet],
+                    zaehler=Zaehler(),
+                    inklusive_geraete=[Geraet()],
                 )
             ),
         ],
diff --git a/tests/test_preisblattnetznutzung.py b/tests/test_preisblattnetznutzung.py
index 370e92285..d902a43aa 100644
--- a/tests/test_preisblattnetznutzung.py
+++ b/tests/test_preisblattnetznutzung.py
@@ -1,11 +1,17 @@
 import pytest
-from pydantic import ValidationError
 
-from bo4e import Bilanzierungsmethode, Kundengruppe, Netzebene, PreisblattNetznutzung, Preisstatus, Sparte
+from bo4e import (
+    Bilanzierungsmethode,
+    Kundengruppe,
+    Marktteilnehmer,
+    Netzebene,
+    PreisblattNetznutzung,
+    Preisposition,
+    Preisstatus,
+    Sparte,
+    Zeitraum,
+)
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_marktteilnehmer import example_marktteilnehmer
-from tests.test_preisposition import example_preisposition
-from tests.test_zeitraum import example_zeitraum
 
 
 class TestPreisblatt:
@@ -17,9 +23,9 @@ class TestPreisblatt:
                     bezeichnung="foo",
                     sparte=Sparte.STROM,
                     preisstatus=Preisstatus.ENDGUELTIG,
-                    preispositionen=[example_preisposition],
-                    gueltigkeit=example_zeitraum,
-                    herausgeber=example_marktteilnehmer,
+                    preispositionen=[Preisposition()],
+                    gueltigkeit=Zeitraum(),
+                    herausgeber=Marktteilnehmer(),
                     bilanzierungsmethode=Bilanzierungsmethode.TLP_GEMEINSAM,
                     netzebene=Netzebene.MSP,
                     kundengruppe=Kundengruppe.SLP_G_GKO,
diff --git a/tests/test_preisgarantie.py b/tests/test_preisgarantie.py
index 7512c0677..5e5ec9447 100644
--- a/tests/test_preisgarantie.py
+++ b/tests/test_preisgarantie.py
@@ -1,48 +1,28 @@
 from datetime import datetime, timezone
-from typing import Any, Dict
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import Preisgarantie, Preisgarantietyp, Zeitraum
 from tests.serialization_helper import assert_serialization_roundtrip
 
-example_preisgarantie = Preisgarantie(
-    preisgarantietyp=Preisgarantietyp.NUR_ENERGIEPREIS,
-    zeitliche_gueltigkeit=Zeitraum(
-        startdatum=datetime(2020, 1, 1, tzinfo=timezone.utc),
-        enddatum=datetime(2020, 4, 1, tzinfo=timezone.utc),
-    ),
-)
-
 
 class TestPreisgarantie:
     @pytest.mark.parametrize(
-        "preisgarantie, expected_json_dict",
+        "preisgarantie",
         [
             pytest.param(
-                example_preisgarantie,
-                {
-                    "beschreibung": None,
-                    "preisgarantietyp": "NUR_ENERGIEPREIS",
-                    "zeitlicheGueltigkeit": {
-                        "startdatum": datetime(2020, 1, 1, 0, 0, tzinfo=timezone.utc),
-                        "endzeitpunkt": None,
-                        "einheit": None,
-                        "enddatum": datetime(2020, 4, 1, 0, 0, tzinfo=timezone.utc),
-                        "startzeitpunkt": None,
-                        "dauer": None,
-                        "_id": None,
-                    },
-                    "_id": None,
-                },
+                Preisgarantie(
+                    preisgarantietyp=Preisgarantietyp.NUR_ENERGIEPREIS,
+                    zeitliche_gueltigkeit=Zeitraum(
+                        startdatum=datetime(2020, 1, 1, tzinfo=timezone.utc),
+                        enddatum=datetime(2020, 4, 1, tzinfo=timezone.utc),
+                    ),
+                ),
             ),
         ],
     )
-    def test_preisgarantie_required_attributes(
-        self, preisgarantie: Preisgarantie, expected_json_dict: Dict[str, Any]
-    ) -> None:
+    def test_preisgarantie_required_attributes(self, preisgarantie: Preisgarantie) -> None:
         """
         Test de-/serialisation of Preisgarantie with minimal attributes.
         """
-        assert_serialization_roundtrip(preisgarantie, expected_json_dict)
+        assert_serialization_roundtrip(preisgarantie)
diff --git a/tests/test_preisposition.py b/tests/test_preisposition.py
index 3257573cb..def7bd5cf 100644
--- a/tests/test_preisposition.py
+++ b/tests/test_preisposition.py
@@ -1,7 +1,6 @@
 from decimal import Decimal
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import (
     BDEWArtikelnummer,
@@ -10,34 +9,34 @@
     Leistungstyp,
     Mengeneinheit,
     Preisposition,
+    Preisstaffel,
     Tarifzeit,
     Waehrungseinheit,
 )
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_preisstaffel import example_preisstaffel
-
-example_preisposition = Preisposition(
-    berechnungsmethode=Kalkulationsmethode.AP_TRANSPORT_ODER_VERTEILNETZ,
-    leistungstyp=Leistungstyp.SONSTIGER_PREIS,
-    leistungsbezeichnung="Foo",
-    preiseinheit=Waehrungseinheit.EUR,
-    bezugsgroesse=Mengeneinheit.KVARH,
-    zeitbasis=Mengeneinheit.HALBJAHR,
-    tarifzeit=Tarifzeit.TZ_HT,
-    bdew_artikelnummer=BDEWArtikelnummer.AUSGLEICHSENERGIE_UNTERDECKUNG,
-    zonungsgroesse=Bemessungsgroesse.BENUTZUNGSDAUER,
-    freimenge_blindarbeit=Decimal(50),  # %
-    freimenge_leistungsfaktor=Decimal(1.0),
-    preisstaffeln=[example_preisstaffel],
-    gruppenartikel_id="1-2-3",
-)
 
 
 class TestPreisposition:
     @pytest.mark.parametrize(
         "preisposition",
         [
-            pytest.param(example_preisposition),
+            pytest.param(
+                Preisposition(
+                    berechnungsmethode=Kalkulationsmethode.AP_TRANSPORT_ODER_VERTEILNETZ,
+                    leistungstyp=Leistungstyp.SONSTIGER_PREIS,
+                    leistungsbezeichnung="Foo",
+                    preiseinheit=Waehrungseinheit.EUR,
+                    bezugsgroesse=Mengeneinheit.KVARH,
+                    zeitbasis=Mengeneinheit.HALBJAHR,
+                    tarifzeit=Tarifzeit.TZ_HT,
+                    bdew_artikelnummer=BDEWArtikelnummer.AUSGLEICHSENERGIE_UNTERDECKUNG,
+                    zonungsgroesse=Bemessungsgroesse.BENUTZUNGSDAUER,
+                    freimenge_blindarbeit=Decimal(50),  # %
+                    freimenge_leistungsfaktor=Decimal(1.0),
+                    preisstaffeln=[Preisstaffel()],
+                    gruppenartikel_id="1-2-3",
+                )
+            ),
         ],
     )
     def test_serialization_roundtrip(self, preisposition: Preisposition) -> None:
diff --git a/tests/test_preisstaffel.py b/tests/test_preisstaffel.py
index 8c24ab8be..cbe9da49e 100644
--- a/tests/test_preisstaffel.py
+++ b/tests/test_preisstaffel.py
@@ -1,62 +1,33 @@
 from decimal import Decimal
-from typing import Any, Dict
+from typing import Any
 
 import pytest
 from pydantic import ValidationError
 
-from bo4e import Preisstaffel
+from bo4e import Preisstaffel, Sigmoidparameter
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_sigmoidparameter import example_sigmoidparameter
-
-example_preisstaffel = Preisstaffel(
-    einheitspreis=Decimal(40.0), staffelgrenze_von=Decimal(12.5), staffelgrenze_bis=Decimal(25.0)
-)
 
 
 class TestPreisstaffel:
     @pytest.mark.parametrize(
-        "preisstaffel, expected_json_dict",
+        "preisstaffel",
         [
             pytest.param(
                 Preisstaffel(
                     einheitspreis=Decimal(40.0),
                     staffelgrenze_von=Decimal(12.5),
                     staffelgrenze_bis=Decimal(25.0),
-                    sigmoidparameter=example_sigmoidparameter,
+                    sigmoidparameter=Sigmoidparameter(),
                 ),
-                {
-                    "einheitspreis": Decimal("40"),
-                    "sigmoidparameter": {
-                        "A": Decimal("1"),
-                        "B": Decimal("2"),
-                        "C": Decimal("3"),
-                        "D": Decimal("4"),
-                        "_id": None,
-                    },
-                    "staffelgrenzeVon": Decimal("12.5"),
-                    "staffelgrenzeBis": Decimal("25"),
-                    "_id": None,
-                },
                 id="all attributes",
             ),
-            pytest.param(
-                example_preisstaffel,
-                {
-                    "einheitspreis": Decimal("40"),
-                    "staffelgrenzeVon": Decimal("12.5"),
-                    "staffelgrenzeBis": Decimal("25"),
-                    "sigmoidparameter": None,
-                    "_id": None,
-                },
-                id="only required params",
-            ),
         ],
     )
-    def test_serialization_roundtrip(self, preisstaffel: Preisstaffel, expected_json_dict: Dict[str, Any]) -> None:
+    def test_serialization_roundtrip(self, preisstaffel: Preisstaffel) -> None:
         """
         Test de-/serialisation of Preisstaffel.
         """
-        assert_serialization_roundtrip(preisstaffel, expected_json_dict)
+        assert_serialization_roundtrip(preisstaffel)
 
     @pytest.mark.parametrize(
         "not_a_sigmoid_parameter",
diff --git a/tests/test_rechnung.py b/tests/test_rechnung.py
index 2daa1dabc..a35190c3c 100644
--- a/tests/test_rechnung.py
+++ b/tests/test_rechnung.py
@@ -2,17 +2,17 @@
 from decimal import Decimal
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import (
     Betrag,
     Geschaeftspartner,
-    Geschaeftspartnerrolle,
     Marktlokation,
+    Menge,
     Mengeneinheit,
     Messlokation,
     NetznutzungRechnungsart,
     NetznutzungRechnungstyp,
+    Preis,
     Rechnung,
     Rechnungsposition,
     Rechnungsstatus,
@@ -24,22 +24,6 @@
     Zeitraum,
 )
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_betrag import example_betrag
-from tests.test_menge import example_menge
-from tests.test_preis import example_preis
-from tests.test_steuerbetrag import example_steuerbetrag
-
-_rechnungsersteller = Geschaeftspartner(
-    name1="Joachim",
-    ist_gewerbe=False,
-    geschaeftspartnerrolle=[Geschaeftspartnerrolle.LIEFERANT],
-)
-
-_rechnungsempfaenger = Geschaeftspartner(
-    name1="Helga",
-    ist_gewerbe=False,
-    geschaeftspartnerrolle=[Geschaeftspartnerrolle.KUNDE],
-)
 
 
 class TestRechnung:
@@ -57,8 +41,8 @@ class TestRechnung:
                     rechnungstyp=Rechnungstyp.ENDKUNDENRECHNUNG,
                     original_rechnungsnummer="RE-2022-01-21_1701",
                     rechnungsperiode=Zeitraum(einheit=Mengeneinheit.TAG, dauer=Decimal(21)),
-                    rechnungsersteller=_rechnungsersteller,
-                    rechnungsempfaenger=_rechnungsempfaenger,
+                    rechnungsersteller=Geschaeftspartner(),
+                    rechnungsempfaenger=Geschaeftspartner(),
                     gesamtnetto=Betrag(wert=Decimal(12.5), waehrung=Waehrungscode.EUR),
                     gesamtsteuer=Betrag(wert=Decimal(12.5), waehrung=Waehrungscode.EUR),
                     gesamtbrutto=Betrag(wert=Decimal(12.5), waehrung=Waehrungscode.EUR),
@@ -79,10 +63,10 @@ class TestRechnung:
                             lieferung_von=datetime(2021, 3, 15, tzinfo=timezone.utc),
                             lieferung_bis=datetime(2022, 3, 15, tzinfo=timezone.utc),
                             positionstext="Besonders wertvolle Rechnungsposition",
-                            positions_menge=example_menge,
-                            einzelpreis=example_preis,
-                            teilsumme_netto=example_betrag,
-                            teilsumme_steuer=example_steuerbetrag,
+                            positions_menge=Menge(),
+                            einzelpreis=Preis(),
+                            teilsumme_netto=Betrag(),
+                            teilsumme_steuer=Steuerbetrag(),
                         )
                     ],
                     sparte=Sparte.STROM,
@@ -108,8 +92,8 @@ class TestRechnung:
                     rechnungstyp=Rechnungstyp.ENDKUNDENRECHNUNG,
                     original_rechnungsnummer="RE-2022-01-21_1701",
                     rechnungsperiode=Zeitraum(einheit=Mengeneinheit.TAG, dauer=Decimal(21)),
-                    rechnungsersteller=_rechnungsersteller,
-                    rechnungsempfaenger=_rechnungsempfaenger,
+                    rechnungsersteller=Geschaeftspartner(),
+                    rechnungsempfaenger=Geschaeftspartner(),
                     gesamtnetto=Betrag(wert=Decimal(12.5), waehrung=Waehrungscode.EUR),
                     gesamtsteuer=Betrag(wert=Decimal(12.5), waehrung=Waehrungscode.EUR),
                     gesamtbrutto=Betrag(wert=Decimal(12.5), waehrung=Waehrungscode.EUR),
@@ -120,10 +104,10 @@ class TestRechnung:
                             lieferung_von=datetime(2021, 3, 15, tzinfo=timezone.utc),
                             lieferung_bis=datetime(2022, 3, 15, tzinfo=timezone.utc),
                             positionstext="Besonders wertvolle Rechnungsposition",
-                            positions_menge=example_menge,
-                            einzelpreis=example_preis,
-                            teilsumme_netto=example_betrag,
-                            teilsumme_steuer=example_steuerbetrag,
+                            positions_menge=Menge(),
+                            einzelpreis=Preis(),
+                            teilsumme_netto=Betrag(),
+                            teilsumme_steuer=Steuerbetrag(),
                         )
                     ],
                     sparte=Sparte.STROM,
diff --git a/tests/test_rechnungsposition.py b/tests/test_rechnungsposition.py
index 360af241e..a2805ff75 100644
--- a/tests/test_rechnungsposition.py
+++ b/tests/test_rechnungsposition.py
@@ -1,14 +1,9 @@
 from datetime import datetime, timezone
 
 import pytest
-from pydantic import ValidationError
 
-from bo4e import BDEWArtikelnummer, Mengeneinheit, Rechnungsposition
+from bo4e import BDEWArtikelnummer, Betrag, Menge, Mengeneinheit, Preis, Rechnungsposition, Steuerbetrag
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_betrag import example_betrag
-from tests.test_menge import example_menge
-from tests.test_preis import example_preis
-from tests.test_steuerbetrag import example_steuerbetrag
 
 
 class TestRechnungsposition:
@@ -24,12 +19,12 @@ class TestRechnungsposition:
                     zeiteinheit=Mengeneinheit.JAHR,
                     artikelnummer=BDEWArtikelnummer.AUSGLEICHSENERGIE_UNTERDECKUNG,
                     lokations_id="51238696781",
-                    positions_menge=example_menge,
-                    zeitbezogene_menge=example_menge,
-                    einzelpreis=example_preis,
-                    teilsumme_netto=example_betrag,
-                    teilrabatt_netto=example_betrag,
-                    teilsumme_steuer=example_steuerbetrag,
+                    positions_menge=Menge(),
+                    zeitbezogene_menge=Menge(),
+                    einzelpreis=Preis(),
+                    teilsumme_netto=Betrag(),
+                    teilrabatt_netto=Betrag(),
+                    teilsumme_steuer=Steuerbetrag(),
                     artikel_id="7-8-9",
                 ),
                 id="maximal attributes",
diff --git a/tests/test_region.py b/tests/test_region.py
index 66dd3dfe2..1c7747611 100644
--- a/tests/test_region.py
+++ b/tests/test_region.py
@@ -1,9 +1,7 @@
 import pytest
-from pydantic import ValidationError
 
-from bo4e import Region
+from bo4e import Region, Regionskriterium
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_regionskriterium import example_regionskriterium
 
 
 class TestRegion:
@@ -13,26 +11,16 @@ class TestRegion:
             pytest.param(
                 Region(
                     bezeichnung="Bikini Bottom",
-                    positiv_liste=[example_regionskriterium],
-                    negativ_liste=[example_regionskriterium],
+                    positiv_liste=[Regionskriterium()],
+                    negativ_liste=[Regionskriterium()],
                 ),
                 id="max attributes",
             ),
-            pytest.param(
-                Region(bezeichnung="Bikini Bottom", positiv_liste=[example_regionskriterium]), id="min attributes"
-            ),
+            pytest.param(Region(bezeichnung="Bikini Bottom", positiv_liste=[Regionskriterium()]), id="min attributes"),
         ],
     )
     def test_serialization_roundtrip(self, region: Region) -> None:
+        """
+        Test de-/serialisation
+        """
         assert_serialization_roundtrip(region)
-
-    def test_region_id(self) -> None:
-        region = Region(
-            bezeichnung="Bikini Bottom",
-            id="foo",
-            positiv_liste=[example_regionskriterium],
-            negativ_liste=[example_regionskriterium],
-        )
-        region_dict = region.model_dump(by_alias=True)
-        assert "_id" in region_dict
-        assert Region.model_validate(region_dict) == region
diff --git a/tests/test_regionalegueltigkeit.py b/tests/test_regionalegueltigkeit.py
index cb6dab69e..5629dde24 100644
--- a/tests/test_regionalegueltigkeit.py
+++ b/tests/test_regionalegueltigkeit.py
@@ -1,7 +1,4 @@
-from typing import Any, Dict
-
 import pytest
-from pydantic import ValidationError
 
 from bo4e import Gueltigkeitstyp, KriteriumWert, RegionaleGueltigkeit, Tarifregionskriterium
 from tests.serialization_helper import assert_serialization_roundtrip
@@ -9,7 +6,7 @@
 
 class TestRegionaleGueltigkeit:
     @pytest.mark.parametrize(
-        "regionalegueltigkeit, expected_json_dict",
+        "regionalegueltigkeit",
         [
             pytest.param(
                 RegionaleGueltigkeit(
@@ -21,19 +18,12 @@ class TestRegionaleGueltigkeit:
                         ),
                     ],
                 ),
-                {
-                    "gueltigkeitstyp": "NUR_IN",
-                    "kriteriumsWerte": [{"kriterium": "NETZ_NUMMER", "wert": "12345", "_id": None}],
-                    "_id": None,
-                },
-                id="only required attributes",
+                id="all attributes at first level",
             ),
         ],
     )
-    def test_regionalegueltigkeit_serialization_roundtrip(
-        self, regionalegueltigkeit: RegionaleGueltigkeit, expected_json_dict: Dict[str, Any]
-    ) -> None:
+    def test_regionalegueltigkeit_serialization_roundtrip(self, regionalegueltigkeit: RegionaleGueltigkeit) -> None:
         """
         Test de-/serialisation of RegionaleGueltigkeit with minimal attributes.
         """
-        assert_serialization_roundtrip(regionalegueltigkeit, expected_json_dict)
+        assert_serialization_roundtrip(regionalegueltigkeit)
diff --git a/tests/test_regionalepreisgarantie.py b/tests/test_regionalepreisgarantie.py
index d649933e9..6ac127c54 100644
--- a/tests/test_regionalepreisgarantie.py
+++ b/tests/test_regionalepreisgarantie.py
@@ -1,8 +1,6 @@
 from datetime import datetime, timezone
-from typing import Any, Dict
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import (
     Gueltigkeitstyp,
@@ -15,54 +13,30 @@
 )
 from tests.serialization_helper import assert_serialization_roundtrip
 
-example_regionale_preisgarantie = RegionalePreisgarantie(
-    preisgarantietyp=Preisgarantietyp.NUR_ENERGIEPREIS,
-    zeitliche_gueltigkeit=Zeitraum(
-        startzeitpunkt=datetime(2011, 2, 5, 16, 43, tzinfo=timezone.utc),
-        endzeitpunkt=datetime(2021, 7, 30, tzinfo=timezone.utc),
-    ),
-    regionale_gueltigkeit=RegionaleGueltigkeit(
-        gueltigkeitstyp=Gueltigkeitstyp.NUR_IN,
-        kriteriums_werte=[KriteriumWert(kriterium=Tarifregionskriterium.POSTLEITZAHL, wert="01069")],
-    ),
-)
-
 
 class TestRegionalePreisgarantie:
     @pytest.mark.parametrize(
-        "regionale_preisgarantie, expected_json_dict",
+        "regionale_preisgarantie",
         [
             pytest.param(
-                example_regionale_preisgarantie,
-                {
-                    "beschreibung": None,
-                    "preisgarantietyp": "NUR_ENERGIEPREIS",
-                    "regionaleGueltigkeit": {
-                        "gueltigkeitstyp": "NUR_IN",
-                        "kriteriumsWerte": [
-                            {"kriterium": Tarifregionskriterium.POSTLEITZAHL, "wert": "01069", "_id": None}
-                        ],
-                        "_id": None,
-                    },
-                    "zeitlicheGueltigkeit": {
-                        "startdatum": None,
-                        "einheit": None,
-                        "enddatum": None,
-                        "dauer": None,
-                        "endzeitpunkt": datetime(2021, 7, 30, 0, 0, tzinfo=timezone.utc),
-                        "startzeitpunkt": datetime(2011, 2, 5, 16, 43, tzinfo=timezone.utc),
-                        "_id": None,
-                    },
-                    "_id": None,
-                },
-                id="only required attributes",
+                RegionalePreisgarantie(
+                    preisgarantietyp=Preisgarantietyp.NUR_ENERGIEPREIS,
+                    zeitliche_gueltigkeit=Zeitraum(
+                        startzeitpunkt=datetime(2011, 2, 5, 16, 43, tzinfo=timezone.utc),
+                        endzeitpunkt=datetime(2021, 7, 30, tzinfo=timezone.utc),
+                    ),
+                    regionale_gueltigkeit=RegionaleGueltigkeit(
+                        gueltigkeitstyp=Gueltigkeitstyp.NUR_IN,
+                        kriteriums_werte=[KriteriumWert(kriterium=Tarifregionskriterium.POSTLEITZAHL, wert="01069")],
+                    ),
+                ),
             ),
         ],
     )
     def test_regionale_preisgarantie_serialization_roundtrip(
-        self, regionale_preisgarantie: RegionalePreisgarantie, expected_json_dict: Dict[str, Any]
+        self, regionale_preisgarantie: RegionalePreisgarantie
     ) -> None:
         """
         Test de-/serialisation of RegionalePreisgarantie with minimal attributes.
         """
-        assert_serialization_roundtrip(regionale_preisgarantie, expected_json_dict)
+        assert_serialization_roundtrip(regionale_preisgarantie)
diff --git a/tests/test_regionalepreisstaffel.py b/tests/test_regionalepreisstaffel.py
index 65b426e31..0b8295e35 100644
--- a/tests/test_regionalepreisstaffel.py
+++ b/tests/test_regionalepreisstaffel.py
@@ -1,25 +1,22 @@
 from decimal import Decimal
-from typing import Any, Dict
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import (
     Gueltigkeitstyp,
     KriteriumWert,
     RegionaleGueltigkeit,
-    RegionalePreisgarantie,
     RegionalePreisstaffel,
+    Sigmoidparameter,
     Tarifregionskriterium,
 )
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_sigmoidparameter import example_sigmoidparameter
 
 example_regionale_preisstaffel = RegionalePreisstaffel(
     einheitspreis=Decimal(40.0),
     staffelgrenze_von=Decimal(12.5),
     staffelgrenze_bis=Decimal(25.0),
-    sigmoidparameter=example_sigmoidparameter,
+    sigmoidparameter=Sigmoidparameter(),
     regionale_gueltigkeit=RegionaleGueltigkeit(
         gueltigkeitstyp=Gueltigkeitstyp.NUR_IN,
         kriteriums_werte=[KriteriumWert(kriterium=Tarifregionskriterium.POSTLEITZAHL, wert="01069")],
@@ -29,39 +26,29 @@
 
 class TestRegionalePreisstaffel:
     @pytest.mark.parametrize(
-        "regionale_preisstaffel, expected_json_dict",
+        "regionale_preisstaffel",
         [
             pytest.param(
-                example_regionale_preisstaffel,
-                {
-                    "regionaleGueltigkeit": {
-                        "gueltigkeitstyp": "NUR_IN",
-                        "kriteriumsWerte": [
-                            {"kriterium": Tarifregionskriterium.POSTLEITZAHL, "wert": "01069", "_id": None}
-                        ],
-                        "_id": None,
-                    },
-                    "einheitspreis": Decimal("40"),
-                    "sigmoidparameter": {
-                        "A": Decimal("1"),
-                        "B": Decimal("2"),
-                        "C": Decimal("3"),
-                        "D": Decimal("4"),
-                        "_id": None,
-                    },
-                    "staffelgrenzeVon": Decimal("12.5"),
-                    "staffelgrenzeBis": Decimal("25"),
-                    "_id": None,
-                },
+                RegionalePreisstaffel(
+                    einheitspreis=Decimal(40.0),
+                    staffelgrenze_von=Decimal(12.5),
+                    staffelgrenze_bis=Decimal(25.0),
+                    sigmoidparameter=Sigmoidparameter(),
+                    regionale_gueltigkeit=RegionaleGueltigkeit(
+                        gueltigkeitstyp=Gueltigkeitstyp.NUR_IN,
+                        kriteriums_werte=[KriteriumWert(kriterium=Tarifregionskriterium.POSTLEITZAHL, wert="01069")],
+                    ),
+                ),
                 id="maximal attributes"
                 # the messing sigmoidparameter is tested in the Preisstaffel tests
             ),
         ],
     )
     def test_serialization_roundtrip(
-        self, regionale_preisstaffel: RegionalePreisstaffel, expected_json_dict: Dict[str, Any]
+        self,
+        regionale_preisstaffel: RegionalePreisstaffel,
     ) -> None:
         """
         Test de-/serialisation of RegionalePreisgarantie with maximal attributes.
         """
-        assert_serialization_roundtrip(regionale_preisstaffel, expected_json_dict)
+        assert_serialization_roundtrip(regionale_preisstaffel)
diff --git a/tests/test_regionaleraufabschlag.py b/tests/test_regionaleraufabschlag.py
index 81a0f4425..6d828a35e 100644
--- a/tests/test_regionaleraufabschlag.py
+++ b/tests/test_regionaleraufabschlag.py
@@ -1,31 +1,18 @@
 import pytest
-from pydantic import ValidationError
 
-from bo4e import AufAbschlagstyp, AufAbschlagsziel, RegionalerAufAbschlag, Tarifeinschraenkung, Waehrungseinheit
-from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_energiemix import example_energiemix
-from tests.test_preisgarantie import example_preisgarantie
-from tests.test_regionalepreisstaffel import example_regionale_preisstaffel
-from tests.test_vertragskonditionen import example_vertragskonditionen
-from tests.test_zeitraum import example_zeitraum
-
-example_regionaler_auf_abschlag = RegionalerAufAbschlag(
-    bezeichnung="Foo",
-    beschreibung="Bar",
-    auf_abschlagstyp=AufAbschlagstyp.RELATIV,
-    auf_abschlagsziel=AufAbschlagsziel.ARBEITSPREIS_HT,
-    einheit=Waehrungseinheit.CT,
-    website="https://www.hochfrequenz.de",
-    zusatzprodukte=["ein standmixer", "ein thermomix"],
-    voraussetzungen=["lecker essen", "mit ökostrom gekocht"],
-    tarifnamensaenderungen="Super-Duper Tarif",
-    staffeln=[example_regionale_preisstaffel],
-    gueltigkeitszeitraum=example_zeitraum,
-    energiemixaenderung=example_energiemix,
-    vertagskonditionsaenderung=example_vertragskonditionen,
-    garantieaenderung=example_preisgarantie,
-    einschraenkungsaenderung=Tarifeinschraenkung(),
+from bo4e import (
+    AufAbschlagstyp,
+    AufAbschlagsziel,
+    Energiemix,
+    Preisgarantie,
+    RegionalePreisstaffel,
+    RegionalerAufAbschlag,
+    Tarifeinschraenkung,
+    Vertragskonditionen,
+    Waehrungseinheit,
+    Zeitraum,
 )
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestRegionalerAufAbschlag:
@@ -33,7 +20,23 @@ class TestRegionalerAufAbschlag:
         "regionaler_auf_abschlag",
         [
             pytest.param(
-                example_regionaler_auf_abschlag,
+                RegionalerAufAbschlag(
+                    bezeichnung="Foo",
+                    beschreibung="Bar",
+                    auf_abschlagstyp=AufAbschlagstyp.RELATIV,
+                    auf_abschlagsziel=AufAbschlagsziel.ARBEITSPREIS_HT,
+                    einheit=Waehrungseinheit.CT,
+                    website="https://www.hochfrequenz.de",
+                    zusatzprodukte=["ein standmixer", "ein thermomix"],
+                    voraussetzungen=["lecker essen", "mit ökostrom gekocht"],
+                    tarifnamensaenderungen="Super-Duper Tarif",
+                    staffeln=[RegionalePreisstaffel()],
+                    gueltigkeitszeitraum=Zeitraum(),
+                    energiemixaenderung=Energiemix(),
+                    vertagskonditionsaenderung=Vertragskonditionen(),
+                    garantieaenderung=Preisgarantie(),
+                    einschraenkungsaenderung=Tarifeinschraenkung(),
+                ),
                 id="maximal attributes",
             ),
         ],
diff --git a/tests/test_regionaletarifpreisposition.py b/tests/test_regionaletarifpreisposition.py
index 9f562a986..78a24b335 100644
--- a/tests/test_regionaletarifpreisposition.py
+++ b/tests/test_regionaletarifpreisposition.py
@@ -1,8 +1,6 @@
 from decimal import Decimal
-from typing import Any, Dict
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import (
     Gueltigkeitstyp,
@@ -12,72 +10,44 @@
     RegionaleGueltigkeit,
     RegionalePreisstaffel,
     RegionaleTarifpreisposition,
+    Sigmoidparameter,
     Tarifregionskriterium,
     Waehrungseinheit,
 )
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_sigmoidparameter import example_sigmoidparameter
-
-example_regionale_tarifpreisposition = RegionaleTarifpreisposition(
-    preistyp=Preistyp.ARBEITSPREIS_NT,
-    einheit=Waehrungseinheit.EUR,
-    bezugseinheit=Mengeneinheit.KWH,
-    mengeneinheitstaffel=Mengeneinheit.WH,
-    preisstaffeln=[
-        RegionalePreisstaffel(
-            einheitspreis=Decimal(40.0),
-            staffelgrenze_von=Decimal(12.5),
-            staffelgrenze_bis=Decimal(25.0),
-            sigmoidparameter=example_sigmoidparameter,
-            regionale_gueltigkeit=RegionaleGueltigkeit(
-                gueltigkeitstyp=Gueltigkeitstyp.NUR_IN,
-                kriteriums_werte=[KriteriumWert(kriterium=Tarifregionskriterium.POSTLEITZAHL, wert="01069")],
-            ),
-        ),
-    ],
-)
 
 
 class TestRegionaleTarifpreisPosition:
     @pytest.mark.parametrize(
-        "regionale_tarifpreis_position, expected_json_dict",
+        "regionale_tarifpreis_position",
         [
             pytest.param(
-                example_regionale_tarifpreisposition,
-                {
-                    "bezugseinheit": Mengeneinheit.KWH,
-                    "preisstaffeln": [
-                        {
-                            "regionaleGueltigkeit": {
-                                "gueltigkeitstyp": "NUR_IN",
-                                "kriteriumsWerte": [
-                                    {"kriterium": Tarifregionskriterium.POSTLEITZAHL, "wert": "01069", "_id": None}
+                RegionaleTarifpreisposition(
+                    preistyp=Preistyp.ARBEITSPREIS_NT,
+                    einheit=Waehrungseinheit.EUR,
+                    bezugseinheit=Mengeneinheit.KWH,
+                    mengeneinheitstaffel=Mengeneinheit.WH,
+                    preisstaffeln=[
+                        RegionalePreisstaffel(
+                            einheitspreis=Decimal(40.0),
+                            staffelgrenze_von=Decimal(12.5),
+                            staffelgrenze_bis=Decimal(25.0),
+                            sigmoidparameter=Sigmoidparameter(),
+                            regionale_gueltigkeit=RegionaleGueltigkeit(
+                                gueltigkeitstyp=Gueltigkeitstyp.NUR_IN,
+                                kriteriums_werte=[
+                                    KriteriumWert(kriterium=Tarifregionskriterium.POSTLEITZAHL, wert="01069")
                                 ],
-                                "_id": None,
-                            },
-                            "einheitspreis": Decimal("40"),
-                            "sigmoidparameter": {
-                                "A": Decimal("1"),
-                                "B": Decimal("2"),
-                                "C": Decimal("3"),
-                                "D": Decimal("4"),
-                                "_id": None,
-                            },
-                            "staffelgrenzeVon": Decimal("12.5"),
-                            "staffelgrenzeBis": Decimal("25"),
-                            "_id": None,
-                        }
+                            ),
+                        ),
                     ],
-                    "einheit": Waehrungseinheit.EUR,
-                    "mengeneinheitstaffel": Mengeneinheit.WH,
-                    "preistyp": "ARBEITSPREIS_NT",
-                    "_id": None,
-                },
+                ),
                 id="all attributes",
             ),
         ],
     )
-    def test_serialization_roundtrip(
-        self, regionale_tarifpreis_position: RegionaleTarifpreisposition, expected_json_dict: Dict[str, Any]
-    ) -> None:
-        assert_serialization_roundtrip(regionale_tarifpreis_position, expected_json_dict)
+    def test_serialization_roundtrip(self, regionale_tarifpreis_position: RegionaleTarifpreisposition) -> None:
+        """
+        Test de-/serialisation
+        """
+        assert_serialization_roundtrip(regionale_tarifpreis_position)
diff --git a/tests/test_regionaltarif.py b/tests/test_regionaltarif.py
index ad2ab452e..f5655969e 100644
--- a/tests/test_regionaltarif.py
+++ b/tests/test_regionaltarif.py
@@ -2,18 +2,24 @@
 
 import pytest
 
-from bo4e import Kundentyp, Regionaltarif, Sparte, Tarifmerkmal, Tariftyp
-from bo4e.enum.registeranzahl import Registeranzahl
+from bo4e import (
+    Energiemix,
+    Kundentyp,
+    Marktteilnehmer,
+    RegionalePreisgarantie,
+    RegionalerAufAbschlag,
+    RegionaleTarifpreisposition,
+    Regionaltarif,
+    Registeranzahl,
+    Sparte,
+    Tarifberechnungsparameter,
+    Tarifeinschraenkung,
+    Tarifmerkmal,
+    Tariftyp,
+    Vertragskonditionen,
+    Zeitraum,
+)
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_energiemix import example_energiemix
-from tests.test_marktteilnehmer import example_marktteilnehmer
-from tests.test_regionalepreisgarantie import example_regionale_preisgarantie
-from tests.test_regionaleraufabschlag import example_regionaler_auf_abschlag
-from tests.test_regionaletarifpreisposition import example_regionale_tarifpreisposition
-from tests.test_tarifberechnungsparameter import example_tarifberechnungsparameter
-from tests.test_tarifeinschraenkung import example_tarifeinschraenkung
-from tests.test_vertragskonditionen import example_vertragskonditionen
-from tests.test_zeitraum import example_zeitraum
 
 
 class TestRegionaltarif:
@@ -23,11 +29,11 @@ class TestRegionaltarif:
             pytest.param(
                 Regionaltarif(
                     preisstand=datetime(2022, 2, 1, 0, 0, 0, tzinfo=timezone.utc),
-                    berechnungsparameter=example_tarifberechnungsparameter,
-                    tarif_auf_abschlaege=[example_regionaler_auf_abschlag],
-                    tarifpreise=[example_regionale_tarifpreisposition],
-                    preisgarantien=[example_regionale_preisgarantie],
-                    tarifeinschraenkung=example_tarifeinschraenkung,
+                    berechnungsparameter=Tarifberechnungsparameter(),
+                    tarif_auf_abschlaege=[RegionalerAufAbschlag()],
+                    tarifpreise=[RegionaleTarifpreisposition()],
+                    preisgarantien=[RegionalePreisgarantie()],
+                    tarifeinschraenkung=Tarifeinschraenkung(),
                     # ^^ above are the attributes of Regionaltarif
                     # vv below is all copy pasted from Tarifinfo test
                     bezeichnung="foo",
@@ -39,31 +45,13 @@ class TestRegionaltarif:
                     tarifmerkmale=[Tarifmerkmal.HEIZSTROM],
                     website="https://foo.inv",
                     bemerkung="super billig aber auch super dreckig",
-                    vertragskonditionen=example_vertragskonditionen,
-                    zeitliche_gueltigkeit=example_zeitraum,
-                    energiemix=example_energiemix,
-                    anbieter=example_marktteilnehmer,
+                    vertragskonditionen=Vertragskonditionen(),
+                    zeitliche_gueltigkeit=Zeitraum(),
+                    energiemix=Energiemix(),
+                    anbieter=Marktteilnehmer(),
                 ),
-                id="required and optional attributes",
-            ),
-            pytest.param(
-                Regionaltarif(
-                    preisstand=datetime(2022, 2, 1, 0, 0, 0, tzinfo=timezone.utc),
-                    berechnungsparameter=example_tarifberechnungsparameter,
-                    tarifpreise=[example_regionale_tarifpreisposition],
-                    # ^^ above are the attributes of Regionaltarif
-                    # vv below is all copy pasted from Tarifinfo test
-                    bezeichnung="foo",
-                    anbietername="der beste stromanbieter",
-                    sparte=Sparte.STROM,
-                    kundentypen=[Kundentyp.PRIVAT, Kundentyp.GEWERBE],
-                    registeranzahl=Registeranzahl.MEHRTARIF,
-                    tariftyp=Tariftyp.GRUND_ERSATZVERSORGUNG,
-                    tarifmerkmale=[Tarifmerkmal.HEIZSTROM],
-                    anbieter=example_marktteilnehmer,
-                ),
-                id="required attributes",
-            ),
+                id="all attributes",
+            )
         ],
     )
     def test_serialization_roundtrip(self, regionaltarif: Regionaltarif) -> None:
diff --git a/tests/test_regionskriterium.py b/tests/test_regionskriterium.py
index ea3d2d69d..acae42d9f 100644
--- a/tests/test_regionskriterium.py
+++ b/tests/test_regionskriterium.py
@@ -1,37 +1,24 @@
-from typing import Any, Dict
-
 import pytest
-from pydantic import ValidationError
 
 from bo4e import Gueltigkeitstyp, Regionskriterium, Regionskriteriumtyp
 from tests.serialization_helper import assert_serialization_roundtrip
 
-example_regionskriterium = Regionskriterium(
-    regionskriteriumtyp=Regionskriteriumtyp.REGELGEBIET_NAME,
-    gueltigkeitstyp=Gueltigkeitstyp.NICHT_IN,
-    wert="Was ist ein Regionskriterium?",
-)
-
 
 class TestRegionskriterium:
     @pytest.mark.parametrize(
-        "regionskriterium, expected_json_dict",
+        "regionskriterium",
         [
             pytest.param(
-                example_regionskriterium,
-                {
-                    "gueltigkeitstyp": "NICHT_IN",
-                    "regionskriteriumtyp": "REGELGEBIET_NAME",
-                    "wert": "Was ist ein Regionskriterium?",
-                    "_id": None,
-                },
+                Regionskriterium(
+                    regionskriteriumtyp=Regionskriteriumtyp.REGELGEBIET_NAME,
+                    gueltigkeitstyp=Gueltigkeitstyp.NICHT_IN,
+                    wert="Was ist ein Regionskriterium?",
+                ),
             ),
         ],
     )
-    def test_regionskriterium_serialization_roundtrip(
-        self, regionskriterium: Regionskriterium, expected_json_dict: Dict[str, Any]
-    ) -> None:
+    def test_regionskriterium_serialization_roundtrip(self, regionskriterium: Regionskriterium) -> None:
         """
         Test de-/serialisation of Regionskriterium with minimal attributes.
         """
-        assert_serialization_roundtrip(regionskriterium, expected_json_dict)
+        assert_serialization_roundtrip(regionskriterium)
diff --git a/tests/test_sigmoidparameter.py b/tests/test_sigmoidparameter.py
index ca17ea8d1..9c1a4bcdc 100644
--- a/tests/test_sigmoidparameter.py
+++ b/tests/test_sigmoidparameter.py
@@ -1,38 +1,30 @@
 from decimal import Decimal
-from typing import Any, Dict
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import Sigmoidparameter
 from tests.serialization_helper import assert_serialization_roundtrip
 
-# this sigmoid parameter can be imported by other tests
-example_sigmoidparameter = Sigmoidparameter(
-    A=Decimal(1),
-    B=Decimal(2),
-    C=Decimal(3),
-    D=Decimal(4),
-)
-
 
 class TestSigmoidparameter:
     @pytest.mark.parametrize(
-        "sigmoidparameter, expected_json_dict",
+        "sigmoidparameter",
         [
             pytest.param(
-                example_sigmoidparameter,
-                {"A": Decimal("1"), "B": Decimal("2"), "C": Decimal("3"), "D": Decimal("4"), "_id": None},
+                Sigmoidparameter(
+                    A=Decimal(1),
+                    B=Decimal(2),
+                    C=Decimal(3),
+                    D=Decimal(4),
+                ),
             ),
         ],
     )
-    def test_sigmoidparameter_serialization_roundtrip(
-        self, sigmoidparameter: Sigmoidparameter, expected_json_dict: Dict[str, Any]
-    ) -> None:
+    def test_sigmoidparameter_serialization_roundtrip(self, sigmoidparameter: Sigmoidparameter) -> None:
         """
         Test de-/serialisation of Sigmoidparameter with minimal attributes.
         """
-        assert_serialization_roundtrip(sigmoidparameter, expected_json_dict)
+        assert_serialization_roundtrip(sigmoidparameter)
 
     @pytest.mark.parametrize(
         "sigmoidparameter, leistung, expected_lp",
diff --git a/tests/test_standorteigenschaften.py b/tests/test_standorteigenschaften.py
index 689ea04a8..d9448c9fa 100644
--- a/tests/test_standorteigenschaften.py
+++ b/tests/test_standorteigenschaften.py
@@ -1,10 +1,7 @@
 import pytest
-from pydantic import ValidationError
 
-from bo4e import Standorteigenschaften
+from bo4e import Standorteigenschaften, StandorteigenschaftenGas, StandorteigenschaftenStrom
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_standorteigenschaftengas import example_standorteigenschaften_gas
-from tests.test_standorteigenschaftenstrom import example_standorteigenschaften_strom
 
 
 class TestStandorteigenschaften:
@@ -13,11 +10,14 @@ class TestStandorteigenschaften:
         [
             pytest.param(
                 Standorteigenschaften(
-                    eigenschaften_strom=[example_standorteigenschaften_strom],
-                    eigenschaften_gas=example_standorteigenschaften_gas,
+                    eigenschaften_strom=[StandorteigenschaftenStrom()],
+                    eigenschaften_gas=StandorteigenschaftenGas(),
                 )
             ),
         ],
     )
     def test_serialization_roundtrip(self, standorteigenschaften: Standorteigenschaften) -> None:
+        """
+        Test de-/serialisation of Sigmoidparameter with minimal attributes.
+        """
         assert_serialization_roundtrip(standorteigenschaften)
diff --git a/tests/test_standorteigenschaftengas.py b/tests/test_standorteigenschaftengas.py
index cc2aa5b92..90eafd20b 100644
--- a/tests/test_standorteigenschaftengas.py
+++ b/tests/test_standorteigenschaftengas.py
@@ -1,7 +1,4 @@
-from typing import Any, Dict, List
-
 import pytest
-from pydantic import ValidationError
 
 from bo4e import MarktgebietInfo, StandorteigenschaftenGas
 from tests.serialization_helper import assert_serialization_roundtrip
@@ -14,19 +11,17 @@
 
 class TestStandorteigenschaftenGas:
     @pytest.mark.parametrize(
-        "standorteigenschaftengas, expected_json_dict",
+        "standorteigenschaftengas",
         [
             pytest.param(
-                example_standorteigenschaften_gas,
-                {
-                    "netzkontonummern": ["GASPOOLNH700xxxx"],
-                    "marktgebiete": [{"marktgebiet": "Gaspool", "marktgebietcode": "37Z701133MH0000B", "_id": None}],
-                    "_id": None,
-                },
+                StandorteigenschaftenGas(
+                    netzkontonummern=["GASPOOLNH700xxxx"],
+                    marktgebiete=[MarktgebietInfo(marktgebiet="Gaspool", marktgebietcode="37Z701133MH0000B")],
+                ),
             )
         ],
     )
     def test_standorteigenschaftengas_serialization_roundtrip(
-        self, standorteigenschaftengas: StandorteigenschaftenGas, expected_json_dict: Dict[str, Any]
+        self, standorteigenschaftengas: StandorteigenschaftenGas
     ) -> None:
-        assert_serialization_roundtrip(standorteigenschaftengas, expected_json_dict)
+        assert_serialization_roundtrip(standorteigenschaftengas)
diff --git a/tests/test_standorteigenschaftenstrom.py b/tests/test_standorteigenschaftenstrom.py
index acb6bfeae..b751d61ae 100644
--- a/tests/test_standorteigenschaftenstrom.py
+++ b/tests/test_standorteigenschaftenstrom.py
@@ -1,34 +1,24 @@
-from typing import Any, Dict
-
 import pytest
-from pydantic import ValidationError
 
 from bo4e import StandorteigenschaftenStrom
 from tests.serialization_helper import assert_serialization_roundtrip
 
-example_standorteigenschaften_strom = StandorteigenschaftenStrom(
-    regelzone="Transnet BW",
-    bilanzierungsgebiet_eic="11YW-ALBSTADT--5",
-    regelzone_eic="10YDE-ENBW-----N",
-)
-
 
 class TestStandorteigenschaftenStrom:
     @pytest.mark.parametrize(
-        "standorteigenschaften_strom, expected_json_dict",
+        "standorteigenschaften_strom",
         [
             pytest.param(
-                example_standorteigenschaften_strom,
-                {
-                    "regelzone": "Transnet BW",
-                    "bilanzierungsgebietEic": "11YW-ALBSTADT--5",
-                    "regelzoneEic": "10YDE-ENBW-----N",
-                    "_id": None,
-                },
+                StandorteigenschaftenStrom(
+                    regelzone="Transnet BW",
+                    bilanzierungsgebiet_eic="11YW-ALBSTADT--5",
+                    regelzone_eic="10YDE-ENBW-----N",
+                ),
             )
         ],
     )
-    def test_serialization_roundtrip(
-        self, standorteigenschaften_strom: StandorteigenschaftenStrom, expected_json_dict: Dict[str, Any]
-    ) -> None:
-        assert_serialization_roundtrip(standorteigenschaften_strom, expected_json_dict)
+    def test_serialization_roundtrip(self, standorteigenschaften_strom: StandorteigenschaftenStrom) -> None:
+        """
+        Test de-/serialisation.
+        """
+        assert_serialization_roundtrip(standorteigenschaften_strom)
diff --git a/tests/test_steuerbetrag.py b/tests/test_steuerbetrag.py
index 26f0b1f9f..5a56160e2 100644
--- a/tests/test_steuerbetrag.py
+++ b/tests/test_steuerbetrag.py
@@ -1,40 +1,27 @@
 from decimal import Decimal
-from typing import Any, Dict
 
 import pytest
-from pydantic import ValidationError
 
-from bo4e import Steuerbetrag, Steuerkennzeichen, Waehrungscode, Waehrungseinheit
+from bo4e import Steuerbetrag, Steuerkennzeichen, Waehrungscode
 from tests.serialization_helper import assert_serialization_roundtrip
 
-example_steuerbetrag = Steuerbetrag(
-    steuerkennzeichen=Steuerkennzeichen.UST_7,
-    basiswert=Decimal(100),
-    steuerwert=Decimal(19),
-    waehrung=Waehrungscode.EUR,
-)
-
 
 class TestSteuerbetrag:
     @pytest.mark.parametrize(
-        "steuerbetrag, expected_json_dict",
+        "steuerbetrag",
         [
             pytest.param(
-                example_steuerbetrag,
-                {
-                    "steuerkennzeichen": "UST_7",
-                    "basiswert": Decimal("100"),
-                    "steuerwert": Decimal("19"),
-                    "waehrung": Waehrungseinheit.EUR,
-                    "_id": None,
-                },
+                Steuerbetrag(
+                    steuerkennzeichen=Steuerkennzeichen.UST_7,
+                    basiswert=Decimal(100),
+                    steuerwert=Decimal(19),
+                    waehrung=Waehrungscode.EUR,
+                ),
             ),
         ],
     )
-    def test_steuerbetrag_required_attributes(
-        self, steuerbetrag: Steuerbetrag, expected_json_dict: Dict[str, Any]
-    ) -> None:
+    def test_steuerbetrag_required_attributes(self, steuerbetrag: Steuerbetrag) -> None:
         """
         Test de-/serialisation of Steuerbetrag with minimal attributes.
         """
-        assert_serialization_roundtrip(steuerbetrag, expected_json_dict)
+        assert_serialization_roundtrip(steuerbetrag)
diff --git a/tests/test_tarif.py b/tests/test_tarif.py
index f7c88cb01..42d646427 100644
--- a/tests/test_tarif.py
+++ b/tests/test_tarif.py
@@ -1,19 +1,25 @@
 from datetime import datetime, timezone
 
 import pytest
-from pydantic import ValidationError
 
-from bo4e import Kundentyp, Registeranzahl, Sparte, Tarif, Tarifmerkmal, Tariftyp
+from bo4e import (
+    AufAbschlagRegional,
+    Energiemix,
+    Kundentyp,
+    Marktteilnehmer,
+    Preisgarantie,
+    Registeranzahl,
+    Sparte,
+    Tarif,
+    Tarifberechnungsparameter,
+    Tarifeinschraenkung,
+    Tarifmerkmal,
+    TarifpreispositionProOrt,
+    Tariftyp,
+    Vertragskonditionen,
+    Zeitraum,
+)
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_aufabschlagregional import example_aufabschlagregional
-from tests.test_energiemix import example_energiemix
-from tests.test_marktteilnehmer import example_marktteilnehmer
-from tests.test_preisgarantie import example_preisgarantie
-from tests.test_tarifberechnungsparameter import example_tarifberechnungsparameter
-from tests.test_tarifeinschraenkung import example_tarifeinschraenkung
-from tests.test_tarifpreispositionproort import example_tarifpreispositionproort
-from tests.test_vertragskonditionen import example_vertragskonditionen
-from tests.test_zeitraum import example_zeitraum
 
 
 class TestTarif:
@@ -23,11 +29,11 @@ class TestTarif:
             pytest.param(
                 Tarif(
                     preisstand=datetime(2022, 2, 1, 0, 0, 0, tzinfo=timezone.utc),
-                    berechnungsparameter=example_tarifberechnungsparameter,
-                    tarif_auf_abschlaege=[example_aufabschlagregional],
-                    tarifpreise=[example_tarifpreispositionproort],
-                    preisgarantie=example_preisgarantie,
-                    tarifeinschraenkung=example_tarifeinschraenkung,
+                    berechnungsparameter=Tarifberechnungsparameter(),
+                    tarif_auf_abschlaege=[AufAbschlagRegional()],
+                    tarifpreise=[TarifpreispositionProOrt()],
+                    preisgarantie=Preisgarantie(),
+                    tarifeinschraenkung=Tarifeinschraenkung(),
                     # below are the attributes of tarifinfo
                     bezeichnung="foo",
                     anbietername="der beste stromanbieter",
@@ -38,29 +44,12 @@ class TestTarif:
                     tarifmerkmale=[Tarifmerkmal.HEIZSTROM],
                     website="https://foo.inv",
                     bemerkung="super billig aber auch super dreckig",
-                    vertragskonditionen=example_vertragskonditionen,
-                    zeitliche_gueltigkeit=example_zeitraum,
-                    energiemix=example_energiemix,
-                    anbieter=example_marktteilnehmer,
+                    vertragskonditionen=Vertragskonditionen(),
+                    zeitliche_gueltigkeit=Zeitraum(),
+                    energiemix=Energiemix(),
+                    anbieter=Marktteilnehmer(),
                 ),
-                id="required and optional attributes",
-            ),
-            pytest.param(
-                Tarif(
-                    preisstand=datetime(2022, 2, 1, 0, 0, 0, tzinfo=timezone.utc),
-                    berechnungsparameter=example_tarifberechnungsparameter,
-                    tarifpreise=[example_tarifpreispositionproort],
-                    # below are the attributes of tarifinfo
-                    bezeichnung="foo",
-                    anbietername="der beste stromanbieter",
-                    sparte=Sparte.STROM,
-                    kundentypen=[Kundentyp.PRIVAT, Kundentyp.GEWERBE],
-                    registeranzahl=Registeranzahl.MEHRTARIF,
-                    tariftyp=Tariftyp.GRUND_ERSATZVERSORGUNG,
-                    tarifmerkmale=[Tarifmerkmal.HEIZSTROM],
-                    anbieter=example_marktteilnehmer,
-                ),
-                id="only required attributes",
+                id="all attributes",
             ),
         ],
     )
diff --git a/tests/test_tarifberechnungsparameter.py b/tests/test_tarifberechnungsparameter.py
index 421bfb34c..a9d0899aa 100644
--- a/tests/test_tarifberechnungsparameter.py
+++ b/tests/test_tarifberechnungsparameter.py
@@ -2,23 +2,15 @@
 
 import pytest
 
-from bo4e import Fremdkostenposition, Messpreistyp, Tarifberechnungsparameter, Tarifkalkulationsmethode
-from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_preis import example_preis
-from tests.test_tarifpreis import example_tarifpreis
-
-example_tarifberechnungsparameter = Tarifberechnungsparameter(
-    berechnungsmethode=Tarifkalkulationsmethode.ZONEN,
-    ist_messpreis_in_grundpreis_enthalten=True,
-    kw_inklusive=Decimal(12.5),
-    kw_weitere_mengen=Decimal(12.5),
-    messpreistyp=Messpreistyp.MESSPREIS_G6,
-    ist_messpreis_zu_beruecksichtigen=True,
-    hoechstpreis_h_t=example_preis,
-    hoechstpreis_n_t=example_preis,
-    mindestpreis=example_preis,
-    zusatzpreise=[example_tarifpreis],
+from bo4e import (
+    Fremdkostenposition,
+    Messpreistyp,
+    Preis,
+    Tarifberechnungsparameter,
+    Tarifkalkulationsmethode,
+    Tarifpreis,
 )
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestFremdkostenposition:
@@ -26,12 +18,19 @@ class TestFremdkostenposition:
         "tarifberechnungsparameter",
         [
             pytest.param(
-                example_tarifberechnungsparameter,
-                id="maximal attributes",
-            ),
-            pytest.param(
-                Tarifberechnungsparameter(),
-                id="minimal attributes",
+                Tarifberechnungsparameter(
+                    berechnungsmethode=Tarifkalkulationsmethode.ZONEN,
+                    ist_messpreis_in_grundpreis_enthalten=True,
+                    ist_messpreis_zu_beruecksichtigen=True,
+                    messpreistyp=Messpreistyp.MESSPREIS_G6,
+                    kw_inklusive=Decimal(12.5),
+                    kw_weitere_mengen=Decimal(12.5),
+                    hoechstpreis_n_t=Preis(),
+                    hoechstpreis_h_t=Preis(),
+                    mindestpreis=Preis(),
+                    zusatzpreise=[Tarifpreis()],
+                ),
+                id="all attributes at first level",
             ),
         ],
     )
diff --git a/tests/test_tarifeinschraenkung.py b/tests/test_tarifeinschraenkung.py
index 60f2b10e1..f7b5e5818 100644
--- a/tests/test_tarifeinschraenkung.py
+++ b/tests/test_tarifeinschraenkung.py
@@ -6,19 +6,6 @@
 from tests.serialization_helper import assert_serialization_roundtrip
 from tests.test_geraet import example_geraet
 
-example_tarifeinschraenkung = Tarifeinschraenkung(
-    zusatzprodukte=["foo", "bar"],
-    voraussetzungen=[Voraussetzungen.ALTVERTRAG, Voraussetzungen.DIREKTVERTRIEB],
-    einschraenkungzaehler=[
-        example_geraet,
-        Geraet(geraetenummer="197foo"),
-    ],
-    einschraenkungleistung=[
-        Menge(wert=Decimal(12.5), einheit=Mengeneinheit.MWH),
-        Menge(wert=Decimal(30), einheit=Mengeneinheit.KWH),
-    ],
-)
-
 
 class TestTarifeinschraenkung:
     @pytest.mark.parametrize(
diff --git a/tests/test_tarifinfo.py b/tests/test_tarifinfo.py
index 97dfad9ff..db58bca0a 100644
--- a/tests/test_tarifinfo.py
+++ b/tests/test_tarifinfo.py
@@ -1,14 +1,20 @@
 from datetime import datetime, timezone
 
 import pytest
-from pydantic import ValidationError
 
-from bo4e import Kundentyp, Registeranzahl, Sparte, Tarifinfo, Tarifmerkmal, Tariftyp
+from bo4e import (
+    Energiemix,
+    Kundentyp,
+    Marktteilnehmer,
+    Registeranzahl,
+    Sparte,
+    Tarifinfo,
+    Tarifmerkmal,
+    Tariftyp,
+    Vertragskonditionen,
+    Zeitraum,
+)
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_energiemix import example_energiemix
-from tests.test_marktteilnehmer import example_marktteilnehmer
-from tests.test_vertragskonditionen import example_vertragskonditionen
-from tests.test_zeitraum import example_zeitraum
 
 
 class TestTarifinfo:
@@ -26,10 +32,10 @@ class TestTarifinfo:
                     tarifmerkmale=[Tarifmerkmal.HEIZSTROM],
                     website="https://foo.inv",
                     bemerkung="super billig aber auch super dreckig",
-                    vertragskonditionen=example_vertragskonditionen,
-                    zeitliche_gueltigkeit=example_zeitraum,
-                    energiemix=example_energiemix,
-                    anbieter=example_marktteilnehmer,
+                    vertragskonditionen=Vertragskonditionen(),
+                    zeitliche_gueltigkeit=Zeitraum(),
+                    energiemix=Energiemix(),
+                    anbieter=Marktteilnehmer(),
                     anwendung_von=datetime(2022, 1, 1, 0, 0, 0, tzinfo=timezone.utc),
                 )
             ),
@@ -37,6 +43,6 @@ class TestTarifinfo:
     )
     def test_serialization_roundtrip(self, tarifinfo: Tarifinfo) -> None:
         """
-        Test de-/serialisation
+        Test de-/serialisation Tarifinfo.
         """
         assert_serialization_roundtrip(tarifinfo)
diff --git a/tests/test_tarifkosten.py b/tests/test_tarifkosten.py
index afc55f077..f7e6007c8 100644
--- a/tests/test_tarifkosten.py
+++ b/tests/test_tarifkosten.py
@@ -1,14 +1,19 @@
 import pytest
-from pydantic import ValidationError
 
-from bo4e import Kundentyp, Sparte, Tarifkosten, Tarifmerkmal, Tariftyp
-from bo4e.enum.registeranzahl import Registeranzahl
+from bo4e import (
+    Energiemix,
+    Kosten,
+    Kundentyp,
+    Marktteilnehmer,
+    Registeranzahl,
+    Sparte,
+    Tarifkosten,
+    Tarifmerkmal,
+    Tariftyp,
+    Vertragskonditionen,
+    Zeitraum,
+)
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_energiemix import example_energiemix
-from tests.test_kosten import example_kosten
-from tests.test_marktteilnehmer import example_marktteilnehmer
-from tests.test_vertragskonditionen import example_vertragskonditionen
-from tests.test_zeitraum import example_zeitraum
 
 
 class TestTarifkosten:
@@ -26,17 +31,17 @@ class TestTarifkosten:
                     tarifmerkmale=[Tarifmerkmal.HEIZSTROM],
                     website="https://foo.inv",
                     bemerkung="super billig aber auch super dreckig",
-                    vertragskonditionen=example_vertragskonditionen,
-                    zeitliche_gueltigkeit=example_zeitraum,
-                    energiemix=example_energiemix,
-                    anbieter=example_marktteilnehmer,
-                    kosten=example_kosten,
+                    vertragskonditionen=Vertragskonditionen(),
+                    zeitliche_gueltigkeit=Zeitraum(),
+                    energiemix=Energiemix(),
+                    anbieter=Marktteilnehmer(),
+                    kosten=Kosten(),
                 )
             ),
         ],
     )
     def test_serialization_roundtrip(self, tarifkosten: Tarifkosten) -> None:
         """
-        Test de-/serialisation
+        Test de-/serialisation Tarifkosten.
         """
         assert_serialization_roundtrip(tarifkosten)
diff --git a/tests/test_tarifpreis.py b/tests/test_tarifpreis.py
index abee9a36a..d880034bb 100644
--- a/tests/test_tarifpreis.py
+++ b/tests/test_tarifpreis.py
@@ -4,36 +4,10 @@
 from pydantic import ValidationError
 
 from bo4e import Mengeneinheit, Preisstatus, Preistyp, Tarifpreis, Waehrungseinheit
-
-example_tarifpreis = Tarifpreis(
-    wert=Decimal(12.5),
-    einheit=Waehrungseinheit.EUR,
-    bezugswert=Mengeneinheit.KWH,
-    preistyp=Preistyp.ARBEITSPREIS_HT,
-)
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestTarifpreis:
-    def test_tarifpreis_only_required(self) -> None:
-        """
-        Test de-/serialisation of Tarifpreis (only has required attributes).
-        """
-        tarifpreis = example_tarifpreis
-
-        json_string = tarifpreis.model_dump_json(by_alias=True)
-
-        assert "ARBEITSPREIS_HT" in json_string
-        assert "null" in json_string
-
-        tarifpreis_deserialized = Tarifpreis.model_validate_json(json_string)
-
-        assert isinstance(tarifpreis_deserialized.wert, Decimal)
-        assert isinstance(tarifpreis_deserialized.einheit, Waehrungseinheit)
-        assert isinstance(tarifpreis_deserialized.bezugswert, Mengeneinheit)
-        assert isinstance(tarifpreis_deserialized.preistyp, Preistyp)
-        assert tarifpreis_deserialized.beschreibung is None
-        assert tarifpreis == tarifpreis_deserialized
-
     def test_wrong_datatype(self) -> None:
         with pytest.raises(ValidationError) as excinfo:
             _ = Tarifpreis(
@@ -47,22 +21,23 @@ def test_wrong_datatype(self) -> None:
         assert "wert" in str(excinfo.value)
         assert "type=decimal_parsing" in str(excinfo.value)
 
-    def test_optional_attribute(self) -> None:
-        tarifpreis = Tarifpreis(
-            wert=Decimal(3.50),
-            einheit=Waehrungseinheit.EUR,
-            bezugswert=Mengeneinheit.KWH,
-            status=Preisstatus.ENDGUELTIG,
-            preistyp=Preistyp.ARBEITSPREIS_HT,
-            beschreibung="Das ist ein HT Arbeitspreis",
-        )
-
-        json_string = tarifpreis.model_dump_json(by_alias=True)
-
-        assert "Das ist ein HT Arbeitspreis" in json_string
-
-        tarifpreis_deserialized = Tarifpreis.model_validate_json(json_string)
-
-        assert isinstance(tarifpreis_deserialized.beschreibung, str)
-        assert tarifpreis_deserialized.beschreibung == "Das ist ein HT Arbeitspreis"
-        assert tarifpreis_deserialized == tarifpreis
+    @pytest.mark.parametrize(
+        "tarifpreis",
+        [
+            pytest.param(
+                Tarifpreis(
+                    wert=Decimal(3.50),
+                    einheit=Waehrungseinheit.EUR,
+                    bezugswert=Mengeneinheit.KWH,
+                    status=Preisstatus.ENDGUELTIG,
+                    preistyp=Preistyp.ARBEITSPREIS_HT,
+                    beschreibung="Das ist ein HT Arbeitspreis",
+                ),
+            ),
+        ],
+    )
+    def test_serialization_roundtrip(self, tarifpreis: Tarifpreis) -> None:
+        """
+        Test de-/serialisation of Tarifpreis.
+        """
+        assert_serialization_roundtrip(tarifpreis)
diff --git a/tests/test_tarifpreisblatt.py b/tests/test_tarifpreisblatt.py
index 3c82f50cf..a03057ca6 100644
--- a/tests/test_tarifpreisblatt.py
+++ b/tests/test_tarifpreisblatt.py
@@ -1,26 +1,25 @@
 import datetime
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import (
+    AufAbschlag,
+    Energiemix,
     Kundentyp,
+    Marktteilnehmer,
+    Preisgarantie,
     Registeranzahl,
     Sparte,
     Tarifberechnungsparameter,
     Tarifeinschraenkung,
     Tarifmerkmal,
     Tarifpreisblatt,
+    Tarifpreisposition,
     Tariftyp,
+    Vertragskonditionen,
+    Zeitraum,
 )
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_aufabschlag import example_aufabschlag
-from tests.test_energiemix import example_energiemix
-from tests.test_marktteilnehmer import example_marktteilnehmer
-from tests.test_preisgarantie import example_preisgarantie
-from tests.test_tarifpreisposition import example_tarifpreisposition
-from tests.test_vertragskonditionen import example_vertragskonditionen
-from tests.test_zeitraum import example_zeitraum
 
 
 class TestTarifpreisblatt:
@@ -38,17 +37,17 @@ class TestTarifpreisblatt:
                     tarifmerkmale=[Tarifmerkmal.HEIZSTROM],
                     website="https://foo.inv",
                     bemerkung="super billig aber auch super dreckig",
-                    vertragskonditionen=example_vertragskonditionen,
-                    zeitliche_gueltigkeit=example_zeitraum,
-                    energiemix=example_energiemix,
-                    anbieter=example_marktteilnehmer,
+                    vertragskonditionen=Vertragskonditionen(),
+                    zeitliche_gueltigkeit=Zeitraum(),
+                    energiemix=Energiemix(),
+                    anbieter=Marktteilnehmer(),
                     # ^^ above is all copy pasted from Tarifinfo BO
                     # vv below are the attributes of tarifpreisblatt
                     preisstand=datetime.datetime(2022, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc),
                     berechnungsparameter=Tarifberechnungsparameter(),
-                    tarif_auf_abschlaege=[example_aufabschlag],
-                    tarifpreise=[example_tarifpreisposition],
-                    preisgarantie=example_preisgarantie,
+                    tarif_auf_abschlaege=[AufAbschlag()],
+                    tarifpreise=[Tarifpreisposition()],
+                    preisgarantie=Preisgarantie(),
                     tarifeinschraenkung=Tarifeinschraenkung(),
                 )
             ),
@@ -56,6 +55,6 @@ class TestTarifpreisblatt:
     )
     def test_serialization_roundtrip(self, tarifpreisblatt: Tarifpreisblatt) -> None:
         """
-        Test de-/serialisation
+        Test de-/serialisation Tarifpreisblatt.
         """
         assert_serialization_roundtrip(tarifpreisblatt)
diff --git a/tests/test_tarifpreisposition.py b/tests/test_tarifpreisposition.py
index 950731110..cc0d62e17 100644
--- a/tests/test_tarifpreisposition.py
+++ b/tests/test_tarifpreisposition.py
@@ -1,50 +1,15 @@
 from decimal import Decimal
-from typing import Any, Dict
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import Mengeneinheit, Preisstaffel, Preistyp, Tarifpreisposition, Waehrungseinheit
 from tests.serialization_helper import assert_serialization_roundtrip
 
-example_tarifpreisposition = Tarifpreisposition(
-    preistyp=Preistyp.ENTGELT_ABLESUNG,
-    einheit=Waehrungseinheit.EUR,
-    bezugseinheit=Mengeneinheit.KWH,
-    preisstaffeln=[
-        Preisstaffel(
-            einheitspreis=Decimal(40.0),
-            staffelgrenze_von=Decimal(12.5),
-            staffelgrenze_bis=Decimal(25.0),
-        ),
-    ],
-)
-
 
 class TestTarifpreisposition:
     @pytest.mark.parametrize(
-        "tarifpreisposition, expected_json_dict",
+        "tarifpreisposition",
         [
-            pytest.param(
-                example_tarifpreisposition,
-                {
-                    "preistyp": "ENTGELT_ABLESUNG",
-                    "einheit": Waehrungseinheit.EUR,
-                    "bezugseinheit": Mengeneinheit.KWH,
-                    "preisstaffeln": [
-                        {
-                            "einheitspreis": Decimal("40"),
-                            "sigmoidparameter": None,
-                            "staffelgrenzeBis": Decimal("25"),
-                            "staffelgrenzeVon": Decimal("12.5"),
-                            "_id": None,
-                        }
-                    ],
-                    "mengeneinheitstaffel": None,
-                    "_id": None,
-                },
-                id="only required attributes",
-            ),
             pytest.param(
                 Tarifpreisposition(
                     preistyp=Preistyp.ENTGELT_ABLESUNG,
@@ -59,30 +24,12 @@ class TestTarifpreisposition:
                     ],
                     mengeneinheitstaffel=Mengeneinheit.STUECK,
                 ),
-                {
-                    "preistyp": "ENTGELT_ABLESUNG",
-                    "einheit": Waehrungseinheit.EUR,
-                    "bezugseinheit": Mengeneinheit.KWH,
-                    "preisstaffeln": [
-                        {
-                            "einheitspreis": Decimal("40"),
-                            "sigmoidparameter": None,
-                            "staffelgrenzeBis": Decimal("25"),
-                            "staffelgrenzeVon": Decimal("12.5"),
-                            "_id": None,
-                        }
-                    ],
-                    "mengeneinheitstaffel": Mengeneinheit.STUECK,
-                    "_id": None,
-                },
                 id="optional and required attributes",
             ),
         ],
     )
-    def test_serialization_roundtrip(
-        self, tarifpreisposition: Tarifpreisposition, expected_json_dict: Dict[str, Any]
-    ) -> None:
+    def test_serialization_roundtrip(self, tarifpreisposition: Tarifpreisposition) -> None:
         """
         Test de-/serialisation of Tarifpreisposition.
         """
-        assert_serialization_roundtrip(tarifpreisposition, expected_json_dict)
+        assert_serialization_roundtrip(tarifpreisposition)
diff --git a/tests/test_tarifpreispositionproort.py b/tests/test_tarifpreispositionproort.py
index bb37807bd..5185fc2db 100644
--- a/tests/test_tarifpreispositionproort.py
+++ b/tests/test_tarifpreispositionproort.py
@@ -1,16 +1,7 @@
 import pytest
-from pydantic import ValidationError
 
-from bo4e import TarifpreispositionProOrt
+from bo4e import TarifpreispositionProOrt, TarifpreisstaffelProOrt
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_tarifpreisstaffelproort import example_tarifpreisstaffelproort
-
-example_tarifpreispositionproort = TarifpreispositionProOrt(
-    postleitzahl="82031",
-    ort="Grünwald",
-    netznr="0815",
-    preisstaffeln=[example_tarifpreisstaffelproort],
-)
 
 
 class TestTarifpreispositionProOrt:
@@ -18,7 +9,12 @@ class TestTarifpreispositionProOrt:
         "tarifpreispositionproort",
         [
             pytest.param(
-                example_tarifpreispositionproort,
+                TarifpreispositionProOrt(
+                    postleitzahl="82031",
+                    ort="Grünwald",
+                    netznr="0815",
+                    preisstaffeln=[TarifpreisstaffelProOrt()],
+                ),
                 id="minimal and maximal attributes",
             ),
         ],
diff --git a/tests/test_tarifpreisstaffelproort.py b/tests/test_tarifpreisstaffelproort.py
index 92138f13e..67e7280d4 100644
--- a/tests/test_tarifpreisstaffelproort.py
+++ b/tests/test_tarifpreisstaffelproort.py
@@ -1,26 +1,23 @@
 from decimal import Decimal
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import TarifpreisstaffelProOrt
 from tests.serialization_helper import assert_serialization_roundtrip
 
-example_tarifpreisstaffelproort = TarifpreisstaffelProOrt(
-    arbeitspreis=Decimal(10),
-    arbeitspreis_n_t=Decimal(11),
-    grundpreis=Decimal(12),
-    staffelgrenze_von=Decimal(13),
-    staffelgrenze_bis=Decimal(14),
-)
-
 
 class TestTarifpreisstaffelProOrt:
     @pytest.mark.parametrize(
         "tarifpreisstaffelproort",
         [
             pytest.param(
-                example_tarifpreisstaffelproort,
+                TarifpreisstaffelProOrt(
+                    arbeitspreis=Decimal(10),
+                    arbeitspreis_n_t=Decimal(11),
+                    grundpreis=Decimal(12),
+                    staffelgrenze_von=Decimal(13),
+                    staffelgrenze_bis=Decimal(14),
+                ),
                 id="maximal (and minimal) attributes",
             ),
         ],
diff --git a/tests/test_unterschrift.py b/tests/test_unterschrift.py
index 2792c1429..dbe1d7119 100644
--- a/tests/test_unterschrift.py
+++ b/tests/test_unterschrift.py
@@ -1,44 +1,26 @@
 from datetime import datetime, timezone
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import Unterschrift
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestUnterschrift:
-    def test_unterschrift_only_required_attributes(self) -> None:
+    @pytest.mark.parametrize(
+        "unterschrift",
+        [
+            pytest.param(
+                Unterschrift(
+                    name="Foo",
+                    ort="Grünwald",
+                    datum=datetime(2019, 6, 7, tzinfo=timezone.utc),
+                ),
+            ),
+        ],
+    )
+    def test_serialization_roundtrip(self, unterschrift: Unterschrift) -> None:
         """
-        Test de-/serialisation of Unterschrift with minimal attributes.
+        Test de-/serialisation of Unterschrift.
         """
-        unterschrift = Unterschrift(name="Foo")
-
-        json_string = unterschrift.model_dump_json(by_alias=True)
-
-        assert "Foo" in json_string
-
-        unterschrift_deserialized = Unterschrift.model_validate_json(json_string)
-
-        assert isinstance(unterschrift_deserialized.name, str)
-        assert unterschrift_deserialized.name == "Foo"
-
-    def test_unterschrift_required_and_optional_attributes(self) -> None:
-        """
-        Test de-/serialisation of Unterschrift with maximal attributes.
-        """
-        unterschrift = Unterschrift(name="Foo", ort="Grünwald", datum=datetime(2019, 6, 7, tzinfo=timezone.utc))
-
-        json_string = unterschrift.model_dump_json(by_alias=True)
-
-        assert "Foo" in json_string
-        assert "Grünwald" in json_string
-        assert "2019-06-07T00:00:00Z" in json_string
-
-        unterschrift_deserialized = Unterschrift.model_validate_json(json_string)
-
-        assert isinstance(unterschrift_deserialized.name, str)
-        assert unterschrift_deserialized.name == "Foo"
-        assert isinstance(unterschrift_deserialized.ort, str)
-        assert unterschrift_deserialized.ort == "Grünwald"
-        assert isinstance(unterschrift_deserialized.datum, datetime)
-        assert unterschrift_deserialized.datum == datetime(2019, 6, 7, tzinfo=timezone.utc)
+        assert_serialization_roundtrip(unterschrift)
diff --git a/tests/test_verbrauch.py b/tests/test_verbrauch.py
index afdc496ad..fec9df884 100644
--- a/tests/test_verbrauch.py
+++ b/tests/test_verbrauch.py
@@ -1,25 +1,15 @@
 from datetime import datetime, timezone
 from decimal import Decimal
-from typing import Any, Dict
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import Mengeneinheit, Messwertstatus, Verbrauch, Wertermittlungsverfahren
 from tests.serialization_helper import assert_serialization_roundtrip
 
-example_verbrauch = Verbrauch(
-    wert=Decimal(40),
-    obis_kennzahl="1-0:1.8.1",
-    einheit=Mengeneinheit.KWH,
-    wertermittlungsverfahren=Wertermittlungsverfahren.MESSUNG,
-    messwertstatus=Messwertstatus.ABGELESEN,
-)
-
 
 class TestVerbrauch:
     @pytest.mark.parametrize(
-        "verbrauch, expected_json_dict",
+        "verbrauch",
         [
             pytest.param(
                 Verbrauch(
@@ -30,35 +20,21 @@ class TestVerbrauch:
                     einheit=Mengeneinheit.KWH,
                     wertermittlungsverfahren=Wertermittlungsverfahren.MESSUNG,
                     messwertstatus=Messwertstatus.ABGELESEN,
-                ),
-                {
-                    "startdatum": datetime(2021, 12, 1, 0, 0, tzinfo=timezone.utc),
-                    "wert": Decimal("40"),
-                    "einheit": Mengeneinheit.KWH,
-                    "enddatum": datetime(2021, 12, 2, 0, 0, tzinfo=timezone.utc),
-                    "wertermittlungsverfahren": Wertermittlungsverfahren.MESSUNG,
-                    "obisKennzahl": "1-0:1.8.1",
-                    "messwertstatus": Messwertstatus.ABGELESEN,
-                    "_id": None,
-                },
+                )
             ),
             pytest.param(
-                example_verbrauch,
-                {
-                    "wert": Decimal("40"),
-                    "einheit": Mengeneinheit.KWH,
-                    "wertermittlungsverfahren": Wertermittlungsverfahren.MESSUNG,
-                    "startdatum": None,
-                    "enddatum": None,
-                    "obisKennzahl": "1-0:1.8.1",
-                    "messwertstatus": Messwertstatus.ABGELESEN,
-                    "_id": None,
-                },
+                Verbrauch(
+                    wert=Decimal(40),
+                    obis_kennzahl="1-0:1.8.1",
+                    einheit=Mengeneinheit.KWH,
+                    wertermittlungsverfahren=Wertermittlungsverfahren.MESSUNG,
+                    messwertstatus=Messwertstatus.ABGELESEN,
+                ),
             ),
         ],
     )
-    def test_serialization_roundtrip(self, verbrauch: Verbrauch, expected_json_dict: Dict[str, Any]) -> None:
+    def test_serialization_roundtrip(self, verbrauch: Verbrauch) -> None:
         """
         Test de-/serialisation of Verbrauch.
         """
-        assert_serialization_roundtrip(verbrauch, expected_json_dict)
+        assert_serialization_roundtrip(verbrauch)
diff --git a/tests/test_vertrag.py b/tests/test_vertrag.py
index b1308ffdd..d88809309 100644
--- a/tests/test_vertrag.py
+++ b/tests/test_vertrag.py
@@ -1,8 +1,6 @@
 from datetime import datetime, timezone
-from typing import Any, Dict, List
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import (
     Adresse,
@@ -10,9 +8,7 @@
     Geschaeftspartner,
     Geschaeftspartnerrolle,
     Kontaktart,
-    Landescode,
     Sparte,
-    Typ,
     Unterschrift,
     Vertrag,
     Vertragsart,
@@ -20,258 +16,72 @@
     Vertragsstatus,
     Vertragsteil,
 )
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestVertrag:
-    _vertragsnummer = "1234567891011"
-    _vertragsart = Vertragsart.BILANZIERUNGSVERTRAG
-    _vertragsstatus = Vertragsstatus.AKTIV
-    _sparte = Sparte.STROM
-    _vertragsbeginn = datetime(2021, 4, 30, 13, 45, tzinfo=timezone.utc)
-    _vertragsende = datetime(2021, 6, 5, 16, 30, tzinfo=timezone.utc)
-    _vertragspartner1 = Geschaeftspartner(
-        anrede=Anrede.FRAU,
-        name1="von Sinnen",
-        name2="Helga",
-        name3=None,
-        ist_gewerbe=True,
-        kontaktweg=[Kontaktart.E_MAIL],
-        umsatzsteuer_id="DE267311963",
-        glaeubiger_id="DE98ZZZ09999999999",
-        e_mail_adresse="test@bo4e.de",
-        website="bo4e.de",
-        geschaeftspartnerrolle=[Geschaeftspartnerrolle.DIENSTLEISTER],
-        partneradresse=Adresse(
-            postleitzahl="24306",
-            ort="Plön",
-            strasse="Kirchstraße",
-            hausnummer="3",
-        ),
-    )
-    _vertragspartner2 = Geschaeftspartner(
-        name1="Eckart",
-        name2="Björn",
-        ist_gewerbe=False,
-        geschaeftspartnerrolle=[Geschaeftspartnerrolle.DIENSTLEISTER],
-        partneradresse=Adresse(
-            postleitzahl="24211",
-            ort="Preetz",
-            strasse="Am Markt",
-            hausnummer="67",
-        ),
+    @pytest.mark.parametrize(
+        "vertrag",
+        [
+            pytest.param(
+                Vertrag(
+                    vertragsnummer="1234567891011",
+                    vertragsart=Vertragsart.BILANZIERUNGSVERTRAG,
+                    vertragsstatus=Vertragsstatus.AKTIV,
+                    sparte=Sparte.STROM,
+                    vertragsbeginn=datetime(2021, 4, 30, 13, 45, tzinfo=timezone.utc),
+                    vertragsende=datetime(2021, 6, 5, 16, 30, tzinfo=timezone.utc),
+                    vertragspartner1=Geschaeftspartner(
+                        anrede=Anrede.FRAU,
+                        name1="von Sinnen",
+                        name2="Helga",
+                        name3=None,
+                        ist_gewerbe=True,
+                        kontaktweg=[Kontaktart.E_MAIL],
+                        umsatzsteuer_id="DE267311963",
+                        glaeubiger_id="DE98ZZZ09999999999",
+                        e_mail_adresse="test@bo4e.de",
+                        website="bo4e.de",
+                        geschaeftspartnerrolle=[Geschaeftspartnerrolle.DIENSTLEISTER],
+                        partneradresse=Adresse(
+                            postleitzahl="24306",
+                            ort="Plön",
+                            strasse="Kirchstraße",
+                            hausnummer="3",
+                        ),
+                    ),
+                    vertragspartner2=Geschaeftspartner(
+                        name1="Eckart",
+                        name2="Björn",
+                        ist_gewerbe=False,
+                        geschaeftspartnerrolle=[Geschaeftspartnerrolle.DIENSTLEISTER],
+                        partneradresse=Adresse(
+                            postleitzahl="24211",
+                            ort="Preetz",
+                            strasse="Am Markt",
+                            hausnummer="67",
+                        ),
+                    ),
+                    vertragsteile=[
+                        Vertragsteil(
+                            vertragsteilbeginn=datetime(2021, 4, 30, tzinfo=timezone.utc),
+                            vertragsteilende=datetime(2021, 6, 5, tzinfo=timezone.utc),
+                        ),
+                        Vertragsteil(
+                            vertragsteilbeginn=datetime(2001, 1, 23, tzinfo=timezone.utc),
+                            vertragsteilende=datetime(2002, 12, 3, tzinfo=timezone.utc),
+                        ),
+                    ],
+                    beschreibung="Hello Vertrag",
+                    vertragskonditionen=Vertragskonditionen(beschreibung="Beschreibung"),
+                    unterzeichnervp1=[Unterschrift(name="Foo")],
+                    unterzeichnervp2=[Unterschrift(name="Bar"), Unterschrift(name="Dr.No")],
+                ),
+            ),
+        ],
     )
-    _vertragsteile = [
-        Vertragsteil(
-            vertragsteilbeginn=datetime(2021, 4, 30, tzinfo=timezone.utc),
-            vertragsteilende=datetime(2021, 6, 5, tzinfo=timezone.utc),
-        )
-    ]
-    _vertragspartner1_dict: Dict[str, Any] = {
-        "_typ": Typ.GESCHAEFTSPARTNER,
-        "externeReferenzen": None,
-        "name1": "von Sinnen",
-        "istGewerbe": True,
-        "geschaeftspartnerrolle": [Geschaeftspartnerrolle.DIENSTLEISTER],
-        "anrede": "FRAU",
-        "name2": "Helga",
-        "name3": None,
-        "hrnummer": None,
-        "amtsgericht": None,
-        "kontaktweg": [Kontaktart.E_MAIL],
-        "umsatzsteuerId": "DE267311963",
-        "glaeubigerId": "DE98ZZZ09999999999",
-        "eMailAdresse": "test@bo4e.de",
-        "website": "bo4e.de",
-        "partneradresse": {
-            "postleitzahl": "24306",
-            "ort": "Plön",
-            "strasse": "Kirchstraße",
-            "hausnummer": "3",
-            "postfach": None,
-            "adresszusatz": None,
-            "coErgaenzung": None,
-            "landescode": Landescode.DE,  # type:ignore[attr-defined]
-            "ortsteil": None,
-            "_id": None,
-        },
-        "_id": None,
-    }
-    _vertragspartner2_dict: Dict[str, Any] = {
-        "_typ": Typ.GESCHAEFTSPARTNER,
-        "externeReferenzen": None,
-        "name1": "Eckart",
-        "istGewerbe": False,
-        "geschaeftspartnerrolle": [Geschaeftspartnerrolle.DIENSTLEISTER],
-        "anrede": None,
-        "name2": "Björn",
-        "name3": None,
-        "hrnummer": None,
-        "amtsgericht": None,
-        "kontaktweg": None,
-        "umsatzsteuerId": None,
-        "glaeubigerId": None,
-        "eMailAdresse": None,
-        "website": None,
-        "partneradresse": {
-            "postleitzahl": "24211",
-            "ort": "Preetz",
-            "strasse": "Am Markt",
-            "hausnummer": "67",
-            "postfach": None,
-            "adresszusatz": None,
-            "coErgaenzung": None,
-            "landescode": Landescode.DE,  # type:ignore[attr-defined]
-            "ortsteil": None,
-            "_id": None,
-        },
-        "_id": None,
-    }
-    _vertragsteile_dict: List[Dict[str, Any]] = [
-        {
-            "vertragsteilbeginn": datetime(2021, 4, 30, tzinfo=timezone.utc),
-            "vertragsteilende": datetime(2021, 6, 5, tzinfo=timezone.utc),
-            "lokation": None,
-            "vertraglichFixierteMenge": None,
-            "minimaleAbnahmemenge": None,
-            "maximaleAbnahmemenge": None,
-            "_id": None,
-        }
-    ]
-
-    def get_example_vertrag(self) -> Vertrag:
-        return Vertrag(
-            vertragsnummer=self._vertragsnummer,
-            vertragsart=self._vertragsart,
-            vertragsstatus=self._vertragsstatus,
-            sparte=self._sparte,
-            vertragsbeginn=self._vertragsbeginn,
-            vertragsende=self._vertragsende,
-            vertragspartner1=self._vertragspartner1,
-            vertragspartner2=self._vertragspartner2,
-            vertragsteile=self._vertragsteile,
-        )
-
-    def get_example_vertrag_expected_dict(self) -> Dict[str, Any]:
-        return {
-            "vertragsnummer": self._vertragsnummer,
-            "vertragsart": self._vertragsart,
-            "vertragsstatus": self._vertragsstatus,
-            "sparte": self._sparte,
-            "vertragsbeginn": self._vertragsbeginn,
-            "vertragsende": self._vertragsende,
-            "vertragspartner1": self._vertragspartner1_dict,
-            "vertragspartner2": self._vertragspartner2_dict,
-            "vertragsteile": self._vertragsteile_dict,
-            "_typ": Typ.VERTRAG,
-            "externeReferenzen": None,
-            "beschreibung": None,
-            "vertragskonditionen": None,
-            "unterzeichnervp1": None,
-            "unterzeichnervp2": None,
-            "_id": None,
-        }
-
-    def test_serialisation_only_required_attributes(self) -> None:
-        """
-        Test de-/serialisation of Vertrag with minimal attributes.
-        """
-        vertrag = self.get_example_vertrag()
-
-        json_string = vertrag.model_dump_json(by_alias=True)
-
-        assert vertrag.typ is Typ.VERTRAG, "_typ was not automatically set"
-        assert self._vertragsnummer in json_string
-        assert "BILANZIERUNGSVERTRAG" in json_string
-        assert "AKTIV" in json_string
-        assert "STROM" in json_string
-        assert "2021-04-30T13:45:00Z" in json_string
-        assert "2021-06-05T16:30:00Z" in json_string
-        assert "von Sinnen" in json_string
-        assert "Preetz" in json_string
-        assert "2021-06-05T00:00:00Z" in json_string
-
-        vertrag_deserialized = Vertrag.model_validate_json(json_string)
-
-        assert vertrag_deserialized.vertragsnummer == self._vertragsnummer
-        assert vertrag_deserialized.vertragsart == self._vertragsart
-        assert vertrag_deserialized.vertragsstatus == self._vertragsstatus
-        assert vertrag_deserialized.sparte == self._sparte
-        assert vertrag_deserialized.vertragsbeginn == self._vertragsbeginn
-        assert vertrag_deserialized.vertragsende == self._vertragsende
-        assert vertrag_deserialized.vertragspartner1 == self._vertragspartner1
-        assert vertrag_deserialized.vertragspartner2 == self._vertragspartner2
-        assert vertrag_deserialized.vertragsteile == self._vertragsteile
-
-    def test_serialisation_required_and_optional_attributes(self) -> None:
+    def test_serialization_roundtrip(self, vertrag: Vertrag) -> None:
         """
-        Test de-/serialisation of Vertrag with maximal attributes.
+        Test de-/serialisation of Vertrag.
         """
-
-        vertrag = Vertrag(
-            vertragsnummer=self._vertragsnummer,
-            vertragsart=self._vertragsart,
-            vertragsstatus=self._vertragsstatus,
-            sparte=self._sparte,
-            vertragsbeginn=self._vertragsbeginn,
-            vertragsende=self._vertragsende,
-            vertragspartner1=self._vertragspartner1,
-            vertragspartner2=self._vertragspartner2,
-            vertragsteile=[
-                Vertragsteil(
-                    vertragsteilbeginn=datetime(2021, 4, 30, tzinfo=timezone.utc),
-                    vertragsteilende=datetime(2021, 6, 5, tzinfo=timezone.utc),
-                ),
-                Vertragsteil(
-                    vertragsteilbeginn=datetime(2001, 1, 23, tzinfo=timezone.utc),
-                    vertragsteilende=datetime(2002, 12, 3, tzinfo=timezone.utc),
-                ),
-            ],
-            beschreibung="Hello Vertrag",
-            vertragskonditionen=Vertragskonditionen(beschreibung="Beschreibung"),
-            unterzeichnervp1=[Unterschrift(name="Foo")],
-            unterzeichnervp2=[Unterschrift(name="Bar"), Unterschrift(name="Dr.No")],
-        )
-
-        json_string = vertrag.model_dump_json(by_alias=True)
-
-        assert vertrag.typ is Typ.VERTRAG, "_typ was not automatically set"
-        assert self._vertragsnummer in json_string
-        assert "BILANZIERUNGSVERTRAG" in json_string
-        assert "AKTIV" in json_string
-        assert "STROM" in json_string
-        assert "2021-04-30T13:45:00Z" in json_string
-        assert "2021-06-05T16:30:00Z" in json_string
-        assert "von Sinnen" in json_string
-        assert "Preetz" in json_string
-        assert "2021-06-05T00:00:00Z" in json_string
-        assert "2002-12-03T00:00:00Z" in json_string
-        assert "Hello Vertrag" in json_string
-        assert "Beschreibung" in json_string
-        assert "Foo" in json_string
-        assert "Bar" in json_string
-        assert "Dr.No" in json_string
-
-        vertrag_deserialized = Vertrag.model_validate_json(json_string)
-
-        assert vertrag_deserialized.vertragsnummer == self._vertragsnummer
-        assert vertrag_deserialized.vertragsart == self._vertragsart
-        assert vertrag_deserialized.vertragsstatus == self._vertragsstatus
-        assert vertrag_deserialized.sparte == self._sparte
-        assert vertrag_deserialized.vertragsbeginn == self._vertragsbeginn
-        assert vertrag_deserialized.vertragsende == self._vertragsende
-        assert vertrag_deserialized.vertragspartner1 == self._vertragspartner1
-        assert vertrag_deserialized.vertragspartner2 == self._vertragspartner2
-        assert vertrag_deserialized.vertragsteile == [
-            Vertragsteil(
-                vertragsteilbeginn=datetime(2021, 4, 30, tzinfo=timezone.utc),
-                vertragsteilende=datetime(2021, 6, 5, tzinfo=timezone.utc),
-            ),
-            Vertragsteil(
-                vertragsteilbeginn=datetime(2001, 1, 23, tzinfo=timezone.utc),
-                vertragsteilende=datetime(2002, 12, 3, tzinfo=timezone.utc),
-            ),
-        ]
-        assert vertrag_deserialized.beschreibung == "Hello Vertrag"
-        assert vertrag_deserialized.vertragskonditionen == Vertragskonditionen(beschreibung="Beschreibung")
-        assert vertrag_deserialized.unterzeichnervp1 == [Unterschrift(name="Foo")]
-        assert vertrag_deserialized.unterzeichnervp2 == [Unterschrift(name="Bar"), Unterschrift(name="Dr.No")]
+        assert_serialization_roundtrip(vertrag)
diff --git a/tests/test_vertragskonditionen.py b/tests/test_vertragskonditionen.py
index 192a84cce..f21f391cc 100644
--- a/tests/test_vertragskonditionen.py
+++ b/tests/test_vertragskonditionen.py
@@ -1,56 +1,36 @@
 from datetime import datetime, timezone
 from decimal import Decimal
 
-from bo4e import Mengeneinheit, Vertragskonditionen, Zeitraum
+import pytest
 
-example_vertragskonditionen = Vertragskonditionen(
-    beschreibung="Foobar",
-    anzahl_abschlaege=Decimal(3),
-    vertragslaufzeit=Zeitraum(
-        startdatum=datetime(2012, 9, 21, tzinfo=timezone.utc),
-        enddatum=datetime(2013, 10, 11, tzinfo=timezone.utc),
-    ),
-    kuendigungsfrist=Zeitraum(einheit=Mengeneinheit.WOCHE, dauer=Decimal(3)),
-    vertragsverlaengerung=Zeitraum(einheit=Mengeneinheit.TAG, dauer=Decimal(14)),
-    abschlagszyklus=Zeitraum(einheit=Mengeneinheit.TAG, dauer=Decimal(5)),
-)
+from bo4e import Mengeneinheit, Vertragskonditionen, Zeitraum
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestVertragskonditionen:
-    def test_vertragskonditionen_with_optional_attributes(self) -> None:
-        """
-        Test de-/serialisation of Vertragskonditionen (only has optional attributes).
-        """
-        vertragskonditionen = example_vertragskonditionen
-
-        json_string = vertragskonditionen.model_dump_json(by_alias=True)
-
-        assert "Foobar" in json_string
-        assert "3" in json_string
-        assert "2013-10-11T00:00:00Z" in json_string
-        assert "WOCHE" in json_string
-        assert "TAG" in json_string
-        assert "14" in json_string
-
-        vertragskonditionen_deserialized = Vertragskonditionen.model_validate_json(json_string)
-
-        assert isinstance(vertragskonditionen_deserialized.beschreibung, str)
-        assert vertragskonditionen_deserialized.beschreibung == "Foobar"
-        assert isinstance(vertragskonditionen_deserialized.anzahl_abschlaege, Decimal)
-        assert vertragskonditionen_deserialized.anzahl_abschlaege == Decimal(3)
-        assert isinstance(vertragskonditionen_deserialized.vertragslaufzeit, Zeitraum)
-        assert vertragskonditionen_deserialized.vertragslaufzeit == Zeitraum(
-            startdatum=datetime(2012, 9, 21, tzinfo=timezone.utc), enddatum=datetime(2013, 10, 11, tzinfo=timezone.utc)
-        )
-        assert isinstance(vertragskonditionen_deserialized.vertragsverlaengerung, Zeitraum)
-        assert vertragskonditionen_deserialized.vertragsverlaengerung == Zeitraum(
-            einheit=Mengeneinheit.TAG, dauer=Decimal(14)
-        )
-
-    def test_vertragskonditionen_empty(self) -> None:
+    @pytest.mark.parametrize(
+        "vertragskonditionen",
+        [
+            pytest.param(
+                Vertragskonditionen(
+                    beschreibung="Foobar",
+                    anzahl_abschlaege=Decimal(3),
+                    vertragslaufzeit=Zeitraum(
+                        startdatum=datetime(2012, 9, 21, tzinfo=timezone.utc),
+                        enddatum=datetime(2013, 10, 11, tzinfo=timezone.utc),
+                    ),
+                    kuendigungsfrist=Zeitraum(einheit=Mengeneinheit.WOCHE, dauer=Decimal(3)),
+                    vertragsverlaengerung=Zeitraum(einheit=Mengeneinheit.TAG, dauer=Decimal(14)),
+                    abschlagszyklus=Zeitraum(einheit=Mengeneinheit.TAG, dauer=Decimal(5)),
+                ),
+            ),
+            pytest.param(
+                Vertragskonditionen(),
+            ),
+        ],
+    )
+    def test_serialization_roundtrip(self, vertragskonditionen: Vertragskonditionen) -> None:
         """
-        Test empty Vertragskonditionen (only has optional attributes).
+        Test de-/serialisation of Vertragskonditionen.
         """
-        empty_vertragskonditionen = Vertragskonditionen()
-
-        assert isinstance(empty_vertragskonditionen, Vertragskonditionen)
+        assert_serialization_roundtrip(vertragskonditionen)
diff --git a/tests/test_vertragsteil.py b/tests/test_vertragsteil.py
index 86e98b4e8..2a324630d 100644
--- a/tests/test_vertragsteil.py
+++ b/tests/test_vertragsteil.py
@@ -2,61 +2,29 @@
 from decimal import Decimal
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import Menge, Mengeneinheit, Vertragsteil
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestVertragsteil:
-    def test_vertragsteil_only_required_attributes(self) -> None:
+    @pytest.mark.parametrize(
+        "vertragsteil",
+        [
+            pytest.param(
+                Vertragsteil(
+                    vertragsteilbeginn=datetime(2001, 3, 15, tzinfo=timezone.utc),
+                    vertragsteilende=datetime(2007, 11, 27, tzinfo=timezone.utc),
+                    lokation="Bar",
+                    vertraglich_fixierte_menge=Menge(wert=Decimal(3.1), einheit=Mengeneinheit.KWH),
+                    minimale_abnahmemenge=Menge(wert=Decimal(2000), einheit=Mengeneinheit.KWH),
+                    maximale_abnahmemenge=Menge(wert=Decimal(0.111111), einheit=Mengeneinheit.KWH),
+                ),
+            ),
+        ],
+    )
+    def test_serialization_roundtrip(self, vertragsteil: Vertragsteil) -> None:
         """
-        Test de-/serialisation of Vertragsteil with minimal attributes.
+        Test de-/serialisation of Vertragsteil.
         """
-        vertragsteil = Vertragsteil(
-            vertragsteilbeginn=datetime(2001, 3, 15, tzinfo=timezone.utc),
-            vertragsteilende=datetime(2007, 11, 27, tzinfo=timezone.utc),
-        )
-
-        json_string = vertragsteil.model_dump_json(by_alias=True)
-
-        assert "2001-03-15T00:00:00Z" in json_string
-        assert "2007-11-27T00:00:00Z" in json_string
-
-        vertragsteil_deserialized = Vertragsteil.model_validate_json(json_string)
-
-        assert isinstance(vertragsteil_deserialized.vertragsteilbeginn, datetime)
-        assert vertragsteil_deserialized.vertragsteilbeginn == datetime(2001, 3, 15, tzinfo=timezone.utc)
-        assert isinstance(vertragsteil_deserialized.vertragsteilende, datetime)
-        assert vertragsteil_deserialized.vertragsteilende == datetime(2007, 11, 27, tzinfo=timezone.utc)
-
-    def test_vertragsteil_required_and_optional_attributes(self) -> None:
-        """
-        Test de-/serialisation of Vertragsteil with maximal attributes.
-        """
-        vertragsteil = Vertragsteil(
-            vertragsteilbeginn=datetime(2001, 3, 15, tzinfo=timezone.utc),
-            vertragsteilende=datetime(2007, 11, 27, tzinfo=timezone.utc),
-            lokation="Bar",
-            vertraglich_fixierte_menge=Menge(wert=Decimal(3.1), einheit=Mengeneinheit.KWH),
-            minimale_abnahmemenge=Menge(wert=Decimal(2000), einheit=Mengeneinheit.KWH),
-            maximale_abnahmemenge=Menge(wert=Decimal(0.111111), einheit=Mengeneinheit.KWH),
-        )
-
-        json_string = vertragsteil.model_dump_json(by_alias=True)
-
-        assert "2001-03-15T00:00:00Z" in json_string
-        assert "2007-11-27T00:00:00Z" in json_string
-        assert "Bar" in json_string
-        assert "KWH" in json_string
-        assert "0.111111" in json_string
-
-        vertragsteil_deserialized = Vertragsteil.model_validate_json(json_string)
-
-        assert isinstance(vertragsteil_deserialized.vertragsteilbeginn, datetime)
-        assert vertragsteil_deserialized.vertragsteilbeginn == datetime(2001, 3, 15, tzinfo=timezone.utc)
-        assert isinstance(vertragsteil_deserialized.vertragsteilende, datetime)
-        assert vertragsteil_deserialized.vertragsteilende == datetime(2007, 11, 27, tzinfo=timezone.utc)
-        assert isinstance(vertragsteil_deserialized.lokation, str)
-        assert vertragsteil_deserialized.lokation == "Bar"
-        assert isinstance(vertragsteil_deserialized.minimale_abnahmemenge, Menge)
-        assert vertragsteil_deserialized.minimale_abnahmemenge == Menge(wert=Decimal(2000), einheit=Mengeneinheit.KWH)
+        assert_serialization_roundtrip(vertragsteil)
diff --git a/tests/test_zaehler.py b/tests/test_zaehler.py
index 8c75b4b03..38a396428 100644
--- a/tests/test_zaehler.py
+++ b/tests/test_zaehler.py
@@ -2,77 +2,34 @@
 from decimal import Decimal
 
 import pytest
-from pydantic import ValidationError
 
-from bo4e import (
-    Energierichtung,
-    ExterneReferenz,
-    Mengeneinheit,
-    Registeranzahl,
-    Sparte,
-    Typ,
-    Zaehler,
-    Zaehlerauspraegung,
-    Zaehlertyp,
-    Zaehlwerk,
-)
-
-example_zaehler = Zaehler(
-    zaehlernummer="000111222",
-    sparte=Sparte.STROM,
-    zaehlerauspraegung=Zaehlerauspraegung.EINRICHTUNGSZAEHLER,
-    zaehlwerke=[
-        Zaehlwerk(
-            zaehlwerk_id="98765",
-            einheit=Mengeneinheit.KW,
-            richtung=Energierichtung.EINSP,
-            bezeichnung="my zaehlwerk",
-            obis_kennzahl="1-0:1.8.1",
-            wandlerfaktor=Decimal(0.95),
-        )
-    ],
-    zaehlertyp=Zaehlertyp.DREHSTROMZAEHLER,
-    registeranzahl=Registeranzahl.ZWEITARIF,
-    zaehlerkonstante=Decimal(0.9),
-    eichung_bis=datetime(2022, 1, 1, 0, 0, 0),
-    externe_referenzen=[ExterneReferenz(ex_ref_name="zaehler im anderen system", ex_ref_wert="7890")],
-    letzte_eichung=datetime(2019, 6, 30, 0, 0, 0),
-)
+from bo4e import Registeranzahl, Sparte, Zaehler, Zaehlerauspraegung, Zaehlertyp, Zaehlwerk
+from bo4e.zusatzattribut import ZusatzAttribut
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestZaehler:
-    def test_de_serialisation(self) -> None:
+    @pytest.mark.parametrize(
+        "zaehler",
+        [
+            pytest.param(
+                Zaehler(
+                    zaehlernummer="000111222",
+                    sparte=Sparte.STROM,
+                    zaehlerauspraegung=Zaehlerauspraegung.EINRICHTUNGSZAEHLER,
+                    zaehlwerke=[Zaehlwerk()],
+                    zaehlertyp=Zaehlertyp.DREHSTROMZAEHLER,
+                    registeranzahl=Registeranzahl.ZWEITARIF,
+                    zaehlerkonstante=Decimal(0.9),
+                    eichung_bis=datetime(2022, 1, 1, 0, 0, 0),
+                    zusatz_attribute=[ZusatzAttribut(name="zaehler im anderen system", wert="7890")],
+                    letzte_eichung=datetime(2019, 6, 30, 0, 0, 0),
+                ),
+            ),
+        ],
+    )
+    def test_serialization_roundtrip(self, zaehler: Zaehler) -> None:
         """
-        Test de-/serialisation of Zaehler only with required attributes
+        Test de-/serialisation of Zaehler.
         """
-        zaehler = Zaehler(
-            zaehlernummer="000111222",
-            sparte=Sparte.STROM,
-            zaehlerauspraegung=Zaehlerauspraegung.EINRICHTUNGSZAEHLER,
-            zaehlwerke=[
-                Zaehlwerk(
-                    zaehlwerk_id="98765",
-                    einheit=Mengeneinheit.KW,
-                    richtung=Energierichtung.EINSP,
-                    bezeichnung="my zaehlwerk",
-                    obis_kennzahl="1-0:1.8.1",
-                    wandlerfaktor=Decimal(0.95),
-                )
-            ],
-            zaehlertyp=Zaehlertyp.DREHSTROMZAEHLER,
-            registeranzahl=Registeranzahl.ZWEITARIF,
-            zaehlerkonstante=Decimal(0.9),
-            eichung_bis=datetime(2022, 1, 1, 0, 0, 0),
-            externe_referenzen=[ExterneReferenz(ex_ref_name="zaehler im anderen system", ex_ref_wert="7890")],
-            letzte_eichung=datetime(2019, 6, 30, 0, 0, 0),
-        )
-        assert zaehler.version is not None, "versionstruktur was not automatically set"
-        assert zaehler.typ is Typ.ZAEHLER, "_typ was not automatically set"
-        assert zaehler.zaehlwerke is not None
-        assert zaehler.zaehlwerke[0].richtung == Energierichtung.EINSP
-        assert zaehler.zaehlwerke[0].einheit == Mengeneinheit.KW
-        json_string = zaehler.model_dump_json(by_alias=True)
-        assert "richtung" in json_string, "Zaehlwerk->richtung was not serialized"
-        assert "einheit" in json_string, "Zaehlwerk->einheit was not serialized"
-        deserialized_zaehler = Zaehler.model_validate_json(json_string)
-        assert deserialized_zaehler == zaehler
+        assert_serialization_roundtrip(zaehler)
diff --git a/tests/test_zeitraum.py b/tests/test_zeitraum.py
index 5f7deddf3..88f9c817e 100644
--- a/tests/test_zeitraum.py
+++ b/tests/test_zeitraum.py
@@ -1,83 +1,25 @@
-from datetime import datetime, timezone
 from decimal import Decimal
-from typing import Dict
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import Mengeneinheit, Zeitraum
-
-example_zeitraum = Zeitraum(
-    einheit=Mengeneinheit.TAG,
-    dauer=Decimal(5),
-)
-example_zeitraum_dict = {
-    "dauer": Decimal("5"),
-    "startdatum": None,
-    "endzeitpunkt": None,
-    "einheit": Mengeneinheit.TAG,
-    "enddatum": None,
-    "startzeitpunkt": None,
-    "_id": None,
-}
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestZeitraum:
-    def test_zeitraum_dauer(self) -> None:
-        """
-        Test de-/serialisation of Zeitraum (only has optional attributes) with option dauer and einheit.
-        """
-        zeitraum = Zeitraum(einheit=Mengeneinheit.TAG, dauer=Decimal(21))
-
-        json_string = zeitraum.model_dump_json(by_alias=True)
-
-        assert "21" in json_string
-        assert "TAG" in json_string
-
-        zeitraum_deserialized = Zeitraum.model_validate_json(json_string)
-
-        assert isinstance(zeitraum_deserialized.einheit, Mengeneinheit)
-        assert zeitraum_deserialized.einheit == Mengeneinheit.TAG
-        assert isinstance(zeitraum_deserialized.dauer, Decimal)
-        assert zeitraum_deserialized.dauer == Decimal(21)
-
-    def test_zeitraum_daten(self) -> None:
+    @pytest.mark.parametrize(
+        "zeitraum",
+        [
+            pytest.param(
+                Zeitraum(
+                    einheit=Mengeneinheit.TAG,
+                    dauer=Decimal(21),
+                ),
+            ),
+        ],
+    )
+    def test_serialization_roundtrip(self, zeitraum: Zeitraum) -> None:
         """
-        Test de-/serialisation of Zeitraum (only has optional attributes) with option startdatum and enddatum.
+        Test de-/serialisation of Zeitraum.
         """
-        zeitraum = Zeitraum(
-            startdatum=datetime(2013, 5, 1, tzinfo=timezone.utc), enddatum=datetime(2022, 1, 28, tzinfo=timezone.utc)
-        )
-
-        json_string = zeitraum.model_dump_json(by_alias=True)
-
-        assert "2013-05-01T00:00:00Z" in json_string
-        assert "2022-01-28T00:00:00Z" in json_string
-
-        zeitraum_deserialized = Zeitraum.model_validate_json(json_string)
-
-        assert isinstance(zeitraum_deserialized.startdatum, datetime)
-        assert zeitraum_deserialized.startdatum == datetime(2013, 5, 1, tzinfo=timezone.utc)
-        assert isinstance(zeitraum_deserialized.enddatum, datetime)
-        assert zeitraum_deserialized.enddatum == datetime(2022, 1, 28, tzinfo=timezone.utc)
-
-    def test_zeitraum_zeitpunkte(self) -> None:
-        """
-        Test de-/serialisation of Zeitraum (only has optional attributes) with option startzeitpunkt and endzeitpunkt.
-        """
-        zeitraum = Zeitraum(
-            startzeitpunkt=datetime(2011, 2, 5, 16, 43, tzinfo=timezone.utc),
-            endzeitpunkt=datetime(2021, 7, 30, tzinfo=timezone.utc),
-        )
-
-        json_string = zeitraum.model_dump_json(by_alias=True)
-
-        assert "2011-02-05T16:43:00Z" in json_string
-        assert "2021-07-30T00:00:00Z" in json_string
-
-        zeitraum_deserialized = Zeitraum.model_validate_json(json_string)
-
-        assert isinstance(zeitraum_deserialized.startzeitpunkt, datetime)
-        assert zeitraum_deserialized.startzeitpunkt == datetime(2011, 2, 5, 16, 43, tzinfo=timezone.utc)
-        assert isinstance(zeitraum_deserialized.endzeitpunkt, datetime)
-        assert zeitraum_deserialized.endzeitpunkt == datetime(2021, 7, 30, tzinfo=timezone.utc)
+        assert_serialization_roundtrip(zeitraum)
diff --git a/tests/test_zeitreihe.py b/tests/test_zeitreihe.py
index 6bbbcb58d..8a9954cab 100644
--- a/tests/test_zeitreihe.py
+++ b/tests/test_zeitreihe.py
@@ -1,9 +1,7 @@
 import pytest
-from pydantic import ValidationError
 
 from bo4e import Medium, Mengeneinheit, Messart, Messgroesse, Wertermittlungsverfahren, Zeitreihe
 from tests.serialization_helper import assert_serialization_roundtrip
-from tests.test_zeitreihenwert import example_zeitreihenwert
 
 
 class TestZeitreihe:
@@ -20,7 +18,7 @@ class TestZeitreihe:
                     medium=Medium.STROM,
                     einheit=Mengeneinheit.KVARH,
                     wertherkunft=Wertermittlungsverfahren.MESSUNG,
-                    werte=[example_zeitreihenwert],
+                    werte=[],
                 )
             ),
         ],
diff --git a/tests/test_zeitreihenwert.py b/tests/test_zeitreihenwert.py
index 0cc7f5258..924844181 100644
--- a/tests/test_zeitreihenwert.py
+++ b/tests/test_zeitreihenwert.py
@@ -2,63 +2,29 @@
 from decimal import Decimal
 
 import pytest
-from pydantic import ValidationError
 
 from bo4e import Messwertstatus, Messwertstatuszusatz, Zeitreihenwert, Zeitspanne
-
-example_zeitreihenwert = Zeitreihenwert(
-    wert=Decimal(2.5),
-    zeitspanne=Zeitspanne(
-        start=datetime(2013, 5, 1, tzinfo=timezone.utc), ende=datetime(2022, 1, 28, tzinfo=timezone.utc)
-    ),
-)
+from tests.serialization_helper import assert_serialization_roundtrip
 
 
 class TestZeitreihenwert:
-    def test_zeitreihenwert_only_required_attributes(self) -> None:
-        """
-        Test de-/serialisation of Zeitreihenwert with minimal attributes.
-        """
-        zeitreihenwert = example_zeitreihenwert
-
-        json_string = zeitreihenwert.model_dump_json(by_alias=True)
-
-        assert "2013-05-01T00:00:00Z" in json_string
-        assert "2022-01-28T00:00:00Z" in json_string
-
-        zeitreihenwert_deserialized: Zeitreihenwert = Zeitreihenwert.model_validate_json(json_string)
-        assert zeitreihenwert_deserialized == zeitreihenwert
-
-    def test_zeitreihenwert_required_and_optional_attributes(self) -> None:
+    @pytest.mark.parametrize(
+        "zeitreihenwert",
+        [
+            pytest.param(
+                Zeitreihenwert(
+                    zeitspanne=Zeitspanne(
+                        start=datetime(2013, 5, 1, tzinfo=timezone.utc), ende=datetime(2022, 1, 28, tzinfo=timezone.utc)
+                    ),
+                    wert=Decimal(2.5),
+                    status=Messwertstatus.ABGELESEN,
+                    statuszusatz=Messwertstatuszusatz.Z78_GERAETEWECHSEL,
+                ),
+            ),
+        ],
+    )
+    def test_serialization_roundtrip(self, zeitreihenwert: Zeitreihenwert) -> None:
         """
-        Test de-/serialisation of Zeitreihenwert with maximal attributes.
+        Test de-/serialisation of Zeitreihenwert.
         """
-        zeitreihenwert = Zeitreihenwert(
-            zeitspanne=Zeitspanne(
-                start=datetime(2013, 5, 1, tzinfo=timezone.utc), ende=datetime(2022, 1, 28, tzinfo=timezone.utc)
-            ),
-            wert=Decimal(2.5),
-            status=Messwertstatus.ABGELESEN,
-            statuszusatz=Messwertstatuszusatz.Z78_GERAETEWECHSEL,
-        )
-
-        json_string = zeitreihenwert.model_dump_json(by_alias=True)
-
-        assert "2.5" in json_string
-        assert "ABGELESEN" in json_string
-        assert "Z78_GERAETEWECHSEL" in json_string
-        assert "2013-05-01T00:00:00Z" in json_string
-        assert "2022-01-28T00:00:00Z" in json_string
-
-        zeitreihenwert_deserialized: Zeitreihenwert = Zeitreihenwert.model_validate_json(json_string)
-        assert zeitreihenwert_deserialized == zeitreihenwert
-
-        assert isinstance(zeitreihenwert_deserialized.wert, Decimal)
-        assert isinstance(zeitreihenwert_deserialized.status, Messwertstatus)
-        assert isinstance(zeitreihenwert_deserialized.statuszusatz, Messwertstatuszusatz)
-
-    def test_wrong_datatype(self) -> None:
-        with pytest.raises(ValidationError) as excinfo:
-            _ = Zeitreihenwert(wert="helloooo")  # type: ignore[arg-type]
-
-        assert "wert" in str(excinfo.value)
+        assert_serialization_roundtrip(zeitreihenwert)
diff --git a/tests/test_zusatz_attribut.py b/tests/test_zusatz_attribut.py
new file mode 100644
index 000000000..fecd87ef3
--- /dev/null
+++ b/tests/test_zusatz_attribut.py
@@ -0,0 +1,39 @@
+import pytest
+
+from bo4e.bo.geschaeftspartner import Geschaeftspartner
+from bo4e.com.adresse import Adresse
+from bo4e.enum.geschaeftspartnerrolle import Geschaeftspartnerrolle
+from bo4e.zusatzattribut import ZusatzAttribut
+from tests.serialization_helper import assert_serialization_roundtrip
+
+
+class TestZusatzAttribut:
+    @pytest.mark.parametrize(
+        "geschaeftspartner",
+        [
+            pytest.param(
+                Geschaeftspartner(
+                    zusatz_attribute=[
+                        ZusatzAttribut(name="SAP GP Nummer", wert="0123456789"),
+                        ZusatzAttribut(name="Schufa-ID", wert="aksdlakoeuhn"),
+                    ],
+                    # just some dummy data to make the GP valid
+                    name1="Duck",
+                    name2="Donald",
+                    ist_gewerbe=False,
+                    geschaeftspartnerrolle=[Geschaeftspartnerrolle.KUNDE],
+                    partneradresse=Adresse(
+                        strasse="Am Geldspeicher",
+                        hausnummer="17",
+                        postleitzahl="88101",
+                        ort="Entenhausen",
+                    ),
+                ),
+            ),
+        ],
+    )
+    def test_serialization_roundtrip(self, geschaeftspartner: Geschaeftspartner) -> None:
+        """
+        Test de-/serialisation of Geschaeftspartner.
+        """
+        assert_serialization_roundtrip(geschaeftspartner)