Het korte antwoord is Lees de fijne handleiding over databasetesten in de PHPUnit-handleiding .
En nu het lange antwoord...
Het eerste dat u moet onthouden over het testen van eenheden, is dat het moet worden uitgevoerd in isolatie van alle andere componenten. Vaak wordt dit doel vereenvoudigd met behulp van inversion of control (IoC) technieken zoals dependency injection . Wanneer uw klassen expliciet vragen om hun afhankelijkheden in de constructormethoden, is het een eenvoudige handeling om spotten die afhankelijkheden zodat u de resterende code afzonderlijk kunt testen.
Het testen van code die interageert met modellen is echter een beetje anders. Meestal is het niet praktisch of raadzaam om je modellen te injecteren in de klas waarin je ze nodig hebt. Uw modellen zijn over het algemeen "domme" datastructuren die beperkte of geen mogelijkheden blootleggen. Als gevolg hiervan is het over het algemeen acceptabel (in termen van testbaarheid) om uw modellen on-the-fly te instantiëren binnen uw anders geïnjecteerde klassen. Helaas maakt dit het testen van databasecode moeilijk omdat, zoals de documentatie van PHPUnit aangeeft:
Dus hoe isoleer en test je code die interageert met de database als de modellen niet direct worden geïnjecteerd? De eenvoudigste manier om dit te doen is door gebruik te maken van testopstellingen .
Aangezien je zeker al gebruik maakt van PDO
of een ORM-bibliotheek die voortbouwt op PDO
(toch?), het opzetten van de armaturen is net zo eenvoudig als het zaaien van een standaard SQLite-database of XML-bestand met gegevens voor uw testgevallen en het gebruik van die speciale databaseverbinding wanneer u de code test die interactie heeft met de database. Je zou deze verbinding kunnen specificeren in je PHPUnit-bootstrap-bestand, maar het is waarschijnlijk semantisch beter om een PHPUnit Database TestCase
.
De algemeen aanvaarde best practice-stappen voor het testen van DB-code (deze worden ook herhaald in de PHPUnit-documentatie over DB-testen):
- Opstelling armatuur
- Trainingssysteem wordt getest
- Uitkomst verifiëren
- Afbreken
Dus, om samen te vatten, alles wat je hoeft te doen is een "dummy" database armatuur te maken en je code te laten interageren met die bekende gegevens in plaats van een echte database die je in productie zou gebruiken. Met deze methode kunt u de te testen code met succes isoleren omdat deze met bekende gegevens omgaat, en dit betekent dat u specifieke/testbare beweringen kunt doen over de resultaten van uw databasebewerkingen.
UPDATE
Gewoon omdat het een buitengewoon nuttige gids is voor wat niet te doen in uw code als u testbaarheid wilt bevorderen, voeg ik een link toe naar Misko Hevery's Hoe schrijf je 3v1L, niet-testbare code . Het is niet specifiek betrokken bij het testen van databases, maar het is niettemin nuttig. Veel plezier met testen!
UPDATE 2
Ik wilde reageren op de opmerking over het uitstellen van modeltesten omdat de bestaande codebasis PDO
niet implementeert voor databasetoegang:
Uw modellen hoeven geen PDO te gebruiken om de DbUnit-extensie van PHPUnit te implementeren.
Het zal je leven een beetje makkelijker maken als je PDO gebruikt, maar je bent niet verplicht dit te doen. Stel dat u bijvoorbeeld uw applicatie heeft gebouwd met de ingebouwde pg_*
van PHP PostgreSQL-functies. Met PHPUnit kun je nog steeds fixtures specificeren en ze kunnen ze nog steeds opnieuw opbouwen voor elke test - je hoeft alleen maar je verbinding te richten bij het uitvoeren van tests naar dezelfde bron die de DbUnit-extensie gebruikt voor zijn fixture.