Testgetriebene Entwicklung mit Laravel & Doctrine

Als PHP-Entwickler können Sie die TDD-Technik (Test-Driven Development) verwenden, um Ihre Software durch Schreiben von Tests zu entwickeln. In der Regel teilt TDD jede Aufgabe der Entwicklung in einzelne Einheiten auf. Anschließend wird ein Test geschrieben, um sicherzustellen, dass sich das Gerät wie erwartet verhält.

Jedes Projekt, das Test-Driven Development verwendet, führt wiederholt drei einfache Schritte aus:

  • Schreiben Sie einen Test für die nächste Funktion, die Sie hinzufügen möchten.
  • Schreiben Sie den Funktionscode, bis der Test bestanden ist.
  • Ersetzen Sie sowohl den neuen als auch den alten Code, um ihn strukturiert zu gestalten.

Durchlaufen Sie diese drei Schritte nacheinander, und testen Sie die Funktionen des Systems. Tests helfen Ihnen beim Umgestalten, wodurch Sie Ihr Design im Laufe der Zeit verbessern können und einige Designprobleme offensichtlicher werden.

Die Tests, die kleine Einzelkomponenten enthalten, werden aufgerufen Unit-Tests. Während Komponententests unabhängig voneinander durchgeführt werden können, müssen Sie einige der Komponenten testen, wenn diese in andere Komponenten integriert sind Integrationstest. Die dritte Art von Tests ist Teststubs. Mit Teststubs können Sie Ihren Code testen, ohne echte Datenbankanrufe tätigen zu müssen.

Warum funktioniert TDD?

Da heutzutage moderne PHP-IDE-Syntax verwendet werden kann, ist das Feedback keine große Sache. Ein wichtiger Aspekt Ihrer Entwicklung ist es sicherzustellen, dass der Code das tut, was Sie erwarten. Da Software kompliziert ist (verschiedene Komponenten sind miteinander integriert), wäre es für alle unsere Erwartungen schwierig, diese zu erfüllen. Insbesondere am Ende des Projekts wird das Projekt aufgrund Ihrer Entwicklung komplexer und damit schwieriger zu debuggen und zu testen.

TDD überprüft, ob der Code das tut, was Sie erwarten. Wenn etwas schief geht, gibt es nur wenige Codezeilen, die erneut geprüft werden müssen. Fehler sind leicht zu finden und zu beheben. In TDD konzentriert sich der Test auf das Verhalten, nicht auf die Implementierung. TDD bietet bewährten Code, der getestet, entworfen und codiert wurde.

PHPUnit & Laravel

PHPUnit ist der De-facto-Standard für das Testen von Unit-PHP. Es ist im Wesentlichen ein Rahmen für das Schreiben von Tests und die Bereitstellung der Tools, die Sie zum Ausführen von Tests und zur Analyse der Ergebnisse benötigen. PHPUnit leitet seine Struktur und Funktionalität aus dem SUnit von Kent Beck ab.

Es gibt verschiedene Zusicherungen, mit deren Hilfe Sie die Ergebnisse aller Arten von Anrufen in Ihren Anwendungen testen können. Manchmal müssen Sie etwas kreativer sein, um eine komplexere Funktionalität testen zu können. Die von PHPUnit bereitgestellten Assertions decken jedoch die meisten Fälle ab, die Sie testen möchten. Hier finden Sie eine Liste einiger der häufigsten, die Sie in Ihren Tests verwenden werden:

  • AssertTrue: Überprüfen Sie die Eingabe, um zu bestätigen, dass sie true ist.
  • AssertFalse: Überprüfen Sie die Eingabe, um sicherzustellen, dass sie dem falschen Wert entspricht.
  • AssertEquals: Prüfen Sie das Ergebnis anhand einer anderen Eingabe auf Übereinstimmung.
  • AssertArrayHasKey (): Meldet einen Fehler, wenn das Array nicht über den Schlüssel verfügt.
  • AssertGreaterThan: Überprüfen Sie das Ergebnis, um zu sehen, ob es größer als ein Wert ist.
  • AssertContains: Überprüfen Sie, ob die Eingabe einen bestimmten Wert enthält.
  • AssertType: Überprüfen Sie, ob eine Variable einen bestimmten Typ hat.
  • AssertNull: Überprüfen Sie, ob eine Variable NULL ist.
  • AssertFileExists: Stellen Sie sicher, dass eine Datei vorhanden ist.
  • AssertRegExp: Überprüfen Sie die Eingabe anhand eines regulären Ausdrucks.

Standardmäßig ist PHPUnit 4.0 in Laravel installiert. Sie können den folgenden Befehl ausführen, um es zu aktualisieren:

bash composer global erfordert "phpunit / phpunit = 5.0. *"

Das phpunit.xml Datei im Laravel-Stammverzeichnis können Sie einige Konfigurationen vornehmen. In diesem Fall können Sie die Datei bearbeiten, wenn Sie die Standardkonfiguration überschreiben möchten:

"xml

./ Tests / app /

"

Wie Sie im obigen Code sehen, habe ich die Beispiel-Datenbankkonfiguration (nicht im Artikel verwendet) hinzugefügt.

Was ist Lehre ORM??

Doctrine ist ein ORM, der das Data-Mapper-Muster implementiert und die saubere Trennung der Geschäftsregeln der Anwendung von der Persistenzschicht der Datenbank ermöglicht. Um Doctrine einzurichten, gibt es eine Brücke, die eine Anpassung an die vorhandene Konfiguration von Laravel 5 ermöglicht. Um Doctrine 2 in unserem Laravel-Projekt zu installieren, führen wir den folgenden Befehl aus:

Bash-Komponist benötigt Laravel-Doktrin / Orm

Wie üblich sollte das Paket dem hinzugefügt werden app / config.php, als Dienstleister:

PHP LaravelDoctrine \ ORM \ DoctrineServiceProvider :: Klasse,

Der Alias ​​sollte auch konfiguriert werden:

php 'EntityManager' => LaravelDoctrine \ ORM \ Facades \ EntityManager :: Klasse

Zum Schluss veröffentlichen wir die Paketkonfiguration mit:

bash php handwerker hersteller: publish --tag = "config"

So testen Sie Doktrin-Repositories

Vor allem sollten Sie über Fixtures Bescheid wissen. Fixtures werden verwendet, um einen kontrollierten Datensatz in eine Datenbank zu laden, die wir zum Testen benötigen. Glücklicherweise verfügt Doctrine 2 über eine Bibliothek, mit der Sie Fixtures für Doctrine ORM schreiben können.

Um das Fixtures-Paket in unserer Laravel App zu installieren, müssen Sie den folgenden Befehl ausführen:

bash composer benötigt --dev doctrine / doctrine-fixtures-bundle

Lassen Sie uns unser Fixture erstellen tests / Fixtures.php:

"php Namespace Test; verwenden Sie Doctrine \ Common \ Persistence \ ObjectManager; verwenden Sie Doctrine \ Common \ DataFixtures \ FixtureInterface; verwenden Sie app \ Entity \ Post;

Klasse Fixtures implementiert FixtureInterface / ** * Laden der Post-Fixtures * @param ObjectManager $ manager * @return void * / public Funktion laden (ObjectManager $ manager) $ Post = neuer Beitrag (['title' => 'hallo Welt') , 'body' => 'this is body']); $ manager-> persist ($ Post); $ manager-> flush ();

"

Wie Sie sehen, sollte Ihre Fixture-Klasse das implementieren FixtureInterface und sollte die haben Laden (ObjectManager $ manager) Methode. Doctrine2-Fixtures sind PHP-Klassen, in denen Sie Objekte erstellen und in der Datenbank speichern können. Um unsere Geräte in Laravel automatisch laden zu können, müssen wir sie anpassen composer.json in unserer Laravelwurzel:

json… "autoload-dev": "classmap": ["tests / TestCase.php", "tests / Fixtures.php" // hier hinzugefügt],…

Dann renne:

bash composer dump-autoload

Lassen Sie uns unsere Testdatei im Testverzeichnis erstellen DoctrineTest.php.

"php Namespace Test; App verwenden; App \ Entity \ Post verwenden; Doctrine \ Common \ DataFixtures \ Executor \ ORMExecutor verwenden. Doctrine \ Common \ DataFixtures \ Purger \ ORMPurger; Doctrine \ Common \ DataFixtures \ Loader. App \ Repository verwenden \ PostRepo;

class doctrineTest erweitert TestCase private $ em; privates $ Repository; privater $ loader; öffentliche Funktion setUp () parent :: setUp (); $ this-> em = App :: make ('Doctrine \ ORM \ EntityManagerInterface'); $ this-> repository = new PostRepo ($ this-> em); $ this-> executor = neuer ORMExecutor ($ this-> em, neuer ORMPurger); $ this-> loader = neuer Loader; $ this-> loader-> addFixture (neue Fixtures);

/ ** @test * / public function post () $ purger = neuer ORMPurger (); $ executor = neuer ORMExecutor ($ this-> em, $ purger); $ executor-> ausführen ($ this-> loader-> getFixtures ()); $ user = $ this-> repository-> PostOfTitle ('Hallo Welt'); $ this-> em-> clear (); $ this-> assertInstanceOf ('App \ Entity \ Post', $ user);  "

In dem Konfiguration() Methode, instanziiere ich die ORMExecutor und der Loader. Wir laden auch die Fixtures Klasse, die wir gerade implementiert haben.

Vergiss das nicht /** @Prüfung */ Annotation ist sehr wichtig, und ohne dies wird die phpunit a zurückgeben Keine Tests im Unterricht gefunden Error.

Um mit dem Testen in unserem Projektstamm zu beginnen, führen Sie einfach den folgenden Befehl aus:

bash sudo phpunit

Das Ergebnis wäre:

"bash PHPUnit 4.6.6 von Sebastian Bergmann und Mitwirkenden.

Konfiguration aus /var/www/html/laravel/phpunit.xml gelesen. Zeit: 17,06 Sekunden, Speicher: 16,00M OK (1 Test, 1 Assertion) "

Wenn Sie Objekte zwischen Fixtures freigeben möchten, können Sie auf einfache Weise einen Verweis auf dieses Objekt anhand des Namens hinzufügen und später darauf verweisen, um eine Beziehung zu bilden. Hier ist ein Beispiel:

"php Namespace Test; verwenden Sie Doctrine \ Common \ Persistence \ ObjectManager; verwenden Sie Doctrine \ Common \ DataFixtures \ FixtureInterface; verwenden Sie app \ Entity \ Post;

Klasse PostFixtures implementiert FixtureInterface / ** * Laden der User-Fixtures * * @param ObjectManager $ manager * @return void * / public Funktion laden (ObjectManager $ manager) $ postOne = neuer Beitrag (['title' => 'hello') , 'body' => 'this is body']); $ postTwo = neuer Post (['title' => 'hallo dort', 'body' => 'das ist body zwei']); $ manager-> persist ($ postOne); $ manager-> persist ($ postTwo); $ manager-> flush ();

 // Verweis auf Administratorrolle für Benutzerbeziehung zu Rolle speichern $ this-> addReference ('new-post', $ postOne);  "

und das Kommentar-Fixture:

"php Namespace Test; verwenden Sie Doctrine \ Common \ Persistence \ ObjectManager; verwenden Sie Doctrine \ Common \ DataFixtures \ FixtureInterface; verwenden Sie app \ Entity \ Post;

class CommentFixtures implementiert FixtureInterface / ** * Laden der User-Fixtures * * @param ObjectManager $ manager * @return void * / public Funktion laden (ObjectManager $ manager) $ comment = new Kommentar (['title' => 'hello') , 'email' => '[email protected]', 'text' => 'nice post']); $ comment-> setPost ($ this-> getReference ('new-post')); // den gespeicherten Verweis laden $ manager-> persist ($ comment); $ manager-> flush (); // speichere den Verweis auf den neuen Beitrag für die Kommentarbeziehung zum Post $ this-> addReference ('new-post', $ postOne); "

Mit zwei Methoden von getReference () und setReference (), Sie können Objekte zwischen Geräten teilen.

Wenn Ihnen die Bestellung von Geräten wichtig ist, können Sie diese einfach mit der getOrder Methode in Ihren Geräten wie folgt:

php public function getOrder () return 5; // Nummer in welcher Reihenfolge zum Laden von Fixtures

Beachten Sie, dass die Bestellung für die Loader-Klasse relevant ist.

Eines der wichtigsten Dinge bei Fixtures ist die Fähigkeit, Abhängigkeitsprobleme zu lösen. Das einzige, was Sie hinzufügen müssen, ist eine Methode in Ihrem Gerät, wie ich es unten gemacht habe:

php public function getDependencies () return array ('Test \ CommentFixtures'); // Fixture-Klassen Fixture hängt von

Fazit

Dies ist nur eine Beschreibung von Test-Driven Development mit Laravel 5 und PHPUnit. Beim Testen von Repositorys ist es unvermeidlich, dass Sie die Datenbank erreichen. In diesem Fall sind Doctrine-Scheinwerfer wichtig.