Introduction
PHPUnit est l'outil de référence pour les tests unitaires en PHP. Dans un contexte professionnel, des tests bien écrits garantissent la stabilité du code lors des refactorisations et des mises à jour. Ce tutoriel intermédiaire vous montre comment aller au-delà des assertions basiques pour créer des suites de tests maintenables, rapides et fiables. Nous aborderons la configuration avancée, l'utilisation intelligente des mocks et les data providers pour éviter la duplication de code.
Prérequis
- PHP 8.2 ou supérieur
- Composer installé
- Connaissances de base en POO et tests unitaires
- Projet PHP existant (Laravel, Symfony ou vanilla)
Installation via Composer
composer require --dev phpunit/phpunit ^11.0
./vendor/bin/phpunit --versionCette commande installe la dernière version stable de PHPUnit en dépendance de développement. Vérifiez toujours la version pour vous assurer de la compatibilité avec vos plugins et extensions.
Configuration du fichier phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
displayDetailsOnTestsThatTriggerWarnings="true">
<testsuites>
<testsuite name="Unit">
<directory>tests/Unit</directory>
</testsuite>
</testsuites>
<source>
<include>
<directory>src</directory>
</include>
</source>
</phpunit>Ce fichier définit les chemins de tests, active les couleurs et inclut uniquement le code source dans la couverture. Il évite d'exécuter les tests d'intégration par erreur.
Premier test unitaire complet
<?php
declare(strict_types=1);
namespace Tests\Unit;
use App\Models\User;
use PHPUnit\Framework\TestCase;
final class UserTest extends TestCase
{
public function testFullNameIsCorrectlyFormatted(): void
{
$user = new User('Jean', 'Dupont');
$this->assertSame('Jean Dupont', $user->getFullName());
}
}Test simple et lisible qui vérifie une méthode métier. Utilisez assertSame plutôt que assertEquals pour les comparaisons strictes de type.
Création d'un mock avancé
<?php
declare(strict_types=1);
namespace Tests\Unit;
use App\Services\PaymentService;
use App\Services\Logger;
use PHPUnit\Framework\TestCase;
final class PaymentServiceTest extends TestCase
{
public function testPaymentIsLoggedOnSuccess(): void
{
$logger = $this->createMock(Logger::class);
$logger->expects($this->once())
->method('info')
->with($this->stringContains('Payment successful'));
$service = new PaymentService($logger);
$service->processPayment(100.0);
}
}Le mock permet d'isoler le service testé. expects($this->once()) garantit que la méthode est appelée exactement une fois, détectant les régressions rapidement.
Data provider pour tests paramétrés
<?php
declare(strict_types=1);
namespace Tests\Unit;
use App\Services\PriceCalculator;
use PHPUnit\Framework\TestCase;
final class PriceCalculatorTest extends TestCase
{
/**
* @dataProvider priceProvider
*/
public function testCalculatePrice(float $base, float $tax, float $expected): void
{
$calculator = new PriceCalculator();
$this->assertSame($expected, $calculator->calculate($base, $tax));
}
public static function priceProvider(): array
{
return [
[100.0, 0.20, 120.0],
[50.0, 0.10, 55.0],
[0.0, 0.20, 0.0],
];
}
}Les data providers évitent la duplication de code et permettent de tester facilement de nombreux cas limites avec une seule méthode de test.
Bonnes pratiques
- Nommez vos tests selon le comportement attendu (testXXXWhenYYYThenZZZ)
- Gardez chaque test indépendant et sans effet de bord
- Utilisez des fixtures ou des factories pour les données de test
- Exécutez les tests en parallèle dès que possible avec --parallel
- Mesurez la couverture mais ne la transformez pas en objectif
Erreurs courantes à éviter
- Tester des implémentations plutôt que des comportements
- Oublier de vider les mocks entre les tests
- Utiliser des assertEquals sur des objets sans __toString
- Ignorer les tests qui échouent aléatoirement (flaky tests)
Pour aller plus loin
Découvrez nos formations avancées sur les tests PHP et l'architecture logicielle : https://learni-group.com/formations