• Ce blog — désormais archivé — est en lecture seule.

Faut-il tester… les tests ?

Avec ce titre très accrocheur, vous allez surement penser que je vais vous parler de tests et vous avez raison… Mais de quels tests et pourquoi d’abord ?

Il y a un presque deux ans maintenant, j’apprenais à écrire des tests unitaires et fonctionnels en Java, à l’aide de JUnit, JMeter, et compagnie. J’ai appris à écrire des scénarios de tests avec un logiciel dont je ne me souviens plus du nom, une alternative gratuite à HP Test Director. On écrit des scénarios de tests, des gens suivent les instructions et fournissent le résultat qu’ils obtiennent. C’est bien gentil tout ça mais je n’ai pas 50 personnes sous la main pour les faire exécuter mes tests et ce n’est pas mon associé qui voudrait suivre mes procédures…

Comme mon boulot consiste à écrire uniquement des sites web, j’ai cherché un outil qui pourrait faire ce boulot à ma place. Il ne m’a pas fallu longtemps pour trouver Selenium, une suite d’outils permettant d’enregistrer un enchaînement d’actions dans le navigateur, de rejouer cet enchaînement autant qu’on le souhaite, sur plusieurs navigateurs, en parallèle (test de « scalabilité« ), …

C’est donc l’outil parfait pour gérer les scénarios fonctionnels. J’enregistre mes tests et je les rejoue. Je vérifie ainsi que mon appli réponds correctement et que je n’ai rien cassé en modifiant une partie du code. Exemple avec symfony, la mise à jour du schema.yml.

D’ailleurs avec symfony, on peut faire des tests fonctionnels et c’est une chose que je ne faisais pas. Pour être franc, je ne faisais pas trop de tests en PHP, enfin si mais pas formellement. Maintenant cette période est terminée. J’adopte une nouvelle approche, l’approche TDD que j’expliciterai plus tard. En symfony, on peut donc faire des tests fonctionnels avec les classes sfTestFunctional et sfBrowser (qui simule un navigateur). Pourquoi utiliser Selenium alors ? Et bien parce que ces tests sont bons mais ne remplacent pas Selenium, par exemple, on ne peut pas tester les appels Ajax. Voici un aperçu d’un test fonctionnel écrit en symfony :

/**
* Functional test file
*
* @author William DURAND
*/


include(dirname(__FILE__).'/../../bootstrap/functional.php');
include(dirname(__FILE__).'/../../bootstrap/doctrine.php');

$browser = new sfTestFunctional(new sfBrowser());

// Auto-generated
$test = $browser->test();
$conn = Doctrine::getConnectionByTableName('Commande');

$conn->beginTransaction();

// Get the form
$browser
  ->call('/commande/new', 'GET', array())
  ->with('request')->begin()
    ->isParameter('module', 'commande')
    ->isParameter('action', 'new')
  ->end()
  ->with('response')->begin()
    ->info('1.1 - Get the "Commande" form')
    ->isStatusCode(200)
    ->checkElement('#content > p', '#Nouvelle commande#')
  ->end()
  ;

C’est très intuitif, les tests sont formés de « blocs » commençant par with() et terminant par end(). Il y a déjà beaucoup d’articles sur le sujet donc je ne m’y étendrait pas. Par contre petit tuyau, pour aller plus vite j’utilise le plugin swFunctionalTestGenerationPlugin qui permet de générer un « stub » de test fonctionnel symfony directement depuis les actions que l’on effectue dans la navigateur, pratique !

Il n’y a pas que les tests fonctionnels dans la vie, il y a également les tests unitaires. Comme JUnit pour Java, on a le droit à PHPUnit pour PHP mais je ne l’ai pas encore essayé. J’utilise Lime, un framework de tests embarqué dans symfony, écrit par Maître @fapbot. Au lieu des classiques assertTrue(), assertFalse(), on dispose des méthodes is(), isnt(), … Comme pour les tests fonctionnels, l’écriture de tests unitaires est très intuitive.

Grâce à ces tests unitaires, mon code est contrôlé et je n’ai plus à me soucier d’éventuels effets de bord. Je sais exactement comment se comportent mes méthodes et mes objets. Je blinde ainsi mon modèle, ce qui fait une chose de moins à me soucier. Je passe 50% de mon temps à écrire du code dans mes actions et vues, 20% de mon temps à écrire du code dans mon modèle, 20% à écrire mes tests et le reste à boire du café… Je ne me soucis pas du reste, mon environnement de test est complètement découplé de mon environnement de dev et l’environnement de prod est distant.

Sauf que… lancer les tests c’est long et j’aime pas trop attendre. Je me suis tourné vers des outils qui font le boulot à ma place. C’est ce que l’on appelle des serveurs d’intégration continue. Je regrette de ne pas avoir pu tester Sismo, le serveur d’intégration continue (CI) de Sensio Labs (vous savez, le même que plus haut, décidément !).

J’ai testé Hudson et phpUnderControl (cruiseControl). Pour ce dernier, je n’en suis pas très satisfait avec symfony et Lime. Il fonctionne bien, l’utilisation de Ant fait plaisir mais je n’ai pas pu profiter de toutes les possibilités de ce serveur. Je l’ai donc laissé tombé au profit d’Hudson. C’est un serveur plaisant, rapide à prendre en main, très lisible et parfaitement customisable avec le nombre incommensurable de plugins dont il dispose. Pour savoir comment le faire fonctionner avec symfony, on lit cet article de Nicolas Perriault. Pour ma part, je n’utilise pas SVN mais Git, il suffit d’installer le plugin qui va bien.

Voilà, sachant que mon Gmail est tout le temps ouvert et que j’ai le checker qui va bien dans Chrome, je suis alerté assez rapidement par mail si je casse tout. Encore quelque chose de moins à me soucier. C’est ce qu’on appelle, je crois, l’efficience et la productivité s’en porte beaucoup mieux.

Il me reste cependant quelque chose à éclaircir : TDD. Test Driven Development ou Développement piloté par les tests. Pour faire simple, avant de développer une fonctionnalité, je réfléchis. Oui mais je réfléchis deux fois puis trois fois même. C’est-à-dire que je cherche comment l’écrire, comment elle pourrait mal se comporter et comment la tester. Ensuite, je prends le chemin inverse. J’écris mes tests, je veille à son comportement lors de son écriture. Et voilà, ma fonctionnalité est écrite, les tests passent, je continue mon travail. Je ne passe pas 30 minutes à chercher ce qui ne va pas…

Au fait, pourquoi cet intitulé d’article ? C’est une interrogation qui vient des cours de qualité logiciel que j’ai pu avoir auparavant. J’ai toujours gardé cette phrase à l’esprit lorsqu’on me parle de tests. La question n’est pas si simple qu’elle en a l’air. Si vous avez une idée, les commentaires sont fait pour cela. Moi, je garde mon idée ;)

En résumé, j’ai passé de bonnes vacances :-D

  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Twitter
  • Google Bookmarks
  • FriendFeed
  • LinkedIn
  • MySpace
  • Netvibes
  • PDF
  • Ping.fm
  • RSS
  • Technorati
  • viadeo FR
  • Wikio
  • Yahoo! Buzz

Related Posts

Cet article a été publié dans Boulot, Ma vie, symfony avec les mots-clefs : , , , , , . Bookmarker le permalien. Les commentaires et les trackbacks sont fermés.

3 commentaires

  1. Amokrane
    Le 10 août 2010 à 14 h 50 min | Permalien

    Excellent article. Tu vas bien t’amuser au cours de Romain (Java pro) toi en F2 :) .
    Le fait de tester la couverture d’un code constitue déjà un test des tests. Et à mon avis, on doit en rester là car ça devient trop compliqué par la suite. Concernant les serveurs d’intégration continues, il faudrait peut être préciser que leurs rôle ne se limite pas à vérifier le nombre de tests unitaires qui passent ou pas, ce n’est qu’une des fonctionnalités d’un serveur CI (et pas la plus importante).

    Sinon j’aime bien le style de ton article, ça se lit facilement!

    • Le 10 août 2010 à 14 h 55 min | Permalien

      Héhé merci beaucoup :-)

      La couverture de code, effectivement, je n’en ai pas parlé. Avec symfony + xDebug on peut tester la couverture de notre code :)
      Pour les serveurs CI, il est vrai, ce n’est pas juste un lanceur de tests. On peut aller plus loin comme tu le sais, lancer des builds stables, déployer, etc… bref une automatisation des process de contrôle qualité et de mise en prod. La-dessus, je ferais un autre article (très bientôt) parce que j’utilise également des outils qui facilitent le travail ;-)

  2. Joan
    Le 10 août 2010 à 22 h 06 min | Permalien

    Oui, bon article! j’ai bien aimé l’explication de TDD parce que comme pour plusieurs choses en développement je le fais mais je savais pas que ça s’appelait comme ça. Je préfére faire les tests, à la fin on à le code, comme ça je testait Hibernate avec mon code métier pour le stage.

2 trackbacks

  1. [...] Ce billet était mentionné sur Twitter par William DURAND, Pierre. Pierre a dit: Faudrait que je m'y mette aux tests un jour RT@couac New post : Faut-il tester… les tests ? http://bit.ly/ayticP #php [...]

  2. [...] le jour où j’ai voulu tester les tests, que le besoin de couleur c’est vraiment fait ressentir: j’ai d’abord perdu pas [...]