Hoofdstuk 10 · oefening
Bewijs het gedrag van de database
Geef elke test een nieuwe database
Een databasetest is moeilijk te vertrouwen wanneer rijen van gisteren in het resultaat van vandaag kunnen belanden. Je eerste taak is één test een eigen catalog.db te geven, daar het huidige schema op te bouwen, de database te sluiten en opnieuw te openen voordat je de laatste assertion uitvoert.
De projectbestanden hebben vier rollen. Bewerk alleen tests/test_catalog.py. catalog_setup.py bereidt schema’s voor en controleert ze, catalog_db.py bevat de gecontroleerde query- en opdrachtfuncties en catalog_import.py bevat de gecontroleerde CSV-import. Laat die drie programmamodules ongewijzigd. Het zichtbare bestand run_tests.py is het startpunt van het project dat je testbestand uitvoert.
Pytest geeft deze test een nieuw argument tmp_path. Een pad zoals tmp_path / "catalog.db" hoort alleen bij die testuitvoering, zodat een andere test de database niet kan erven. Maak create_fresh_database(tmp_path, filename="catalog.db") af: leid het pad af van tmp_path, roep catalog_setup.prepare_database(database_path) aan en geef datzelfde pad terug.
Maak daarna test_fresh_database_has_the_current_schema(tmp_path) af. Gebruik create_fresh_database, open het resulterende bestand met sqlite3.connect en lees de namen van gebruikerstabellen en de kolommen van alle drie de tabellen in hun volgorde. De exacte structuur van versie 2 is:
items:id,asset_tag,name,category,loan_daysmembers:id,member_code,name,loan_limit,emailloans:id,item_id,member_id,checked_out_on,returned_on
Sluit die verbinding in finally. Open hetzelfde pad opnieuw, lees PRAGMA user_version en sluit opnieuw. Door de volledige structuur te vergelijken, ontdek je een database die slechts gedeeltelijk actueel is. Ook heropenen is van belang: het bewijst dat je het bestand leest en niet een toestand die alleen op één verbinding bestaat.
Druk op Run. run_tests.py gaat naar de projectmap en roept precies pytest.main(["-q", "-p", "no:cacheprovider", "tests/test_catalog.py"]) aan. Bij een fout zie je het nuttige rapport van pytest. Succes wordt zo samengevat:
Database tests passed: 1
Gebruik Run voor de pytest-tests van dit hoofdstuk. De afzonderlijke werkbalkactie Run project tests gebruikt de kleine testrunner van Python Land, die geen pytest-fixtures zoals tmp_path meegeeft.
Submit voert je test ook uit met een nieuw tijdelijk pad en controleert dat die een voorbereidingsfunctie opmerkt die ergens anders schrijft. Een database die in versiebeheer staat, een vervangende database in het geheugen of een assertion die maar één tabel controleert, kan dat bewijs niet leveren. Zodra dit slaagt, volgt elke latere test dezelfde isolatieregel.
Opdracht
Maak create_fresh_database(tmp_path, filename="catalog.db") en test_fresh_database_has_the_current_schema(tmp_path) in tests/test_catalog.py af. Bouw het pad onder tmp_path, roep catalog_setup.prepare_database aan, inspecteer de exacte structuur met drie tabellen van versie 2, sluit, open opnieuw en controleer met een assertion dat user_version gelijk is aan 2. Laat de gecontroleerde programmamodules ongewijzigd.