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.
Commencez par récupérer l'application Symfony via ce repo.
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
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 :
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 nonSymfony\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.