PHPUnit: Les tests unitaires avec PHPUnit
Introduction
Attendez… quelqu'un a ENCORE construit un parc de dinosaures sans AUCUN test !?!? J'ai déjà vu ce film, et c'est à nous de jouer : ajouter une suite complète de tests avant que les dinos ne viennent pour nous…
Plus sérieusement : les tests sont géniaux. Ce n'est pas seulement un outil pour éviter les bugs, c'est aussi une philosophie de développement qui peut vous aider à écrire du code plus ciblé, centré sur ce que vous voulez réellement construire.
Dans ce tutoriel, vous allez atteindre le niveau super-héros des tests unitaires, avec notamment :
- Les bases des tests unitaires
- Le développement dirigé par les tests (TDD) : comment le faire, et quand le faire !
- L'utilisation de Fixtures pour exécuter plusieurs fois les tests avec différentes entrées
- Les mocks et doubles de test ! Créer des mocks avec PHPUnit
- L'exécutable PHPUnit et sa configuration
- Tester les exceptions
Initiation à PHPUnit
Installation via Composer (recommandé)
PHPUnit s'installe le plus souvent via Composer comme dépendance de développement :
composer require --dev phpunit/phpunit
Cela permet à PHPUnit d'être intégré à votre projet, versionné, et exécuté depuis le répertoire vendor.
Vérification de l'installation
Une fois installé, vous pouvez vérifier que tout fonctionne :
./vendor/bin/phpunit --version
Si tout est prêt, vous verrez s'afficher une version de type PHPUnit x.y.z.
💡 Pour simplifier, vous pouvez créer un alias dans votre fichier composer.json :
"scripts": {
"test": "vendor/bin/phpunit"
}
Et exécuter vos tests simplement avec :
composer test
Structure de base d'un test PHPUnit
Un test unitaire est une classe qui hérite de PHPUnit\Framework\TestCase. Chaque méthode publique qui commence par test sera considérée comme un test par PHPUnit.
Exemple minimal
Créeons un fichier Calculator.php :
<?php
namespace App;
class Calculator
{
public function add(int $a, int $b): int
{
return $a + $b;
}
}
Créons ensuite un fichier de test tests/CalculatorTest.php :
<?php
use PHPUnit\Framework\TestCase;
use App\Calculator;
class CalculatorTest extends TestCase
{
public function testAddReturnsTheCorrectSum(): void
{
$calculator = new Calculator();
$this->assertEquals(4, $calculator->add(2, 2));
}
}
Pour exécuter le test :
./vendor/bin/phpunit tests/CalculatorTest.php
Résultat attendu
OK (1 test, 1 assertion)
Si le test échoue, vous verrez un message explicite indiquant l'échec.
Les assertions les plus courantes
PHPUnit propose une grande variété d'assertions :
assertEquals($expected, $actual): Vérifie que les deux valeurs sont égales.assertNotEquals($expected, $actual): Vérifie que les deux valeurs ne sont pas égales.assertTrue($condition): Vérifie que la condition est vraie.assertFalse($condition): Vérifie que la condition est fausse.assertNull($actual): Vérifie que la valeur est nulle.assertCount($expectedCount, $haystack): Vérifie que le nombre d'éléments dans$haystackest égal à$expectedCount.assertInstanceOf($expectedClass, $actual): Vérifie que$actualest une instance de$expectedClass.assertContains($needle, $haystack): Vérifie que$needleest présent dans$haystack.
Organisation des tests dans Symfony
Dans un projet Symfony, les tests sont généralement situés dans le dossier tests/. Par convention :
- Les tests fonctionnels sont dans
tests/Functional/ - Les tests unitaires sont dans
tests/Unit/ - Les tests d'intégration sont dans
tests/Integration/
Symfony fournit un environnement de test isolé par défaut (APP_ENV=test) et des outils comme le KernelTestCase pour tester avec le container de service.