• 6 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 5/12/22

Implémentez vos premiers tests fonctionnels

Vous allez vous lancer en installant une nouvelle  application Symfony.

Vous allez jouer le rôle d'un développeur qui découvre une nouvelle application. Votre mission : implémenter des tests fonctionnels pour documenter l'ensemble de l'application.

Vous ne connaissez pas encore les fonctionnalités, ni à quoi ressemblent les pages du site. Ce n'est pas grave pour l'instant.

Dans un premier temps, vous allez simplement vous assurer que lorsque vous requêtez une page, celle-ci renvoie une réponse avec le code status  200  .

Installez l'application

L'application Symfony est très simple à installer.

  1. Commencez par récupérer l'application Symfony via ce repo.

  2. Puis lisez le fichier readme.md situé à la racine de votre projet.

Connectons-nous une première fois afin de créer notre user pour la suite des tests. Lançons le serveur Symfony local dans la console avec la commande :

 symfony server:start 

Puis, dans le navigateur, allons à l’adresse :

http://127.0.0.1:8000/login 

L’adresse  http://127.0.0.1:8000/  est indiquée dans la console après avoir tapé la commande.

En cliquant sur le bouton Se connecter avec GitHub, nous tombons sur un écran de  GitHub qui indique les informations que nous souhaitons récupérer depuis ce service. En acceptant, GitHub nous redirige vers notre site : nous serons connectés et  enfin prêts à travailler !

Créez votre premier test fonctionnel

Lorsque l'on écrit un test fonctionnel, il s'agit de requêter une URL et de récupérer la réponse. Le point d'entrée de l'application est donc le contrôleur correspondant à l'URL demandée. Ainsi, nos classes de tests devront refléter l'arborescence des classes de contrôleurs liées aux URL testées.

Que va-t-on tester, exactement ?

Ah ! En voilà une excellente question !

Pour commencer, il nous faut établir la liste des URL de l'application afin de connaître la somme de travail que nous avons devant nous.

Maintenant, placez-vous à la racine du projet fraîchement installé, puis tapez la commande suivante dans votre outil de lignes de commande pour lister toutes les routes de l'application :

$ bin/console debug:router
Liste des routes de l'application
Liste des routes de l'application

Nous n'allons pas tester toutes les routes de l'application. Nous allons nous concentrer uniquement sur les routes autres que celles provenant du framework Symfony (toutes celles qui ne commencent pas par  _  ).

Allons-y ! Assurons-nous dans nos tests que l'URI  /  retourne bien le code status  200  .

Créez une classe de test

Pour voir la classe de test correspondant au nom de route “homepage”, tapez la commande suivante :

$ bin/console debug:router homepage

Symfony nous indique que le contrôleur associé est  App\Controller\DiaryController::indexAction()  , soit la méthode  indexAction  contenue dans la classe  App\Controller\DiaryController  .

Nous devons donc créer la classe de test ayant le nom suivant :   DiaryControllerTest  . Le fichier doit être créé sous l'arborescence tests/Controller dans le projet Symfony.

<?php
namespace App\Tests\Controller;
class DiaryControllerTest
{
}

Requêtez une URL et affichez la réponse

La prochaine étape est d'effectuer une requête. Pour cela, vous aurez besoin de créer un client HTTP qui tiendra le rôle du navigateur.

Pour vous aider dans l'écriture de vos tests, et avoir des méthodes raccourcies pour simuler le déroulement d'un test par un humain et un navigateur, vous pouvez étendre une classe déjà existante : il s'agit de  Symfony\Bundle\FrameworkBundle\Test\WebTestCase  .

Voyons dès maintenant comment en tirer partie :

<?php
namespace App\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class DiaryControllerTest extends WebTestCase
{
    public function testHomepageIsUp()
    {
        $client = static::createClient();
    }
}
<?php
// ...
use Symfony\Component\HTTPFoundation\Response;
class DiaryControllerTest extends WebTestCase
{
    private KernelBrowser|null $client = null;

   public function setUp() : void

 {
   $this->client = static::createClient();
 }
 public function testHomepageIsUp()
 {

    $urlGenerator = $this->client->getContainer()->get('router.default');

    $this->client->request(Request::METHOD_GET, $urlGenerator->generate('homepage'));

 }
}

Maintenant, lancez la commande suivante :

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

Sous Windows, vous utilisez la même commande,  vendor/bin/phpunit  .

Cette commande permet de rediriger la sortie avec le fichier placé dans le dossier web et appelé  resultTest.html  .

Et enfin, affichez la page : http://127.0.0.1:8000/resultTest.html :

Contenu de la réponse HTTP suite à la requête
Contenu de la réponse HTTP suite à la requête

C’est pratique pour suivre ce qu'il se passe au fur et à mesure du développement de vos tests fonctionnels ! Ici, il n’y a pas d’assertion, c’est pourquoi nous voyons “There was 1 risky test”. Nous verrons un peu plus tard ce que cela signifie.

Écrivez votre première assertion

N'oublions pas que nous sommes dans le cadre d'un test ! Il nous faut donc ajouter une assertion.

Il faut savoir que la classe  Symfony\Bundle\FrameworkBundle\Test\WebTestCase  étend la classe PHPUnit  PHPUnit_Framework_Test  , nous permettant d'utiliser les méthodes pour écrire des assertions.

Nous avons besoin de nous connecter en tant que user afin de pouvoir tester nos routes ; pour cela nous récupérerons également l’entityManager pour récupérer notre user en base de données.

$userRepository = $this->client->getContainer()->get('doctrine.orm.entity_manager')->getRepository(User::class);
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class DiaryControllerTest extends WebTestCase
{
   public function testHomepageIsUp()
   {
        $userRepository = $this->client->getContainer()->get('doctrine.orm.entity_manager')->getRepository(User::class);
        $testUser = $userRepository->findOneByEmail('<utiliser le mail de github comme expliqué dans le readme>'
);
        $urlGenerator = $this->client->getContainer()->get('router.default');
        //Authentification sur Symfony pour le test avec le user récupéré en base
        $this->client->loginUser($testUser);
          
        $this->client->request(Request::METHOD_GET, $urlGenerator->generate('homepage'));
        $this->assertResponseStatusCodeSame(Response::HTTP_OK);
   }
}

Nous vérifions que le code status de la réponse HTTP est bien  200(Response::HTTP_OK)  .

Maintenant, vous pouvez faire de même pour toutes les pages de l'application. De cette manière, on s'assure au minimum que toutes les pages renvoient bien le bon code status.

Avec un peu de refactorisation, ça donne ça :

<?php
   public function setUp() : void

     {
        $this->client = static::createClient();

        $this->userRepository = $this->client->getContainer()->get('doctrine.orm.entity_manager')->getRepository(User::class);

        // Mettre comme argument de la méthode FindOneByEmail

        // l'e-mail utilisé sur GitHub, ou regarder en base de données quel est l'e-mail renseigné.

        $this->user = $this->userRepository->findOneByEmail('email renseigné sur github');

        $this->urlGenerator = $this->client->getContainer()->get('router.default');

        $this->client->loginUser($this->user);
   }

    public function testHomepageIsUp()

   {
        $this->client->request(Request::METHOD_GET, $this->urlGenerator->generate('homepage'));

        $this->assertResponseStatusCodeSame(Response::HTTP_OK);
   }

Vous avez suivi ? Allez, voyons cela en vidéo !

Créez le client HTTP

Client

Comme nous venons de le voir, il nous faut un client pour effectuer des requêtes HTTP. Cet objet créé grâce à la méthode statique  createClient()  est une instance de la classe  Symfony\Bundle\FrameworkBundle\KernelBrowser  .

Lisez le code de la classe pour découvrir tout ce qu’il est possible de faire avec cet objet.

Requête et réponse

Nous avons été en mesure de récupérer le code status de la réponse assez simplement, parce que la réponse est accessible via le client HTTP.

Nous vous invitons vivement à lire cette classe pour en savoir plus sur ce qu'il est possible de faire !

En résumé

  • Nous avons besoin d’un client HTTP pour effectuer notre requête. Attention, il s’agit de   Symfony\Component\BrowserKit\Request  et non  Symfony\Component\HttpFoundation\Request  .

  • L’objet obtenu en réponse à la requête est du type  Symfony\Component\BrowserKit\Response  .

Rendez-vous au prochain chapitre pour apprendre à manipuler le crawler, afin de vérifier que certains éléments sont bien dans la réponse HTTP.

Example of certificate of achievement
Example of certificate of achievement