Das Datenbankverhalten belegen · Übung
Eine defekte Fremdschlüsselprüfung erkennen
Eine konfigurierte Verbindung soll einen Ausleihvorgang ablehnen, dessen Gegenstand oder Mitglied nicht existiert. Einen von PRAGMA foreign_keys gemeldeten Wert zu sehen ist ein schwächerer Nachweis, als den verbotenen Schreibzugriff zu versuchen und sowohl die Ausnahme als auch die unveränderte Datenbank zu beobachten.
Bearbeite tests/test_catalog.py und vervollständige test_foreign_keys_reject_missing_parents(tmp_path). Beginne mit create_fresh_database(tmp_path, "foreign-keys.db") und öffne dann über catalog_db.open_database(database_path). Diese öffentliche Verbindungsfabrik ist die getestete Schnittstelle.
Bereite mit gebundenen INSERT-Aufrufen einen echten Gegenstand und ein echtes Mitglied vor und schreibe dann diesen bekannten Ausgangszustand fest. Versuche einen Ausleihvorgang mit fehlender Gegenstands-ID, während die Mitglieds-ID gültig ist. Verwende pytest.raises(sqlite3.IntegrityError) um den einzelnen execute()-Aufruf und rolle danach zurück, damit die Verbindung für den nächsten Versuch bereit ist. Wiederhole das mit gültiger Gegenstands-ID und fehlender Mitglieds-ID. Beide Fehler sollen der sqlite3.IntegrityError der Datenbank sein, kein vom Test gewählter Fehler wegen eines doppelten Primärschlüssels.
Schließe die ausführende Verbindung. Öffne denselben Pfad mit einer neuen Verbindung und wähle die Ausleih-IDs aus. Sichere zu, dass keine Ausleihzeile existiert. Diese letzte Beobachtung beantwortet eine andere Frage als die Ausnahme: Der Fehler trat auf und hinterließ keinen dauerhaft gespeicherten Teilzustand.
Es mag verlockend sein, nur zuzusichern, dass die Fremdschlüsseldurchsetzung eingeschaltet ist. Das prüft eine Einstellung, belegt aber nicht, dass die zugesagte Grenze mit echten Verweisen auf übergeordnete Datensätze funktioniert. Ebenso belegt eine Abfrage nur über die ursprüngliche Verbindung nicht, was eine andere Verbindung sehen wird.
Klicke auf Run. Der feste Einstieg ruft pytest.main(["-q", "-p", "no:cacheprovider", "tests/test_catalog.py"]) auf und sollte Folgendes melden:
Database tests passed: 3
Submit führt die gesammelten Tests zweimal aus und prüft diese Geschichte dann gegen eine Verbindungsfabrik, die Fremdschlüssel nicht mehr aktiviert. Wenn der neue Test die exakte Ausnahme erwartet und erneut öffnet, um die Ausleihvorgänge zu untersuchen, erkennt er diese Verhaltensänderung. Die anderen beiden Tests bleiben unabhängig, weil jede Funktion ihren eigenen tmp_path erhält und ihren eigenen Dateinamen wählt.
Aufgabe
Vervollständige test_foreign_keys_reject_missing_parents(tmp_path) in tests/test_catalog.py. Bereite über catalog_db.open_database einen gültigen Gegenstand und ein gültiges Mitglied vor, erwarte sqlite3.IntegrityError für einen fehlenden Gegenstand und ein fehlendes Mitglied, rolle jeden Versuch zurück, schließe, öffne erneut und sichere zu, dass keine Ausleihzeile erhalten blieb.