Écrire des assertions PHPUnit plus simples grâce au VarDumper
Les tests unitaires sont une étape cruciale pour garantir la qualité de votre
code, mais parfois, les répétitions peuvent devenir lassantes. Avez-vous déjà soupiré en enchaînant des appels à $this->assertXXX()
pour valider des structures complexes ? Heureusement, il existe une solution élégante pour simplifier tout cela : le composant Symfony/VarDumper.
Voyons ensemble comment l’utiliser pour rendre vos tests plus concis et lisibles tout en conservant leur efficacité.
Section intitulée un-exemple-concretUn exemple concret
Imaginons que nous souhaitions tester certaines propriétés d’une classe comme celle-ci :
final readonly class MyObject
{
public function __construct(
public string $aPublicProperty = 'a public property',
protected string $aProtectedProperty = 'a protected property',
private string $aPrivateProperty = 'a private property',
public string $anotherPublicProperty = 'another public property',
protected string $anotherProtectedProperty = 'another protected property',
private string $anotherPrivateProperty = 'another private property',
) {}
}
Lorsque vous dumpez un objet instancié avec ses valeurs par défaut, voici le résultat obtenu :
PhpunitVarDumper\MyObject^ {#325
+aPublicProperty: "a public property"
#aProtectedProperty: "a protected property"
-aPrivateProperty: "a private property"
+anotherPublicProperty: "another public property"
#anotherProtectedProperty: "another protected property"
-anotherPrivateProperty: "another private property"
}
Section intitulée simplifier-les-testsSimplifier les tests
Traditionnellement, on utiliserait plusieurs appels à $this->assertSame()
pour valider ces propriétés. Cependant, grâce à Symfony/VarDumper, nous pouvons alléger ce processus en utilisant une assertion sur le dump directement.
Commencez par installer le composant en mode développement :
composer require --dev symfony/var-dumper
Ensuite, importez le trait VarDumperTestTrait
et utilisez la méthode assertDumpEquals()
dans vos tests :
use PHPUnit\Framework\TestCase;
use PhpunitVarDumper\MyObject;
use Symfony\Component\VarDumper\Test\VarDumperTestTrait;
final class MyObjectTest extends TestCase
{
use VarDumperTestTrait;
public function test()
{
$myObject = new MyObject();
$this->assertDumpEquals(
<<<'DUMP'
PhpunitVarDumper\MyObject {
+aPublicProperty: "a public property"
#aProtectedProperty: "a protected property"
-aPrivateProperty: "a private property"
+anotherPublicProperty: "another public property"
#anotherProtectedProperty: "another protected property"
-anotherPrivateProperty: "another private property"
}
DUMP,
$myObject,
);
}
}
N’est-ce pas plus clair et élégant ? 🎉
Section intitulée aller-plus-loin-avec-les-castersAller plus loin avec les Casters
Dans certains cas, toutes les propriétés d’un objet ne sont pas pertinentes pour vos tests, ou vous ne souhaitez pas les mettre à jour à chaque modification de la classe. C’est ici que les casters entrent en jeu.
Un caster est une fonction de rappel qui personnalise la représentation d’un objet dumpé. Elle prend en paramètre :
- L’objet en cours de dump ;
- Un tableau représentant l’état de l’objet ;
- (d’autres paramètres que nous n’utilisons pas ici).
Pour ajouter un caster, utilisez la méthode setUpVarDumper()
dans votre test :
final class MyObjectTest extends TestCase
{
use VarDumperTestTrait;
protected function setUp(): void
{
$this->setUpVarDumper(
[
MyObject::class => static function (MyObject $myObject, array $a): array {
return $a;
},
],
);
}
}
Pour le moment, notre caster ne sert à rien. Observons donc ce que contient la variable $a
:
^ array:6 [
"aPublicProperty" => "a public property"
"\x00*\x00aProtectedProperty" => "a protected property"
"\x00PhpunitVarDumper\MyObject\x00aPrivateProperty" => "a private property"
"anotherPublicProperty" => "another public property"
"\x00*\x00anotherProtectedProperty" => "another protected property"
"\x00PhpunitVarDumper\MyObject\x00anotherPrivateProperty" => "another private property"
]
Si vous avez déjà joué avec PHP et ses mécanismes de sérialisation, vous ne devriez pas être perdu. Sinon une petite explication s’impose :
- Chaque clé représente une propriété de l’objet.
- Les notations varient en fonction de la visibilité de la propriété :
- Pour une propriété publique, son nom apparaît directement en clair, comme
"aPublicProperty"
. - Pour une propriété protégée, son nom est précédé par le préfixe spécial
\x00*\x00
, qui signale sa visibilité restreinte. - Pour une propriété privée, le préfixe indique son contexte de déclaration :
\x00[NomDeLaClasse]\x00
. Ici, cela donne par exemple\x00PhpunitVarDumper\MyObject\x00aPrivateProperty
.
- Pour une propriété publique, son nom apparaît directement en clair, comme
Ces notations un peu cryptiques peuvent sembler complexes à première vue. Heureusement, Symfony fournit des constantes pour les manipuler plus facilement, comme Caster::PREFIX_PROTECTED
ou Caster::PATTERN_PRIVATE
. Utilisons-les pour simplifier notre code de caster :
use Symfony\Component\VarDumper\Caster\Caster;
protected function setUp(): void
{
$this->setUpVarDumper(
[
MyObject::class => static function (MyObject $myObject, array $a) {
unset(
$a['anotherPublicProperty'],
$a[Caster::PREFIX_PROTECTED.'anotherProtectedProperty'],
$a[sprintf(Caster::PATTERN_PRIVATE, MyObject::class, 'anotherPrivateProperty')],
);
return $a;
},
],
AbstractDumper::DUMP_LIGHT_ARRAY,
);
}
Ce caster permet de supprimer les propriétés non pertinentes. Le test devient alors :
public function test()
{
$myObject = new MyObject();
$this->assertDumpEquals(
<<<'DUMP'
PhpunitVarDumper\MyObject {
+aPublicProperty: "a public property"
#aProtectedProperty: "a protected property"
-aPrivateProperty: "a private property"
}
DUMP,
$myObject,
);
}
En cas d’erreur, PHPUnit affiche un diff très lisible, ce qui facilite le debug :
1) PhpunitVarDumper\Tests\MyObjectTest::test
Failed asserting that two strings are identical.
--- Expected
+++ Actual
@@ @@
'PhpunitVarDumper\MyObject {
- +aPublicProperty: "Hello you!"
+ +aPublicProperty: "a public property"
#aProtectedProperty: "a protected property"
-aPrivateProperty: "a private property"
}'
Section intitulée quelques-astuces-supplementairesQuelques astuces supplémentaires
- Affichage léger des tableaux Utilisez
AbstractDumper::DUMP_LIGHT_ARRAY
comme deuxième paramètre desetUpVarDumper()
pour des tableaux plus compacts.-array:3 [ - 0 => "a" - 1 => "b" - 2 => "c" +[ + "a" + "b" + "c" ]
- Gestion des valeurs dynamiques Préférez un caster à
assertDumpMatchesFormat()
, car les diff générés avec des formats sont souvent difficiles à lire.
Section intitulée conclusionConclusion
Le composant VarDumper est un allié précieux, tant pour le débogage que pour simplifier vos tests. Grâce à lui, vous gagnez en clarté et en efficacité.
Alors, dites adieu aux assertions fastidieuses, et concentrez-vous sur ce qui compte vraiment : la qualité de votre code. 🎉
Commentaires et discussions
Nos formations sur ce sujet
Notre expertise est aussi disponible sous forme de formations professionnelles !

Symfony avancée
Découvrez les fonctionnalités et concepts avancés de Symfony
Ces clients ont profité de notre expertise
Cacharel, marque emblématique du prêt-à-porter féminin et du parfum, s’associe à JoliCode pour accélérer son virage digital et renouer avec les jeunes femmes après trois ans d’absence. Avec une nouvelle direction artistique, l’objectif est de proposer une collection moderne tout en restant fidèle à l’héritage de la marque. Pour accompagner cette renaissance, …
L’équipe d’Alain Afflelou a choisi JoliCode comme référent technique pour le développement de son nouveau site internet. Ce site web-to-store incarne l’image premium de l’enseigne, met en valeur les collections et offre aux clients de nouvelles expériences et fonctionnalités telles que l’e-réservation, le store locator, le click & collect et l’essayage…
Nous avons réalisé différentes applications métier à l’aide de technologies comme Symfony2 et Titanium. Arianespace s’est appuyé sur l’expertise reconnue de JoliCode pour mettre en place des applications sur mesure, testées et réalisées avec un haut niveau de qualité.