Premiers pas avec Nette Tester
Même les bons programmeurs font des erreurs. La différence entre un bon et un mauvais programmeur, c'est que le bon ne fait une erreur qu'une seule fois et que, la fois suivante, il la détecte à l'aide de tests automatisés.
- “Qui ne teste pas est condamné à répéter ses erreurs.” (proverbe)
- “Dès qu'on se débarrasse d'une erreur, une autre apparaît.” (loi de Murphy)
- “Chaque fois que vous êtes tenté d'écrire un print, écrivez plutôt un test.” (Martin Fowler)
Avez-vous déjà écrit en PHP du code comme celui-ci ?
$obj = new MyClass;
$result = $obj->process($input);
var_dump($result);
Autrement dit, avez-vous affiché le résultat d'un appel de fonction juste pour vérifier des yeux qu'il renvoie bien ce qu'il devrait ? Vous le faites sans doute plusieurs fois par jour. La main sur le cœur : si tout fonctionne correctement, supprimez-vous ce code ? Vous attendez-vous à ce que la classe ne casse pas à l'avenir ? Les lois de Murphy garantissent le contraire :-)
Au fond, vous avez écrit un test. Il lui manque juste une petite modification pour qu'il n'exige plus d'inspection visuelle, mais se contrôle lui-même. Et si vous ne supprimez pas le test, vous pourrez le lancer à tout moment à l'avenir pour vérifier que tout fonctionne toujours comme il faut. Avec le temps, vous créerez un grand nombre de tels tests, et il serait donc utile de les exécuter automatiquement.
Et Nette Tester va vous aider dans tout cela.
Qu'est-ce qui rend Tester unique ?
Écrire des tests pour Nette Tester a ceci d'unique que chaque test est un script PHP standard qui peut être exécuté seul.
Ainsi, quand vous écrivez un test, vous pouvez simplement le lancer et découvrir s'il contient par exemple une erreur de programmation. S'il fonctionne correctement. Sinon, vous pouvez facilement l'exécuter pas à pas dans votre IDE et chercher le bug. Vous pouvez même l'ouvrir dans un navigateur.
Et surtout : en le lançant, vous exécutez le test. Vous apprenez immédiatement s'il passe ou échoue. Comment ? Montrons-le.
Nous allons écrire un test trivial sur l'utilisation d'un tableau PHP et l'enregistrer dans le fichier
ArrayTest.php :
<?php
use Tester\Assert;
require __DIR__ . '/vendor/autoload.php'; # charge l'autoloader de Composer
Tester\Environment::setup(); # initialise Nette Tester
$stack = [];
Assert::same(0, count($stack)); # nous attendons que count() renvoie zéro
$stack[] = 'foo';
Assert::same(1, count($stack)); # nous attendons que count() renvoie un
Assert::contains('foo', $stack); # vérifie que $stack contient l'élément 'foo'
Comme vous le voyez, ce sont des méthodes d'assertion comme
Assert::same() qui servent à confirmer que la valeur réelle correspond à la valeur attendue.
Le test est écrit et nous pouvons le lancer depuis la ligne de commande. Le premier lancement révélera d'éventuelles erreurs de syntaxe et, si vous n'avez fait aucune faute de frappe, il affichera :
$ php ArrayTest.php
OK
Essayez de remplacer l'assertion du test par une assertion fausse, comme Assert::contains('XXX', $stack);, et
regardez ce qui se passe à l'exécution :
$ php ArrayTest.php Failed: ['foo'] should contain 'XXX' in ArrayTest.php(17) Assert::contains('XXX', $stack); FAILURE
Nous poursuivons sur l'écriture des tests dans le chapitre Écrire des tests.
Installation et prérequis
La version minimale de PHP exigée par Tester est 8.0 (plus de détails dans le tableau Versions de PHP prises en charge). La méthode d'installation recommandée passe par Composer :
composer require --dev nette/tester
Essayez de lancer Nette Tester depuis la ligne de commande (sans arguments, il n'affichera que l'aide) :
vendor/bin/tester
Exécuter les tests
À mesure que l'application grandit, le nombre de tests grandit avec elle. Il ne serait pas pratique de les lancer un par un. C'est pourquoi Tester dispose d'un lanceur de tests en masse, que nous appelons depuis la ligne de commande. En paramètre, nous indiquons le répertoire où se trouvent les tests. Un point signifie le répertoire courant.
vendor/bin/tester .
Le lanceur de tests parcourt le répertoire indiqué et tous ses sous-répertoires et y cherche les tests, c'est-à-dire les
fichiers *.phpt et *Test.php. Il trouvera donc aussi notre test ArrayTest.php, puisqu'il
correspond au masque.
Il commence ensuite les tests. Chaque test est lancé comme un nouveau processus PHP, il s'exécute donc totalement isolé des autres. Il les lance en parallèle dans plusieurs threads, ce qui le rend extrêmement rapide. Et il lance d'abord les tests qui ont échoué lors de l'exécution précédente, ce qui vous permet de savoir tout de suite si vous avez réussi à corriger le bug.
Pendant l'exécution des tests, Tester affiche en continu les résultats dans le terminal sous forme de caractères :
.– test réussis– test ignoréF– test échoué
La sortie peut ressembler à ceci :
_____ ___ ___ _____ ___ ___ |_ _/ __)( __/_ _/ __)| _ ) |_| \___ /___) |_| \___ |_|_\ v2.6.0 PHP 8.5.2 (cli) | php | 8 threads ........s................F......... -- FAILED: greeting.phpt Failed: 'Hello John' should be ... 'Hello Peter' in greeting.phpt(19) Assert::same('Hello Peter', $o->say('John')); FAILURES! (35 tests, 1 failures, 1 skipped, 1.7 seconds)
35 tests ont été exécutés, un a échoué, un a été ignoré.
Nous poursuivons dans le chapitre Exécuter les tests.
Mode watch
Vous refactorisez du code ? Ou vous développez peut-être même selon la méthodologie TDD (Test Driven Development) ? Alors le mode watch vous plaira. Dans ce mode, Tester surveille les codes sources et se relance automatiquement à chaque modification.
Pendant le développement, vous avez dans un coin de votre écran un terminal où brille une barre d'état verte et, quand elle vire soudain au rouge, vous savez que vous venez de faire quelque chose qui ne va pas. C'est en fait un excellent jeu où vous programmez en essayant de garder la couleur.
Le mode watch se lance avec le paramètre --watch.
Rapports de couverture de code
Tester sait générer des rapports donnant un aperçu de la part du code source couverte par les tests. Le rapport peut être soit au format HTML lisible par un humain, soit en Clover XML pour un traitement automatisé ultérieur.
Voir un exemple de rapport HTML de couverture de code.
Versions de PHP prises en charge
| Version | Compatible avec PHP |
|---|---|
| Tester 2.6 | PHP 8.0 – 8.5 |
| Tester 2.5 | PHP 8.0 – 8.5 |
| Tester 2.4 | PHP 7.2 – 8.2 |
| Tester 2.3 | PHP 7.1 – 8.0 |
| Tester 2.1 – 2.2 | PHP 7.1 – 7.3 |
| Tester 2.0 | PHP 5.6 – 7.3 |
| Tester 1.7 | PHP 5.3 – 7.3 + HHVM 3.3+ |
| Tester 1.6 | PHP 5.3 – 7.0 + HHVM |
| Tester 1.3 – 1.5 | PHP 5.3 – 5.6 + HHVM |
| Tester 0.9 – 1.2 | PHP 5.3 – 5.6 |
Vaut pour la dernière version corrective.
Tester prenait aussi en charge, jusqu'à la version 1.7, HHVM 3.3.0 ou plus récent (via
tester -p hhvm). La prise en charge a été abandonnée à partir de la version 2.0 de Tester.