• 6 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 12/05/2022

Interagissez avec votre application lors des tests

Au chapitre précédent, vous avez appris à requêter votre application via un client HTTP. Vous avez la possibilité de récupérer la réponse suite à la requête pour en vérifier le code de statut, par exemple. Vous pouvez en tester les en-têtes également, si cela a lieu d'être.

La prochaine étape est de vérifier que certains éléments sont présents sur la page (par exemple un titre), ou qu'une phrase est présente dans le contenu d'une réponse HTTP.

Inspectez les informations d’une page web avec le crawler

Pour extraire les informations d’une page web, nous pouvons faire appel au “crawler”. Le crawler est un objet auquel vous pouvez accéder après chaque requête, comme suit :

<?php
namespace App\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class DiaryControllerTest extends WebTestCase
{
   // …
   public function testHomepage()
   {
                                     $crawler = $this->client->request(Request::METHOD_GET, $this->urlGenerator->generate('homepage'));
        $this->assertSame(
            1,
               $crawler->filter('html:contains("Bienvenue sur FoodDiary!")')->count()
        );

    }
}

Comme vous le voyez, à chaque requête nous pouvons récupérer un objet crawler. Il s'agit d'une instance de la classe  Symfony\Component\DomCrawler\Crawler  . Après chaque requête, l'objet retourné contient toutes les informations inhérentes au DOM (Document Object Model) de la page.

Pour utiliser les sélecteurs CSS avec le crawler, il faut installer la dépendance suivante :

composer require symfony/css-selector

Dans le code ci-dessus, nous inspectons le contenu de la page (correspondant à la réponse HTTP).

L'instruction  $crawler->filter('html:contains("Bienvenue sur FoodDiary !")')->count()  détermine le nombre d'éléments contenus dans la balise  html  ayant pour texte "Bienvenue sur FoodDiary".

Il ne nous reste plus ensuite qu'à ajouter une assertion pour nous assurer qu'il n'y a qu'un seul élément avec ces caractéristiques.

Une autre manière de procéder aurait été de trouver l'élément h1 dans la page à l'aide du crawler et de la méthode  filter  , comme ceci :

<?php
namespace Tests\AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class DiaryControllerTest extends WebTestCase
{
   // …
   public function testHomepage()
   {

// …
                             $this->assertSame(1, $crawler->filter('h1')->count());

   }
}

Testez un formulaire

Revoyons toutes les étapes de cette vidéo pour vérifier que vous avez bien compris.

En vous baladant dans l'application, vous pouvez remarquer qu'il y a un formulaire pour saisir des entrées dans son journal de bord. Le code pour ce journal de bord est présent dans la classe de contrôleur  App\Controller\DiaryController  .

Il est assez simple de comprendre ce qui se trame dans l'action  addRecordAction  . La route associée est  add-new-record  , et l'URI qu'il faut requêter est la suivante :  /diary/add-new-record  .

Soumettez un formulaire

Pour soumettre un formulaire, il faut dans un premier temps requêter la page affichant le formulaire, puis sélectionner le formulaire qui nous intéresse, renseigner les informations nécessaires à la soumission du formulaire et enfin le soumettre.

Voici comment procéder dans le code de nos tests :

<?php
namespace App\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class DiaryControllerTest extends WebTestCase
{
    // …
    public function testAddRecord()
    {
                                     $crawler = $this->client->request(Request::METHOD_GET, $this->urlGenerator->generate('add-new-record'));
                                        $form = $crawler->selectButton('Ajouter')->form();
        $form['food[entitled]'] = 'Plat de pâtes';
        $form['food[calories]'] = 600;
        $this->client->submit($form);
        echo $this->client->getResponse()->getContent();

    }
}

Affichez le résultat du formulaire

Pour suivre ce qu'il se passe au fur et à mesure que l'on avance dans le code, nous affichons la réponse après la soumission du formulaire.

Lancez la commande suivante :

$ vendor/bin/phpunit --filter=testAddRecord > public/resultTest.html

Sous Windows, utilisez la commande  vendor/bin/phpunit  .

Affichons le résultat dans un navigateur :

La redirection est rapide, on peut la voir passer très brièvement à l'écran.
Affichage de la redirection après la soumission du formulaire

Cela ne nous arrange pas pour effectuer nos assertions dans notre test…

Ce qui se passe est important à comprendre : en effet, si nous ne demandons pas au client HTTP de suivre les redirections, il restera bloqué à la réponse obtenue après requête.

Il faut donc que nous demandions explicitement au client de suivre la redirection, comme ceci :

<?php
namespace App\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class DiaryControllerTest extends WebTestCase
{
    // …
    public function testAddRecord()
    {
                                     $crawler = $this->client->request(Request::METHOD_GET, $this->urlGenerator->generate('add-new-record'));
                                        $form = $crawler->selectButton('Ajouter')->form();
        $form['food[entitled]'] = 'Plat de pâtes';
        $form['food[calories]'] = 600;
        $this->client->submit($form);
        $this->client->followRedirect();
        echo $this->client->getResponse()->getContent();

    }
}

Notez la ligne  $client->followRedirect();  : c'est là que vous demandez au client de suivre la redirection. Relancez la commande précédente.

Réponse suite à la soumission du formulaire et le suivi de la redirection
Réponse suite à la soumission du formulaire et le suivi de la redirection

Désormais, le client suit bien la redirection, ce qui nous permet d'avoir la dernière réponse. Vous allez maintenant pouvoir écrire une assertion pour vérifier que tout s'est bien passé.

Écrivez une assertion

<?php
namespace App\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class DiaryControllerTest extends WebTestCase
{
    // …
    public function testAddRecord()
    {
                                     $crawler = $this->client->request(Request::METHOD_GET, $this->urlGenerator->generate('add-new-record'));
                                        $form = $crawler->selectButton('Ajouter')->form();
        $form['food[entitled]'] = 'Plat de pâtes';
        $form['food[calories]'] = 600;
        $this->client->submit($form);
        $this->client->followRedirect();
          // Attention à bien récupérer le crawler mis à jour
          
$this->assertSelectorTextContains('div.alert.alert-success','Une nouvelle entrée dans votre journal a bien été ajoutée');

    }
}

Il est également possible de faire en sorte que toutes les redirections soient suivies. Pour cela, il faut ajouter l'instruction suivante juste après la création du client :

<?php
$client->followRedirects();

Ainsi, il est inutile d'ajouter l'instruction  $client->followRedirect()  après chaque requête entraînant une redirection.

Exercez-vous en créant un test de plus, en faisant en sorte qu'un ou plusieurs champs soient vides, afin de vérifier les contraintes de validation.

Nous allons installer une autre dépendance afin de ne rien enregistrer en base de données lors de nos tests ; il faudra par la suite modifier un peu notre fichier phpunit.xml.dist.

La commande  composer require --dev dama/doctrine-test-bundle  nous permet de ne pas remplir inutilement notre base de données, en faisant un rollback des données enregistrées juste après le test.

Modifions maintenant notre fichier phpunit.xml.dist pour y insérer à la fin les lignes suivantes :

<extensions>

<extension class="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension"/>

</extensions>

Grâce à ces manipulations, la base de données reste “propre”, et nous pouvons tester à volonté sans risquer de casser d’autres tests qui auraient besoin de certains jeux de données.

Cliquez sur un lien pour naviguer vers une autre page

Écrire un test fonctionnel consiste à décrire un scénario utilisateur. Nous pouvons en créer un complet en partant de la page d'accueil, puis simuler un clic sur le lien "Voir tous les rapports", et enfin nous assurer qu'il y a bien le titre  H1  "Tous les rapports" :

<?php
namespace App\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class DiaryControllerTest extends WebTestCase
{
    // …
    public function testList()
    {
                                     $crawler = $this->client->request(Request::METHOD_GET, $this->urlGenerator->generate('diary'));
            $link = $crawler->selectLink('Voir tous mes rapports')->link();
        $crawler = $this->client->click($link);
        $info = $crawler->filter('h1')->text();
            // On retire les retours à la ligne pour faciliter la vérification
        $info = $string = trim(preg_replace('/\s\s+/', ' ', $info));
        $this->assertSame("Tous les rapports Tout ce qui a été mangé !", $info);

    }
}

À la ligne  $link = $crawler->selectLink('Voir tous les rapports')->link();  , on se charge de récupérer l'objet lien pour pouvoir cliquer dessus ensuite (à la ligne  $crawler = $client->click($link);  ).

En cliquant sur le lien, le navigateur (via le client) est sur la page correspondant à la liste des rapports. Il ne nous reste plus qu'à retrouver l'élément de la page que l'on souhaite tester, et le tour est joué !

Tirez partie du profiler de Symfony

Vous pouvez obtenir bon nombre d'informations, pour corriger vos applications, du profiler de Symfony. Néanmoins, ces informations ne sont visibles que via la “Web Debug Toolbar”, ou encore les pages proposées par le “profiler”.

Alors, comment récupérer ces informations lors de nos tests fonctionnels ?

Depuis l'objet  client  créé, il est possible de récupérer le profiler grâce à la méthode  getProfile()  .

Pour cela, il faut :

  1. Activer le profiler.

  2. Puis effectuer toutes les actions propres à son scénario de test.

  3. Et enfin, y collecter les informations.

En résumé

  • Le crawler est un objet qui nous permet de parcourir toute notre page afin de faire nos tests.

  • Il ne faut pas oublier de l’appeler après chaque redirection, sinon vos données seront faussées.

  • Attention à ne pas trop utiliser le profiler Symfony, pour garder des tests rapides et légers à l’exécution (principe de base des tests).

C’est bientôt la fin de ce cours ! Dans le prochain chapitre, nous vous proposons de découvrir d’autres librairies avec lesquelles vous pouvez tester votre application. Allez, on y va !

Exemple de certificat de réussite
Exemple de certificat de réussite