Raccourcis : Contenu - rubriques - sous rubriques
EN FR

Le développement de tests unitaires est de plus en plus présent dans les projets, et jelix propose de quoi en réaliser facilement. La réalisation des tests unitaires fait d'ailleurs partie des méthodes de développement comme XP (eXtreme programming). Le processus de développement veut, en théorie (et en gros), qu'à chaque fois que l'on développe une fonctionnalité, une méthode, on développe aussi les tests qui vont permettre de vérifier le bon fonctionnement de la méthode. Et à chaque fois que l'on modifie ou ajoute un bout de code, on lance tous les tests unitaires pour vérifier qu'il n'y a pas de régressions. Cela permet ainsi de garantir un minimum, un fonctionnement robuste de l'application.

Créer des tests avec PHPUnit

L'utilisation du framework de tests PHPUnit est la solution "officielle" depuis Jelix 1.3. Lire son manuel pour en savoir plus sur son fonctionnement. De plus, il n'est pas fourni avec Jelix, vous devez donc l'installer (via Composer si possible).

Cependant, Jelix fourni de quoi l'intégrer au mieux dans votre application. La commande createapp a créé un script tests/runtests.php dans votre application (ou copier le fichier lib/jelix-scripts/templates/tests/runtests.php).

Vous devez exécuter ce fichier en ligne de commande plutot que PHPUnit pour lancer les tests. Il vous évite de créer un fichier phpunit.xml, et lance les tests qui sont stockés dans le repertoire tests/ de chacun de vos modules.

Pour créer des tests :

  • les fichiers doivent être dans le répertoire tests/ de vos modules
  • les noms des fichiers doivent avoir un suffix .pu.php (et non pas Tests.php comme c'est le cas en général pour PHPUnit)
  • lancez php runtests.php --all-modules pour démarrer les tests de tout les modules
  • lancez php runtests.php --module foo pour démarrer les tests du module "foo"
  • vous pouvez ajouter l'option --testtype xxxx et cela lancera uniquement les tests des fichiers en *.xxxx.pu.php. Ainsi, vous pouvez séparer par exemple, les tests unitaires des tests fonctionnels.

Vous pouvez aussi ajouter les options usuelles de PHPUnit.

Créer des tests avec Simpletest

Simpletest était le framework de tests unitaires utilisé jusqu'à la version 1.2 incluse. Il est maintenant obsolète dans le projet Jelix, mais est toujours présent jusqu'à la version 1.6, pour des raisons de compatibilité. Il ne sera plus présent dans les version suivantes.

Le module jUnitTest doit être installé. Pour cela il vous suffit d'exécuter la commande


php cmd.php installmodule junittests

Copier également le répertoire jelix-modules/junittests/install/www/tests dans myApp/www/

Préparation

Les tests unitaires dans Jelix ne peuvent s'effectuer qu'avec l'édition "developer" de Jelix. Celle-ci contient en effet un module spécifique pour lancer les tests unitaires, junittests, et la bibliothèque SimpleTest. Si vous voulez absolument lancer les tests unitaires sur un serveur en production avec une édition "optimized" de jelix, vous devez y copier les répertoires lib/simpletest/ et lib/jelix-modules/junittests de l'édition "developer".

Pour pouvoir lancer les tests, il faut aussi ajouter au début du fichier de configuration de votre application :


  enableTests = on

Vous devez mettre à off quand vous passez votre application sur le serveur de production, ou utilisez une édition "optimized" de jelix (ou encore supprimer le module junittests tout simplement). Cela évite que n'importe qui puisse lancer les tests unitaires.

les fichiers de tests

Les tests unitaires, ce sont des scripts qui font des tests sur des classes, des méthodes, des fonctions.

Les tests dans Jelix doivent reposer sur la bibliothèque simpletest : vous devez donc réaliser des classes, qui héritent de la classe UnitTestCase de simpletest, et vous les placez dans un ou plusieurs fichiers dans les répertoires "tests" de vos modules.

Ces fichiers seront ensuite appelés par le module junittests quand vous voudrez les exécuter.

Les tests peuvent être lancés soit par l'interface web de junittests, soit par le script en ligne de commande fourni par junittests. Certains tests doivent parfois s'exécuter uniquement via le web, ou uniquement via la ligne de commande (tout dépend de la nature de ces tests). Aussi les noms des fichiers de tests doivent se terminer par un suffixe précis pour faire savoir à junittests les tests qu'il peut lancer dans tel ou tel contexte :

  • .html.php : le test ne pourra être lancé que via l'interface web
  • .cli.php : le test ne pourra être lancé que via la ligne de commande
  • .html_cli.php : le test peut être lancé indifféremment via le web ou via la ligne de commande.

Le nom qui précède le suffixe importe peu. Sachez toutefois qu'il sert de libellé lors des affichages des tests, et une transformation est effectué sur ce nom pour un affichage plus lisible :

  • les points sont transformés en ": "
  • les caractères soulignés "_" sont transformés en espaces.

Par exemple si on nomme le fichier ainsi, "jdao.main_api_with_pdo.html.php", le libellé des tests contenus dans ce fichier sera "jdao: main api with pdo". Et comme il a le suffixe ".html.php", il ne pourra être lancé que via l'interface web de junittests.

Création d'un test

Pour créer un test, il faut créer une classe héritant de UnitTestCase ou des autres classes héritières de UnitTestCase proposées par simpletest, et y écrire des méthodes dont le nom doit commencer par "test". Ces méthodes feront alors les tests que vous désirez, en utilisant l'API de simpletest. Pour plus de détails sur cette API, lisez la documentation sur le site de simpletest, en particulier la page sur unittestcase. Notez que dans cette documentation, vous devez ignorer tout ce qui concerne les "reporters" et les "group tests" : le module junittests s'occupant déjà de tout ça. Vous pouvez aussi regarder les tests qui sont présents dans le module unittest de l'application testapp disponible en téléchargement.

Voici un exemple de test. Admettons que l'on veuille faire des tests sur une classe "panier" d'un module "shop". On créer alors un fichier "shop/tests/panier.html.php" et on y place la classe suivante :


class testShopPanier extends UnitTestCase {

   function testPanierVide () {
      $panier = jClasses::create("shop~panier");
      $content = $panier->getProductList();
      $this->assertIdentical( $content, array());
   }
}

Le nom de la classe "testShopPanier" est totalement libre. Mais il faut faire attention que ce ne soit pas un nom déjà pris par une autre classe de tests dans d'autres modules. Aussi il est recommandé que le nom contienne le nom du module ou autre signe distinctif.

On a ici créé une fonction qui teste si, lors de la création d'un panier, celui-ci est bien vide. On instancie donc la classe panier, on appelle sa méthode getProductList qui devrait nous renvoyer une liste de produit. Et ensuite on test si le contenu renvoyé est bien un tableau vide.

Vous pouvez ajouter autant de méthodes de tests que vous voulez dans une même classe de test, mais aussi de classes dans un seul fichier. Voici un deuxième exemple :


   function testAjoutProduit () {
     // creation d'un panier
     $panier = jClasses::create("shop~panier");

     // creation d'un produit
     $product = jClasses::create("shop~product");
     $product->label = "DVD coluche";
     $product->price = 12.40;

     // ajout du produit dans le panier
     $panier->addProduct($product);

     $liste = $panier->getProductList();

     // test si le panier contient bien un produit
     $this->assertTrue( count($liste) == 1);

     // test si le produit contenu correspond bien à celui mis
     $p = $liste[0];
     // verification que c'est un objet product
     if($this->assertIsA($p , 'product')){
          $this->assertEqual($p->label , 'DVD coluche');
          $this->assertEqual($p->price , 12.40);
     }

     // on enleve le produit
     $panier->removeProduct('DVD coluche');

     // on vérifie que le panier est bien vide à nouveau
     $content = $panier->getProductList();
     $this->assertIdentical( $content, array());

   }

Lancement des tests via l'interface web

Le lancement des tests se fait en appelant la page principale du module junittests. Un exemple d'url : http://testapp.jelix.org/index.php?module=junittests . Vous pouvez d'ailleurs vous rendre à cette url précise : vous y verrez tous les tests unitaires sur jelix ;-)

N'oubliez pas de mettre dans la configuration le paramètre enableTests = on, sinon vous aurez droit à une erreur 404.

Cette première page présente sur la gauche toute la liste des tests présents dans votre application, classés par module. Il suffit de cliquer sur un des tests pour le lancer et voir le résultat. Vous avez des liens aussi pour lancer tous les tests d'un module, ou tous les tests de votre application (attention cependant, les lancer tous peut être long pour les grosses applications, et provoquer un "timeout" au niveau du navigateur).

À la fin du lancement de tests, il est affiché le nombre de tests unitaires qui sont passés avec succès, et celui des tests échoués.

Notez que le module junittests utilise sa propre réponse HTML, et fait appel à une feuille de style tests/design.css qui doit être placée dans le répertoire www de votre application. Vous en trouverez une dans le répertoire install du module junittests.

Lancements des tests via la ligne de commande

Le lancement des tests se fait en exécutant un script tests.php se trouvant dans le répertoire scripts de l'application jelix. Vous pouvez utiliser l'application testapp (voir dans "Application de test") pour en voir un exemple.

Voici une listes des différentes commandes disponibles :

Lister tous les tests

Voir la liste de tous les tests de votre application rangés par modules. Vous devez préciser seulement ici le nom du contrôleur car le mot-clé "help" renvoie vers l'aide générale de la ligne de commande de Jelix. Exemple :


php tests.php default:help

Lancer tous les tests de l'application

Exécuter l'ensemble des tests de votre application. Pas besoin ici de paramètre particulier, car exécuter tous les tests de l'application est l'action par défaut. Exemple :


php tests.php

Lancer tous les tests d'un module

Exécuter l'ensemble des tests d'un module spécifié. Vous devez ici donner le nom de votre module en paramètre. Exemple pour testapp :


php tests.php module jelix_tests

Lancer un test particulier

Exécuter le test spécifié. Vous devez ici donner le nom du module et le nom du test en paramètre, qui est spécifié dans la commande help (entre parenthèses). Exemple :


php tests.php single jelix_tests core.jlocale

À la fin du lancement des tests, il est affiché le nombre de tests unitaires qui sont passés avec succès, et celui des tests échoués.

Notez que si vous n'avez pas le fichier tests.php dans le répertoire scripts, vous pouvez récupérer tous les fichiers nécessaires (le script et le fichier de configuration) dans le répertoire install du module junittests.