Pour cela, il faut qu'un grand nombre de tests soient écrits par la communauté.

Si vous désirez participer, et ainsi contribuer à l'amélioration du langage et voir votre code distribué avec le code source de PHP, la procédure à suivre n'est pas compliquée.

Tout d'abord, il faut disposer d'un environnement de test, qui contient les dernières versions de PHP 5.2, PHP 5.3 et du trunk.

La méthode la plus simple pour créer cet environnement est d'utiliser les scripts d'Éric Stewart qui vous permettrons de l'installer automatiquement sous Mac OS X Snow Leopard, Ubuntu, et bientôt FreeBSD puisque j'ai développé le script correspondant et qu'Éric va l'intégrer dans sa distribution, si ce n'est pas déjà fait.

En utilisant ces scripts, vous disposerez, une fois le processus d'installation terminé, d'un répertoire contenant trois sous-répertoires, un pour chacune des versions actives du langage.

Une fois l'environnement de test créé, il faut maintenant écrire un test.

Cependant, il faut savoir ce qui mérite d'être testé, car il ne faut pas oublier que l'objectif de la TestFest est d'augmenter le pourcentage du code source de PHP couvert par les tests.

Afin de trouver le sujet de votre test, plusieurs pistes sont à votre disposition :

  • La liste des fonctions testées.
  • Le rapport relatif à la couverture de code.
  • Les rapports de bugs.

Dans le cadre de ce billet, nous allons écrire un test relatif à ce bug, pris totalement au hasard (ou pas).

Notre test doit respecter le format PHPT, qui se résume à une suite de plusieurs scripts PHP séparés par des balises spécifiques.

En conséquence, nous pouvons parfaitement utiliser les outils que nous utilisons habituellement pour écrire du code PHP pour écrire un test PHPT.

C'est donc armé de notre IDE ou de notre éditeur de texte favori que nous allons créer le fichier bug52013.phpt, puisque c'est la régle de nommage à suivre en ce qui concerne les tests relatifs aux bugs.

Nous allons commencer par un test très basique, afin de comprendre le fonctionnement du format PHPT :

--TEST--
Test for bug 52013 about Phar::descompressFiles().
--FILE--
<?php

echo 'ok';

?>
--EXPECT--
ok

Le texte qui suit la balise --TEST-- décrit le test.

Le code du test proprement dit est après la balise --FILE--.

Le texte suivante la balise --EXPECT-- permet quand à lui de définir ce que doit produire le code qui suit la balise --FILE--.

Il est à noter que les assertions définies à la suite de la balise --EXPECT-- sont vérifiées par rapport à ce qui est affiché par le code PHP du test.

Ce dernier doit donc nécessairement faire appel à des fonctions telles que echo, printf() ou bien encore var_dump() pour que son fonctionnement puisse être validé.

Notre test est relatif à un problème sur le format phar, qui n'est disponible qu'à partir de PHP 5.3.

Il faut donc ajouter le code nécessaire dans notre fichier afin que le test ne soit exécuté que si la version de PHP supporte cette fonctionnalité, grâce à la balise --SKIPIF-- :

--TEST--
Test for bug 52013 about Phar::descompressFiles().
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
--FILE--
<?php

echo 'ok';

?>
--EXPECT--
ok

De plus, nous avons besoin de générer une archive phar, et PHP demande une configuration spécifique pour cela.

Il faut donc définir cette dernière à l'aide de la balise --INI-- :

--TEST--
Test for bug 52013 about Phar::descompressFiles().
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>

--INI--
phar.require_hash=0
phar.readonly=0
open_basedir=
--FILE--
<?php

echo 'ok';

?>
--EXPECT--
ok

La structure de base de notre test est maintenant mise en place.

Il ne reste donc plus qu'à reprendre le code fourni dans le rapport de bug pour reproduire le problème et l'insérer après la balise --FILE-- :

--TEST--
Test for bug 52013 about Phar::descompressFiles().
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>

--INI--
phar.require_hash=0
phar.readonly=0
open_basedir=
--FILE--
<?php

mkdir(dirname(__FILE__) . '/testdir');
file_put_contents(dirname(__FILE__) . '/testdir/1.php', str_repeat(' ', 1455));

$phar = new \Phar(dirname(__FILE__) . '/compressed.phar');
$phar->buildFromDirectory(dirname(__FILE__) . '/testdir', '/\.php$/');
$phar->setSignatureAlgorithm(\Phar::SHA1);
$phar->compressFiles(\Phar::GZ);
$phar->decompressFiles();

echo 'ok';

?>
--EXPECT--
ok

Il est à noter que le code a été simplifié afin de cerner le problème le plus précisément possible.

Il ne reste plus maintenant qu'à faire le ménage, puisque notre code de test génère une archive phar, un répertoire et un fichier.

Il faut donc définir après la balise --CLEAN-- le code de nettoyage :

--TEST--
Test for bug 52013 about Phar::descompressFiles().
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>

--INI--
phar.require_hash=0
phar.readonly=0
open_basedir=
--FILE--
<?php

mkdir(dirname(__FILE__) . '/testdir');
file_put_contents(dirname(__FILE__) . '/testdir/1.php', str_repeat(' ', 1455));

$phar = new \Phar(dirname(__FILE__) . '/compressed.phar');
$phar->buildFromDirectory(dirname(__FILE__) . '/testdir', '/\.php$/');
$phar->setSignatureAlgorithm(\Phar::SHA1);
$phar->compressFiles(\Phar::GZ);
$phar->decompressFiles();

echo 'ok';

?>
--CLEAN--
<?php

unlink(dirname(__FILE__) . '/testdir/1.php');
rmdir(dirname(__FILE__) . '/testdir');
unlink(dirname(__FILE__) . '/compressed.phar');

?>
--EXPECT--
ok

L'écriture de notre test est maintenant terminé, et il ne reste donc plus qu'à l’exécuter, afin de savoir si le bug a été corrigé dans les versions de développement du langage.

Pour cela, il suffit d’exécuter à partir du répertoire de votre environnement de test la commande suivante :

# ./php53/sapi/cli/php ./php53/run-tests.php -p ./php53/sapi/cli/php/ /path/to/bug52013.phpt

Afin de vérifier si le test n'est pas exécuté par PHP 5.2, il suffit de faire appel à php 5.2, de la façon suivante :

# ./php52/sapi/cli/php ./php52/run-tests.php -p ./php52/sapi/cli/php/ /path/to/bug52013.phpt

De même, il suffit de remplacer php53 par php-trunk pour tester la dernière version du trunk.

Il peut arriver que votre test soit mal écrit, ou que vous n'obteniez pas le résultat attendu.

Dans ce cas, je vous invite à consulter les fichiers .diff et .log préfixé avec le nom de votre fichier de test.

Ces fichiers sont générés lors de l’exécution du test et vous permettront de diagnostiquer le problème.

Le fichier .diff contient en effet la description des différences entre ce qu'a généré votre test et ce qui est attendu dans la section --EXPECT--.

Le fichier .log résume quand à lui ce qui est attendu et ce qui est effectivement obtenu.

Une fois notre test fonctionnel, il reste à le soumettre à l'équipe qualité de PHP afin que notre test soit vérifié et intégré.

Dans le cadre de la TestFest, la procédure est particulière, mais comme pour l'instant personne n'a organisé un évènement sur ce thème en France (mais que fait l'AFUP ?), il faut passer par la liste de diffusion correspondante php-qa@lists.php.net.

Vous êtes maintenant paré pour écrire vos propres tests et ainsi améliorer la qualité de PHP.

Pour tout complément d'information sur le sujet, je vous invite à vous référer à la documentation proposées par l'équipe qualité de PHP dans le cadre de la TestFest 2010, ainsi qu'aux tests fournis avec le code source de PHP.