Testdriven utveckling med Laravel & Läran

Som en PHP-utvecklare kan du använda tekniken för testdriven utveckling (TDD) för att utveckla din programvara genom att skriva test. Typiskt kommer TDD att dela upp varje uppgift av utvecklingen i enskilda enheter. Ett test skrivs sedan för att säkerställa att enheten beter sig som förväntat.

Varje projekt som använder testdriven utveckling följer tre enkla steg flera gånger:

  • Skriv ett test för nästa bit av funktionalitet du vill lägga till.
  • Skriv funktionskoden tills testet passerar.
  • Refactor både ny och gammal kod för att göra det väl strukturerat.

Fortsätt cykla genom dessa tre steg, ett test i taget, bygga upp systemets funktionalitet. Testning hjälper dig att refactor, vilket gör att du kan förbättra din design över tiden och göra vissa designproblem mer uppenbara.

Testerna som innehåller små enskilda komponenter kallas enhetstester. Medan enhetstest kan utföras självständigt, om du testar några av komponenterna när de är integrerade med andra komponenter, gör du det integrationsprovning. Den tredje typen av testning är teststubbar. Teststubbar gör att du kan testa din kod utan att behöva göra riktiga samtal till en databas.

Varför TDD fungerar

Nuförtiden, eftersom du kan använda modern PHP IDE-syntax är feedback inte en stor sak. En av de viktiga aspekterna av din utveckling är att se till att koden gör vad du förväntar dig att göra. Eftersom programvaran är komplicerad (olika komponenter integrerad med varandra) skulle det vara svårt för alla våra förväntningar att bli sanna. Speciellt i slutet av projektet, på grund av din utveckling, kommer projektet att bli mer komplext och därmed svårare att felsöka och testa.

TDD verifierar att koden gör vad du förväntar dig att göra. Om något går fel, finns det bara några rader av kod som ska kontrolleras igen. Misstag är lätta att hitta och fixa. I TDD fokuserar testet på beteendet, inte genomförandet. TDD tillhandahåller beprövad kod som har testats, konstruerats och kodats.

PHPUnit & Laravel

PHPUnit är de facto-standarden för enhetstestning av PHP. Det är i huvudsak en ram för att skriva test och tillhandahålla de verktyg som du behöver för att köra test och analysera resultaten. PHPUnit härleder sin struktur och funktionalitet från Kent Becks SUnit.

Det finns flera olika påståenden som kan hjälpa dig att testa resultaten av alla slags samtal i dina applikationer. Ibland måste du vara lite mer kreativ för att testa en mer komplex funktionalitet, men påståenden från PHPUnit täcker de flesta fall du vill testa. Här är en lista över några av de vanligaste som du kommer att hitta dig själv i dina tester:

  • assertTrue: Kontrollera inmatningen för att verifiera att den är sann.
  • AssertFalse: Kontrollera inmatningen för att verifiera den är lika med falskt värde.
  • AssertEquals: Kontrollera resultatet mot en annan ingång för en matchning.
  • AssertArrayHasKey (): Rapporterar ett fel om array inte har nyckeln.
  • AssertGreaterThan: Kontrollera resultatet för att se om det är större än ett värde.
  • AssertContains: Kontrollera att ingången innehåller ett visst värde.
  • AssertType: Kontrollera att en variabel är av en viss typ.
  • AssertNull: Kontrollera att en variabel är null.
  • AssertFileExists: Verifiera att en fil finns.
  • AssertRegExp: Kontrollera inmatningen mot ett reguljärt uttryck.

Som standard är PHPUnit 4.0 installerat i Laravel, och du kan springa följande kommando för att uppdatera det:

bash-kompositör globalt kräver "phpunit / phpunit = 5.0. *"

De phpunit.xml filen i Laravel root-katalogen låter dig göra vissa konfigurationer. I det här fallet, om du vill åsidosätta standardkonfigurationen kan du redigera filen:

"xml

./ test / app/

"

Som du ser i koden ovan har jag lagt till provet (som inte används i artikeln) -databaskonfigurationen.

Vad är lära ORM?

Läran är en ORM som implementerar data mapper mönstret och låter dig göra en ren separation av programmets affärsregler från databasens uthållighetslager. För att ställa upp Läran finns en bro för att möjliggöra matchning med Laravel 5s befintliga konfiguration. För att installera Läran 2 i vårt Laravel-projekt kör vi följande kommando:

bash-kompositören kräver laravel-doktrin / orm

Som vanligt ska paketet läggas till app / config.php, som tjänsteleverantör:

php LaravelDoctrine \ ORM \ DoctrineServiceProvider :: klass,

Aliaset ska också konfigureras:

php 'EntityManager' => LaravelDoctrine \ ORM \ Fasader \ EntityManager :: klass

Slutligen publicerar vi paketkonfigurationen med:

bash php artisan leverantör: publicera - tag = "config"

Hur man testar doktrinsupplagor

Innan något annat borde du veta om armaturer. Fixtures används för att ladda en kontrollerad uppsättning data till en databas, som vi behöver för testning. Lyckligtvis har Läran 2 ett bibliotek som hjälper dig att skriva in fixturer för Läran ORM.

För att installera fixturesbuntet i vår Laravel App måste vi springa följande kommando:

bash-kompositören kräver -dev-lära / doktrin-fixtures-bunt

Låt oss skapa vår armatur i test / Fixtures.php:

"php namespace Test, använd doktrin \ Common \ Persistence \ ObjectManager; använd doktrin \ Common \ DataFixtures \ FixtureInterface; använd app \ Entity \ Post;

Klassificeringsverktyget implementerar FixtureInterface / ** * Ladda postfästningarna * @param ObjectManager $ manager * @return void * / public function load (ObjectManager $ manager) $ Post = ny Post (['title' => 'Hello World' , 'body' => 'det här är kroppen']); $ Manager-> kvarstår ($ Post); $ Manager-> flush ();

"

Som du ser, bör din armaturklass implementera FixtureInterface och borde ha ladda (ObjectManager $ manager) metod. Läran2 fixturer är PHP klasser där du kan skapa objekt och fortsätta dem till databasen. För att autoload våra armaturer i Laravel måste vi ändra composer.json i vår Laravel root:

json ... "autoload-dev": "klasskarta": ["test / TestCase.php", "test / Fixtures.php" // lagt till här), ...

Kör sedan:

bash-kompositör dump-autoload

Låt oss skapa vår testfil i testkatalogen DoctrineTest.php.

"php namespace Test, använd App, använd App \ Entity \ Post, använd doktrin \ Common \ DataFixtures \ Executor \ ORMExecutor; använd doktrin \ Common \ DataFixtures \ Purger \ ORMPurger; använd doktrin \ Common \ DataFixtures \ Loader; använd App \ Repository \ PostRepo;

klassdoktrinTest utökar TestCase private $ em; privat $ repository; privat $ loader; allmän funktion setUp () förälder :: setUp (); $ this-> em = App :: make ('Läran \ ORM \ EntityManagerInterface'); $ this-> repository = new PostRepo ($ this-> em); $ this-> executor = ny ORMExecutor ($ this-> em, ny ORMPurger); $ this-> loader = new Loader; $ this-> loader-> addFixture (new fixtures);

/ ** @test * / public function post () $ renare = ny ORMPurger (); $ exekverare = ny ORMExecutor ($ this-> em, $ purger); $ Executor-> execute ($ this-> loader-> getFixtures ()); $ user = $ this-> repository-> PostOfTitle ('hej värld'); $ This-> syssel-> clear (); $ this-> assertInstanceOf ('App \ Entity \ Post', $ användare);  "

I inrätta() metod, jag instanserar ORMExecutor och lastaren. Vi laddar också fixturer klass vi just genomfört.

Glöm inte att / ** @test * / annotering är mycket viktigt, och utan detta kommer funktit att returnera a Inga tester hittades i klassen fel.

För att börja testa i vår projektrot, kör bara kommandot:

bash sudo phpunit

Resultatet skulle vara:

"bash PHPUnit 4.6.6 av Sebastian Bergmann och bidragsgivare.

Konfigurationen läses från /var/www/html/laravel/phpunit.xml. Tid: 17,06 sekunder, Minne: 16,00M OK (1 test, 1 påstående) "

Om du vill dela objekt mellan fixturer är det möjligt att enkelt lägga till en referens till det objektet med namnet och referera det senare till en relation. Här är ett exempel:

"php namespace Test, använd doktrin \ Common \ Persistence \ ObjectManager; använd doktrin \ Common \ DataFixtures \ FixtureInterface; använd app \ Entity \ Post;

klass PostFixtures implementerar FixtureInterface / ** * Ladda användarinställningarna * * @param ObjectManager $ manager * @return void * / public function load (ObjectManager $ manager) $ postOne = ny Post (['title' => 'hej' , 'body' => 'det här är kroppen']); $ postTwo = ny post (['title' => 'hej där', 'body' => 'detta är kropp två']); $ Manager-> kvarstår ($ postOne); $ Manager-> kvarstår ($ postTwo); $ Manager-> flush ();

 // lagra referens till admin roll för användarrelation till roll $ this-> addReference ('new-post', $ postOne);  "

och kommentarfästet:

"php namespace Test, använd doktrin \ Common \ Persistence \ ObjectManager; använd doktrin \ Common \ DataFixtures \ FixtureInterface; använd app \ Entity \ Post;

class CommentFixtures implementerar FixtureInterface / ** * Ladda användarinställningarna * * @param ObjectManager $ manager * @return void * / public function load (ObjectManager $ manager) $ comment = new Kommentar (['title' => 'hej' , 'email' => '[email protected]', 'text' => 'trevligt inlägg']); $ Comment-> setPost ($ this-> getReference (nya inlägg)); // ladda den sparade referensen $ manager-> persist ($ comment); $ Manager-> flush (); // lagra referens till nytt inlägg för Kommentar relation till post $ this-> addReference ('new-post', $ postOne); "

Med två metoder av getReference () och setReference (), du kan dela objekt mellan armarna.

Om beställning av armaturer är viktigt för dig, kan du enkelt beställa dem med getOrder metod i din armatur som följer:

php public function getOrder () return 5; // nummer i vilken ordning att ladda in armaturer

Observera att beställningen är relevant för Loader-klassen.

En av de viktiga sakerna kring fixturer är deras förmåga att lösa beroendeproblem. Det enda du behöver lägga till är en metod i din armatur som jag gjorde nedan:

php public function getDependencies () return array ('Test \ CommentFixtures'); // fixtur klassen fixtur är beroende av

Slutsats

Detta är bara en beskrivning av testdriven utveckling med Laravel 5 och PHPUnit. Vid testning av arkiv är det oundvikligt att du kommer att slå databasen. I det här fallet är läranordningar viktiga.