Test Unitaire avec simpletest
Les tests unitaires sont très utile pour vérifier si les mise à jours ne génèrent pas des bugs de régressions.
Nous allons voir comment faire des test unitaires fiables en php en utilisant la librairie simpletest.
Mis en place de simpletest
Pour télécharger la librairie c’est ici. Vous pouvez allez aussi sur le site officiel pour télécharger la dernière version.
Dans ce tutoriel nous allons créer une classe de toute pièce pour faire nos tests unitaires.
Nous allons créer un dossier operation où nous allons mettre notre dossier décompressé simpletest.
comment construire un test unitaire
Construire un test unitaire efficace, demande beaucoup d’abstraction. En effet le test unitaire à la responsabilité de prévoir de façon exhaustive toute les possibilités et les comportements d’un code source. On peu dire que le test unitaire doit s’assurer que le code source fonctionne en toute circonstance et qu’il répond aux spécifications fonctionnelles.
Roul, mais comment veux tu que je fasse test unitaire qui prévoie tout ?
Ne vous inquiétez pas, je suis loin d’être un as en développement
, mais j’arrive à faire des test unitaires corrects. D’ailleurs vous allez voir que ce n’est vraiment pas compliqué, parce que allons justement en faire un (sur une classe très simple). Il faut juste suivre une bonne méthode de travail pas à pas et ne pas précipiter les choses ^^. Mettez vos combinaisons nous allons devoir tester une classe vraiment pas propre …
La classe opération
Nous allons commencer, par créer une classe toute simple. La classe opération, cette classe donnera juste la possibilité d’effectuer des opérations basiques (addition, soustraction, multiplication ….) sur des réels.
class operation
{
public function __construct()
{
;
}
public function addition($fNb1,$fNb2) {
return $fNb1 + $fNb2;
}
}
Donc la première méthode de la classe opération, est de faire une addition.
Nous allons faire le test unitaire ce cette méthode.
On va faire appel à la librairie simpletest.
require_once('simpletest/unit_tester.php');
require_once('simpletest/reporter.php');
require_once('./operation.class.php');
Là on va créer notre classe de testUnitaire qui héritera de la classe UniTestCase.
class testUnitaireOperation extends UnitTestCase {
function __construct() {
$this->UnitTestCase('Test unitaire sur la classe operation');
}
}
Maintenant on va tester notre méthode addition.
Comment simpletest test une addition ?
En fait c’est très simple, on va faire appel à une série de méthode simpletest.
Chaque méthodes simpletest va faire appel aux fonctions que nous allons tester (pour nous, ça sera la méthode addition). Chaque méthodes simpletest vont bien entendu attendent un résultat.
Si les résultats ne correspondent pas à ce que l’on attend, simpletest va tout de suite afficher un message d’erreur et indiquer sa provenance.
On va commencer par cette méthode :
$this->assertIsA
Alors, dans cette méthode on va lui indiquer un type. Ensuite il va vérifier si l’objet passé en paramètre est bien du même type que celui-ci.
C’est pas très clair ? Bon on va voir un exemple
:
$this->assertIsA($oKevin, ‘garçon’);
Le test unitaire vérifie si l’objet $oKevin est bien un objet du type garçon.
Revenons dans notre classe opération. Pour commencer nous allons vérifier si l’objet oMonOpération que l’on va créer est bien du type operation :
public function testAddition() {
echo 'Debut des test sur les additions '."n";
// Creation du objet operation
$oMonOperation = new operation();
$this->assertIsA($oMonOperation, 'operation');
}
Pour déclencher le test, juste après votre classe vous pouvez faire :
$oOperationTest = &new testUnitaireOperation(); $oOperationTest->run(new TextReporter());
Vous pouvez lancer votre test unitaire via interface Web ![]()
Normalement le test unitaire devrait bien se dérouler et vous devriez voir ça :
Comment lire le résultat :
Passes : Le nombre de test qui sont se bien déroulé.
Failures : Le nombre de test dont résultat ne corresponds pas à ce que l’on attends.
Exceptions : Le nombre de test qui ont généré une erreur.
Nous allons voir une autre méthode de simpletest. Cell-ci vérifie si la fonction testée, retourne bien vrai.
$this->assertTrue
la fonction qui vérifie si la fonction retourne faux c’est :
$this->assertFalse
Pour notre test unitaire nous allons utiliser la méthode assertTrue pour vérifier si la méthode addition peut être appeler (a travers l’objet opération).
notre test unitaire doit maintenant ressembler à ça :
public function testAddition() {
echo 'Debut des test sur les additions '."n";
// Creation du objet operation
$oMonOperation = new operation();
$this->assertIsA($oMonOperation, 'operation');
$aMethode = array($oMonOperation, 'addition');
//Appel de la methode addition
$this->assertTrue(is_callable($aMethode, true));
}
Maintenant, on doit avoir deux tests qui sont passés. C’est vrai pour l’instant ce test unitaire n’est pas très utile.
Mais ne vous inquiétez pas, nous allons vite arriver sur des cas que l’on avait pas forcément pensé.
Les test unitaires vont se faire un plaisir de nous rappeler à l’ordre.
$this->assertEqual
Pour cette méthode il faut deux paramètres. Le premier c’est la fonction que l’on veut tester,
et le second c’est ce que doit renvoyer la fonction.
Si on veut tester la commande addition, on va faire une addition du style 1 + 1 et notre méthode devra retourner … (ou est cette calculette ?) … 2 !
En langage php cela donne : $this->assertEqual($oMonOperation->addition(1,1), 2);
Pour notre classe opération on va faire toute une batterie de test pour vérifier que tout fonctionne bien.
public function testAddition() {
echo 'Debut des test sur les additions '."n";
// Creation du objet operation
$oMonOperation = new operation();
$this->assertIsA($oMonOperation, 'operation');
$aMethode = array($oMonOperation, 'addition');
//Appel de la methode addition
$this->assertTrue(is_callable($aMethode, true));
// 1 + 1 = 1
$this->assertEqual($oMonOperation->addition(1,1), 2);
// 1 + 0 = 0
$this->assertEqual($oMonOperation->addition(1,0), 1);
// 0 + 1 = 1
$this->assertEqual($oMonOperation->addition(0,1), 1);
// 24 112 126 468 + 54 456 123 123 = 78 568 249 591
$this->assertEqual($oMonOperation->addition(24112126468,54456123123), 78568249591);
// 12.5 + 13.3 = 25.8
$this->assertEqual($oMonOperation->addition(12.5,13.3), 25.8);
}
Super ! nos 7 tests sont passés
Jusque là c’était facile, maintenant nous allons nous lancer sur des tests plus perspicaces.
Mais comment faire Roul ?
Il faut juste essayer de pourrir notre code en envoyant tout et n’importe quoi en paramètre.
Pour le test unitaire de la méthode addition on va faire :
$this->assertFalse($oMonOperation->addition(‘a’,12));
On test ….
Oh lalala ! La belle erreur ! Notre fonction ne renvoie pas faux, mais 120.
Notre fonction, n’est pas encore opérationnelle, on va vite corriger ça.
public function addition($fNb1,$fNb2) {
if (is_numeric($fNb1) && is_numeric($fNb2))
{
return $fNb1 + $fNb2;
}else{
return false;
}
}
C’est bon, tout passe ^^.
Vous savez maintenant faire des test-unitaires. Bien sur ce test unitaire n’est pas du tout fiable, on devrait faire des batteries des tests beaucoup plus importantes. Il n’est pas nécessaire d’approfondir plus sur le test d’addition, parce que chaque test unitaire est propre au code qu’il vérifie.
Oui, je sais faire un test unitaire, mai j’ai un gros blanc, je ne sais pas quoi tester, comment faire ???
En fait la démarche pour faire les test vous la connaissez déjà.
Dans un premier temps on vérifie si notre fonction ne retourne pas d’erreur.
Puis nous faisons différents tests pour voir si les fonctions retournent bien le résultat demandé.
Et enfin, on en fait voir de toutes les couleurs à nos fonctions(voir si elle ne génère pas d’erreur).
Après en fonction des spécifications techniques, on peux faire des test unitaire sur la consommation de mémoire (qui est un vrai problème en php) ou sur la vitesse d’exécution du script.
Quand faut-il faire les tests unitaires ?
En fait cela dépend de votre projet, mais il faut savoir qu’il y a trois techniques différents pour savoir quand construire ces tests unitaires :
La technique classique : le code d’abord, les tests ensuite.
La technique inversée : les tests d’abord et le code ensuite
La technique entrelacée : on fait les test en fonction de l’avancement du projet.
Un dernier exemple plus poussée
On va construire la méthode division de notre classe opération :
public function division($fNb1,$fNb2) {
if (is_numeric($fNb1) && is_numeric($fNb2))
{
return $fNb1 / $fNb2;
}else{
return false;
}
}
Et on va reprendre notre test unitaire de la méthode addition pour faire celle de la méthode division.
public function testDivision() {
echo 'Debut des test sur les divisions '."n";
// Creation du objet operation
$oMonOperation = new operation();
$this->assertIsA($oMonOperation, 'operation');
$aMethode = array($oMonOperation, 'division');
//Appel de la methode division
$this->assertTrue(is_callable($aMethode, true));
// 1 / 1 = 1
$this->assertEqual($oMonOperation->division(1,1), 1);
// 1 / 0 = faux
$this->assertFalse($oMonOperation->division(1,0));
// 0 / 1 = 0
$this->assertEqual($oMonOperation->division(0,1), 0);
// 24 112 126 468 / 54 456 123 123 = 0.442
$this->assertEqual($oMonOperation->division(24112126468,54456123123), 0.442);
// 12 / 4 = 3
$this->assertEqual($oMonOperation->division(12,4), 3);
// a / 12 => false
$this->assertFalse($oMonOperation->division('a',12));
}
Eh la, malheur ! nos tests unitaires nous renvoie que des erreurs.
Maintenant il reste plus qu’à debugger, mais la ce n’est pas l’objectif du tutoriel, et pour moi il est l’heure de me coucher







Note de l'article