Développement piloté par les tests avec Laravel & Doctrine

En tant que développeur PHP, vous pouvez utiliser la technique TDD (Test-Driven Development) pour développer votre logiciel en écrivant des tests. En règle générale, TDD divisera chaque tâche du développement en unités individuelles. Un test est ensuite écrit pour s'assurer que l'unité se comporte comme prévu.

Chaque projet utilisant le développement piloté par les tests suit trois étapes simples à plusieurs reprises:

  • Ecrivez un test pour le prochain bit de fonctionnalité que vous souhaitez ajouter.
  • Écrire le code fonctionnel jusqu'à la réussite du test.
  • Refactoriser le code ancien et le code nouveau pour le rendre bien structuré.

Continuez à parcourir ces trois étapes, test par test, en développant les fonctionnalités du système. Les tests vous aideront à refactoriser, ce qui vous permettra d’améliorer votre conception au fil du temps et de mettre en évidence certains problèmes de conception..

Les tests contenant de petits composants individuels sont appelés tests unitaires. Alors que les tests unitaires peuvent être effectués indépendamment, si vous testez certains composants lorsqu'ils sont intégrés à d'autres composants, vous effectuez test d'intégration. Le troisième type de test est bouts d'essai. Les talons de test vous permettent de tester votre code sans avoir à faire de vrais appels à une base de données.

Pourquoi TDD fonctionne

De nos jours, comme vous pouvez utiliser la syntaxe moderne IDE PHP, les retours d'informations ne sont pas une grosse affaire. L'un des aspects importants de votre développement est de vous assurer que le code fait ce que vous attendez de lui. Les logiciels étant compliqués (différents composants étant intégrés les uns aux autres), il serait difficile de répondre à toutes nos attentes. En particulier à la fin du projet, en raison de votre développement, le projet deviendra plus complexe et donc plus difficile à déboguer et à tester..

TDD vérifie que le code fait ce que vous attendez de lui. Si quelque chose ne va pas, il n'y a que quelques lignes de code à revérifier. Les erreurs sont faciles à trouver et à corriger. En TDD, le test porte sur le comportement, pas sur la mise en œuvre. TDD fournit un code éprouvé qui a été testé, conçu et codé.

PHPUnit & Laravel

PHPUnit est le standard de facto pour les tests unitaires PHP. Il s'agit essentiellement d'un cadre permettant de rédiger des tests et de fournir les outils nécessaires pour exécuter des tests et analyser les résultats. PHPUnit tire sa structure et ses fonctionnalités de SUnit de Kent Beck.

Plusieurs affirmations peuvent vous aider à tester les résultats de toutes sortes d'appels dans vos applications. Parfois, vous devez être un peu plus créatif pour tester une fonctionnalité plus complexe, mais les assertions fournies par PHPUnit couvrent la majorité des cas que vous souhaitez tester. Voici une liste des plus courants que vous utiliserez dans vos tests:

  • AssertTrue: Vérifiez l'entrée pour vérifier qu'elle est égale à true.
  • AssertFalse: Vérifiez l'entrée pour vérifier qu'elle est égale à la valeur fausse.
  • AssertEquals: Comparer le résultat avec une autre entrée pour une correspondance.
  • AssertArrayHasKey (): Signale une erreur si le tableau n'a pas la clé.
  • AssertGreaterThan: Vérifiez le résultat pour voir s'il est supérieur à une valeur.
  • AssertContains: Vérifie que l'entrée contient une certaine valeur.
  • AssertType: Vérifie qu'une variable est d'un certain type.
  • AssertNull: Vérifier qu'une variable est nulle.
  • AssertFileExists: Vérifier qu'un fichier existe.
  • AssertRegExp: Vérifie l'entrée par rapport à une expression régulière.

Par défaut, PHPUnit 4.0 est installé à Laravel et vous pouvez exécuter la commande suivante pour le mettre à jour:

bash composer global nécessite "phpunit / phpunit = 5.0. *"

le phpunit.xml Un fichier dans le répertoire racine de Laravel vous permettra d’effectuer certaines configurations. Dans ce cas, si vous souhaitez remplacer la configuration par défaut, vous pouvez éditer le fichier:

"xml

./ tests / app /

"

Comme vous le voyez dans le code ci-dessus, j'ai ajouté l'exemple de configuration de la base de données (non utilisé dans l'article)..

Qu'est-ce que la doctrine ORM??

Doctrine est un ORM qui implémente le modèle de mappeur de données et vous permet de bien séparer les règles de gestion de l'application de la couche de persistance de la base de données. Pour configurer Doctrine, il existe un pont permettant la correspondance avec la configuration existante de Laravel 5. Pour installer Doctrine 2 dans notre projet Laravel, nous exécutons la commande suivante:

compositeur bash exige laravel-doctrine / orm

Comme d'habitude, le paquet devrait être ajouté à la app / config.php, en tant que prestataire de services:

php LaravelDoctrine \ ORM \ DoctrineServiceProvider :: class,

L'alias devrait également être configuré:

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

Enfin, nous publions la configuration du paquet avec:

bash vendeur artisan: publish --tag = "config"

Comment tester les référentiels de doctrine

Avant toute chose, vous devriez savoir à propos des appareils. Les fixations sont utilisées pour charger un ensemble contrôlé de données dans une base de données, ce dont nous avons besoin pour les tests. Heureusement, Doctrine 2 dispose d'une bibliothèque pour vous aider à écrire des fixtures pour l'ORDM Doctrine..

Pour installer le groupe de luminaires dans notre application Laravel, nous devons exécuter la commande suivante:

bash composer a besoin de --dev doctrine / doctrine-fixtures-bundle

Créons notre appareil dans tests / Fixtures.php:

"php namespace Test; utilisez Doctrine \ Common \ Persistence \ ObjectManager; utilisez Doctrine \ Common \ DataFixtures \ FixtureInterface; utilisez app \ Entity \ Post;

La classe Fixtures implémente FixtureInterface / ** * Charger les fixtures Post * @param ObjectManager $ manager * @return void * / charge de la fonction publique (ObjectManager $ manager) $ Post = new Post (['title' => 'hello world' , 'body' => 'this is body']); $ manager-> persist ($ Post); $ manager-> flush ();

"

Comme vous le voyez, votre classe de fixture doit implémenter le FixtureInterface et devrait avoir le load (gestionnaire $ ObjectManager) méthode. Les appareils Doctrine2 sont des classes PHP dans lesquelles vous pouvez créer des objets et les conserver dans la base de données. Pour charger automatiquement nos appareils à Laravel, nous devons modifier composer.json dans notre racine de Laravel:

json… "autoload-dev": "classmap": ["tests / TestCase.php", "tests / Fixtures.php" // ajouté ici,…

Puis lancez:

bash composer dump-autoload

Créons notre fichier de test dans le répertoire tests DoctrineTest.php.

"php namespace Test; utilisez App; utilisez App \ Entity \ Post; utilisez Doctrine \ Common \ DataFixtures \ Executor \ ORMExecutor; utilisez Doctrine \ Common \ DataFixtures \ Purger \ ORMPurger; utilisez Doctrine \ Common \ DataFixtures \ Loader; utilisez App \ Repository \ PostRepo;

la classe doctrineTest étend TestCase private $ em; dépôt privé $; chargeur privé $; fonction publique setUp () parent :: setUp (); $ this-> em = App :: make ('Doctrine \ ORM \ EntityManagerInterface'); $ this-> repository = new PostRepo ($ this-> em); $ this-> executor = nouvel ORMExecutor ($ this-> em, nouvel ORMPurger); $ this-> loader = new Loader; $ this-> loader-> addFixture (nouveaux calendriers);

/ ** @test * / public function post () $ purger = new ORMPurger (); $ executor = new ORMExecutor ($ this-> em, $ purger); $ executor-> execute ($ this-> loader-> getFixtures ()); $ user = $ this-> repository-> PostOfTitle ('hello world'); $ this-> em-> clear (); $ this-> assertInstanceOf ('App \ Entity \ Post', $ utilisateur);  "

dans le installer() méthode, j’instancie la ORMExecutor et le chargeur. Nous chargeons aussi le Agencements classe que nous venons de mettre en œuvre.

Ne pas oublier que le / ** @test * / L’annotation est très importante, et sans cela le phpunit retournera un Aucun test trouvé en classe Erreur.

Pour commencer les tests à la racine de notre projet, lancez la commande suivante:

bash sudo phpunit

Le résultat serait:

"bash PHPUnit 4.6.6 de Sebastian Bergmann et des contributeurs.

La configuration a été lue dans /var/www/html/laravel/phpunit.xml. Temps: 17.06 secondes, Mémoire: 16.00M OK (1 test, 1 assertion) "

Si vous souhaitez partager des objets entre des fixtures, il est possible d'ajouter facilement une référence à cet objet par son nom et de le référencer ultérieurement pour former une relation. Voici un exemple:

"php namespace Test; utilisez Doctrine \ Common \ Persistence \ ObjectManager; utilisez Doctrine \ Common \ DataFixtures \ FixtureInterface; utilisez app \ Entity \ Post;

class PostFixtures implémente FixtureInterface / ** * Charger les fixtures utilisateur * * @param ObjectManager $ manager * @return void * / charge de la fonction publique (ObjectManager $ manager) $ postOne = new Post (['title' => 'hello' , 'body' => 'this is body']); $ postTwo = new Post (['title' => 'bonjour', 'body' => 'ceci est le corps deux']); $ manager-> persist ($ postOne); $ manager-> persist ($ postTwo); $ manager-> flush ();

 // stocke la référence au rôle admin pour la relation utilisateur au rôle $ this-> addReference ('new-post', $ postOne);  "

et le commentaire:

"php namespace Test; utilisez Doctrine \ Common \ Persistence \ ObjectManager; utilisez Doctrine \ Common \ DataFixtures \ FixtureInterface; utilisez app \ Entity \ Post;

class CommentFixtures implémente FixtureInterface / ** * Charger les fixtures utilisateur * * @param ObjectManager $ manager * @return void * / fonction publique load (ObjectManager $ manager) $ comment = new Comment (['title' => 'hello' , 'email' => '[email protected]', 'text' => 'nice post']); $ comment-> setPost ($ this-> getReference ('new-post')); // charge la référence stockée $ manager-> persist ($ comment); $ manager-> flush (); // enregistre la référence au nouveau poste pour que la relation de commentaire soit associée à $ this-> addReference ('new-post', $ postOne); "

Avec deux méthodes de getReference () et setReference (), vous pouvez partager des objets entre les fixtures.

Si la commande de luminaires est importante pour vous, vous pouvez facilement les commander avec le obtenir un ordre méthode dans vos appareils comme suit:

php public function getOrder () return 5; // numéro dans lequel charger les fixtures

Remarquez que l'ordre est pertinent pour la classe Loader.

Une des choses importantes à propos des fixtures est leur capacité à résoudre les problèmes de dépendance. La seule chose que vous devez ajouter est une méthode dans votre appareil, comme je l'ai fait ci-dessous:

php public function getDependencies () return array ('Test \ CommentFixtures'); // fixture fixture dépend de

Conclusion

Ceci est juste une description de Test Driven Development avec Laravel 5 et PHPUnit. Lors du test des référentiels, il est inévitable que vous alliez accéder à la base de données. Dans ce cas, les appareils de la doctrine sont importants.