Det korta svaret är att läs The Fine Manual-posten om databastestning i PHPUnit-manualen .
Och nu det långa svaret ...
Det första att komma ihåg om enhetstestning är att det måste utföras isolerat från alla andra komponenter. Ofta förenklas detta mål med IoC-tekniker (inversion of control) som beroendeinjektion . När dina klasser uttryckligen frågar efter deras beroenden i konstruktormetoderna är det en enkel operation att håna dessa beroenden så att du kan testa den återstående koden isolerat.
Att testa kod som interagerar med modeller är dock lite annorlunda. Vanligtvis är det inte praktiskt eller tillrådligt att injicera dina modeller i den klass där du behöver komma åt dem. Dina modeller är i allmänhet "dumma" datastrukturer som exponerar begränsade eller inga möjligheter. Som ett resultat är det allmänt acceptabelt (när det gäller testbarhet) att instansiera dina modeller i farten i dina annars injicerade klasser. Tyvärr gör detta det svårt att testa databaskod eftersom, som PHPUnit-dokumentationen noterar:
Så hur isolerar och testar man kod som interagerar med databasen om modellerna inte är direkt injicerade? Det enklaste sättet att göra detta är att använda testfixturer .
Eftersom du definitivt redan använder PDO
eller ett ORM-bibliotek som bygger på PDO
(rätt?), att ställa in fixturerna är lika enkelt som att skapa en grundläggande SQLite-databas eller XML-fil med data för att passa dina testfall och använda den speciella databasanslutningen när du testar koden som interagerar med databasen. Du kan ange denna anslutning i din PHPUnit bootstrap-fil, men det är förmodligen mer semantiskt lämpligt att ställa in en PHPUnit Database TestCase
.
De allmänt accepterade bästa metoderna för att testa DB-kod (dessa återfinns också i PHPUnit-dokumentationen om DB-testning):
- Konfigurera fixtur
- Träningssystem under test
- Verifiera resultatet
- Rivning
Så, för att sammanfatta, allt du behöver göra är att skapa en "dummy" databasfixtur och få din kod att interagera med den kända data istället för en faktisk databas du skulle använda i produktionen. Denna metod gör att du framgångsrikt kan isolera koden som testas eftersom den handlar om känd data, och det betyder att du kan göra specifika/testbara påståenden om resultaten av dina databasoperationer.
UPPDATERA
Bara för att det är en utomordentligt användbar guide för vad inte att göra i din kod om du vill främja testbarhet, jag lägger till en länk till Misko Heverys Hur man skriver 3v1L, otestbar kod . Det är inte involverat i databastestning i synnerhet, men det är ändå användbart. Lycka till med testet!
UPPDATERING 2
Jag ville svara på kommentaren om att skjuta upp modelltestning eftersom den befintliga kodbasen inte implementerar PDO
för databasåtkomst:
Dina modeller behöver inte använda PDO för att implementera PHPUnits DbUnit-tillägg.
Det kommer att göra ditt liv lite lättare om du använder PDO, men du är inte skyldig att göra det. Säg till exempel att du har byggt din applikation med PHPs inbyggda pg_*
PostgreSQL-funktioner. PHPUnit låter dig fortfarande specificera fixturer och det kan fortfarande bygga om dem för varje test -- du skulle helt enkelt behöva peka din anslutning när du utför tester till samma resurs som DbUnit-tillägget använder för sin fixtur.