Christophe Meneses - Développeur
  • Liste des articles
  • Contact
  • Linkedin
  • Github
  • Flux RSS
Tous les articles Symfony / PHPUnit / Panther Migrer ses tests fonctionnels vers Symfony Panther
Symfony PHPUnit Panther

Migrer ses tests fonctionnels vers Symfony Panther

Publié le 13/04/2019.

Cet article est un retour d'expérience sur la migration de tests fonctionnels Symfony classiques (utilisant les composants BrowserKit et DomCrawler) vers le nouveau composant Symfony Panther.

Les avantages de Panther

Les tests fonctionnels classiques sont une simulation de requêtes et de réponses en instanciant des objets PHP (Request et Response). S'il y a des soucis de chargement des ressources web, du JavaScript qui ne fonctionne pas par exemple, ces tests ne les repéreront pas.

Panther quant à lui, utilise un client PHP qui implémente le protocole WebDriver. Les tests vont se réaliser sur un vrai navigateur. On peut donc tester réellement ce qui se passe, et notamment le JavaScript. Actuellement, seul un driver Chrome est disponible.

Installation sur Docker

Il faut ajouter les lignes ci-dessous dans le Dockerfile de l'image contenant PHP :

# Installation pour Symfony Panther
RUN apt-get install -y libzip-dev zlib1g-dev chromium
# To disable Chrome's sandboxing (unsafe, but allows to use Panther in containers)
ENV PANTHER_NO_SANDBOX 1 

Il faut également l'extension PHP zip. Si elle n'est pas déjà présente dans l'image, il faut la rajouter :

RUN apt-get install -y php7.3-zip

Il faut ensuite reconstruire l'image PHP.

Modification des tests fonctionnels existants

Il faut modifier toutes les classes parentes des classes de tests qui utilise WebTestCase, en mettant à la place PantherTestCase.

Par exemple, la classe :

namespace Tests\App\Controller\Front;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

/**
 * Class ArticleControllerTest.
 */
class ArticleControllerTest extends WebTestCase
{
    [...]
}

Devient :

namespace Tests\App\Controller\Front;

use Symfony\Component\Panther\PantherTestCase;

/**
 * Class ArticleControllerTest.
 */
class ArticleControllerTest extends PantherTestCase
{
    [...]
}

2ème étape, il faut modifier la méthode utilisée pour créer un client. Il faut le faire pour toutes les classes de tests qui créent un client.

Avant :

$client = static::createClient();

Après :

$client = static::createPantherClient(); 

Et c'est tout pour l'instant ! Il suffit alors de relancer les tests :

./bin/phpunit

En fonction de comment ont été écrits les anciens tests, il y aura plus ou moins des erreurs.

Correction des anciens tests

Si la récupération des services avec l'ancien client se faisait grâce à la méthode getContainer() :

$client->getContainer()->get('doctrine.orm.entity_manager');

Cette façon de faire ne fonctionne plus, le message d'erreur ci-dessous va apparaitre :

Error: Call to undefined method Symfony\Component\Panther\Client::getContainer()

Il faut maintenant accéder directement au conteneur :

self::$container->get('doctrine.orm.entity_manager');

Si les anciens tests utilisaient l'objet Response du composant HttpFoundation, l'erreur ci-dessous va apparaitre :

LogicException: HttpFoundation Response object is not available when using WebDriver.

Il ne faut plus accéder à l'objet Response dans les tests. Par exemple, le code ci-dessous n'est plus possible :

$client->getResponse()->isSuccessful();

C'est également le cas avec l'objet Request.

Panther utilise un client PHP qui implémente le protocole WebDriver. Ce protocole ne permet pas de récupérer le code de retour d'une requête HTTP. Donc à la place de vérifier un code de retour, il faut regarder par exemple qu'un élément de la page attendue soit bien affiché.

En conséquence, la méthode pour connaitre l'URL courante à changer. Avant :

$client->getRequest()->getUri();

Après :

$client->getCurrentURL();

Une fois les corrections effectuées, il faut relancer l'ensemble des tests jusqu'à obtenir 100% de succès.

Bonus

Avec Panther, on peut prendre une capture d'écran de manière très simple :

$client->takeScreenshot('mon_screenshot.png');

L'image est sauvegardée à la racine du projet. Elle permet de trouver plus facilement pourquoi un test est en erreur.

Version

Cet article a été testé avec :

Symfony : 4.2
PHP : 7.3
PHPUnit : 6.5
Début de l'article

Tous les articles Symfony / PHPUnit / Panther Migrer ses tests fonctionnels vers Symfony Panther

Liste des articles par catégorie

  1. Tous 124
  2. Apache2
  3. APC1
  4. Assetic2
  5. Bash2
  6. CentOS9
  7. Composer6
  8. CSS1
  9. Debian1
  10. Deployer1
  11. Design Pattern11
  12. Docker6
  13. Doctrine14
  14. Elasticsearch3
  15. Git6
  16. Google Charts1
  17. Hardware1
  18. Hébergement1
  19. JavaScript1
  20. jQuery4
  21. Kibana2
  22. Logstash1
  23. Machine Learning1
  24. MariaDB2
  25. Memcached2
  26. MySQL3
  27. Nginx2
  28. Panther3
  29. PHP59
  30. PHP_CodeSniffer1
  31. PHP-FPM2
  32. PhpMyAdmin1
  33. PhpStorm3
  34. PHPUnit6
  35. PostgreSQL2
  36. RabbitMQ2
  37. SQL1
  38. SVN4
  39. Sybase ASE1
  40. Symfony56
  41. Twig3
  42. Ubuntu14
  43. Vue.js2
  44. Vuex1
  45. Webpack Encore1
  46. Xdebug5

Derniers articles publiés

PHP
Différence entre les mots clés self et static dans le langage PHP

Symfony / Docker / Nginx
Migrer un projet Symfony du protocole HTTP 1.1 au protocole HTTP 2

Vue.js
Utiliser un filtre Vue.js directement dans le JavaScript

PHP / Symfony
Supprimer les messages de dépréciation de type : The "sensio_framework_extra.routing.loader.annot_*" service is deprecated since version 5.2

Symfony / RabbitMQ
Exemple d'utilisation du composant Messenger pour envoyer des emails en asynchrone avec RabbitMQ

PHP Symfony MariaDB HTML5 CSS3 JavaScript Bootstrap

© 2014 - 2019 réalisé par Christophe MENESES