Phptourlille2011 - tharkun/atoum GitHub Wiki
PHP Tour Lille 2011
Le support de cette conférence est également disponible au format pdf. Une vidéo de l'évolution du dépôt de code de atoum de sa création à aujourd'hui a servi d'introduction à la conférence.
Je m'appelle Frédéric Hardy, j'ai 35 ans, et cela fait maintenant un peu plus de 12 ans que je fais du PHP.
L'histoire de atoum est très liée à la mienne, puisque son développement a commencé en 2005 suite à la création de ma société.
En plus des casquettes de secrétaire et de commercial, je portais également la casquette de développeur et j'assurais à la fois le développement du système de gestion de l'entreprise au niveau commercial et technique ainsi que le développement de projets pour nos clients.
Je devais donc assurer à moi seul à la fois la conception des projets qui m'étais confié, tout en les testant et en respectant les délais de livraison.
J'avais donc un gros problème, car je n'avais pas le temps nécessaire pour réaliser correctement chacune de ses tâches.
Comme nous n'avions pas la possibilité d'embaucher pour des raisons économiques et qu'il n'était pas possible de modifier les dates de livraisons, il ne m'était donc possible que d'agir sur les tests pour gagner du temps.
Je me suis donc fortement intéressé aux tests automatisés et plus particulièrement aux outils de tests unitaire comme SimpleTest et PHPUnit, afin de faire tester mon code de manière automatique par la machine et ainsi me libérer suffisamment de temps pour la conception et pouvoir respecter les dates de livraison.
Ces outils présentaient cependant l'inconvénient, à l'époque, d'être développé en PHP 4, alors que l'ensemble de mes développements étaient réalisés à l'aide du tout récent PHP 5.
Cela posait donc un certain nombre de problèmes, car ils n'étaient pas à 100% compatible avec PHP 5 et je n'avais pas le temps d'attendre qu'ils le deviennent.
J'ai donc décidé de développer en PHP 5 mon propre outil de tests unitaires, d'autant que cette version du langage disposait d'une API d'instropection très utile dans ce contexte.
Son développement s'est poursuivi pendant cinq années, durant lesquelles, en fonction de mes envies et des évolutions de PHP, il a subit un certain nombre de mutations diverses et variées destinées essentiellement à tester les nouvelles fonctionnalités du langage, améliorer ma productivité et l'adapter à mes besoins.
En 2010, le projet a connu un tournant décisif, car je me suis rendu compte de trois choses.
Tout d'abord, il me servait essentiellement pour développer mon framework PHP personnel et j'ai réalisé à cette époque que cela n'avait plus guère d'intérêts car il y avait maintenant des frameworks matures comme Symfony ou Zend Framework de disponible, et je savais très bien que je n'aurais pas les moyens de faire percer ma solution face à eux.
Ensuite, j'ai compris que le développement de SimpleTest était au point mort depuis un bon moment et qu'il y avait donc une place à prendre.
Enfin, je m'amusais beaucoup plus à développer mon outil de tests unitaires que mon framework.
En conséquence, j'ai décidé d'arrêter le développement de ce dernier et de concentrer tout mes efforts sur mon outil de tests unitaires et j'ai donc donné naissance à atoum le 28 mai 2010.
Depuis, son développement se poursuit mais toujours dans le respect de trois valeurs fondamentales.
La première de ces trois valeurs est la simplicité, dont Léonard de Vinci a dit qu'elle était la sophistication suprême, et je suis totalement d'accord avec cette définition. Cette recherche de la simplicité se retrouve aussi bien au niveau du code que de l'utilisation de atoum.
Le code suit en effet le principe KISS, afin d'être le plus facile possible à comprendre et à maintenir.
Le même principe est également appliqué pour tout ce qui concerne la mise en œuvre du framework, qui ne doit pas demander de réflexion de la part de l'utilisateur.
Un ensemble de 5 autres principe de développement relatif à la programmation orientée objet regroupés sous l'acronyme SOLID sont également utilisés, toujours dans l'optique d'avoir un code modulaire et testable.
Grâce à ces deux choses, le code de atoum est donc simple à lire, à comprendre et surtout à mettre en œuvre pour écrire des tests, ce qui est très bien, mais il faut également que qu'ils soient simple à exécuter.
C'est la raison pour laquelle la création d'une classe de test ainsi que son exécution ne nécessite la manipulation que d'un seul et même script.
Il suffit en effet au développeur d'inclure ce fichier dans un script pour qu'il dispose des outils nécessaires à la rédaction des tests, et il lui suffit de faire appel à ce fichier en ligne de commande pour les exécuter.
Le développeur n'a donc pas à se poser des questions et n'a à mémoriser qu'un seul chemin d'accès pour à la fois rédiger et exécuter ses tests unitaires, le tout avec une interface de programmation simple à appréhender et à utiliser.
Le concept du fichier unique pour tout faire a été poussé plus loin avec la mise en œuvre d'une archive PHAR pour distribuer atoum.
Cette archive contient en effet l'intégralité du code source du framework et dispose exactement des mêmes fonctionnalités que le fichier évoqué précédement sans qu'il n'y ait besoin de la décompresser.
Elle s'utilise donc exactement de la même manière et de plus, l'installation et la mise à jour de atoum s'en trouve considérablement simplifiées vu qu'il n'y a plus qu'un seul fichier à manipuler dans les deux cas.
Le concept du fichier unique a été poussé à l'extrème en ce qui concerne l'exécution des tests, à tel point qu'il est possible d'exécuter des tests sans faire appel explicitement à atoum.
Il est en effet possible de lancer les tests contenu dans un fichier juste en faisant exécuter ce fichier par PHP en ligne de commande.
La rédaction des tests, déjà simple grâce au fait qu'il n'y a besoin d'inclure qu'un seul fichier pour exploiter atoum a été rendue encore plus simple grâce à l'élaboration d'un langage naturel pour rédiger les tests.
Le développeur écrit donc ses tests comme s'il racontait une histoire, avec des mots qui forment des phrases qu'il peut enchaîner à volonté, à la manière de ce que permet un outil tel que behat.
Grâce à atoum, il devient donc possible de faire travailler en tandem sur un même poste un développeur et un expert métier afin qu'il développe ensemble en même temps un code métier.
Grâce à ce langage naturel, la rédaction des tests devient donc plus fluide, plus naturel et donc plus simple, et il est également plus facile de les relire et de les faire évoluer.
Cela est encore simplifié par le fait que le vocabulaire du framework est évolutif.
Il est ainsi possible de définir des synonymes afin de redéfinir le vocabulaire du langage de base.
Le code des assertions a en effet été conçu de façon à pouvoir en créer facilement ou pour pouvoir les faire évoluer le plus facilement possible.
Cette capacité d'évolution et le fait qu'il est possible de définir des synonimes font qu'il est possible d'adapter les assertions de atoum au vocabulaire des développeurs ou à celui des experts métier.
Cette volonté de simplifier au maximum la rédaction des tests a également eu une grande influence sur les possibilités de bouchonnage de atoum, qui n'ont rien à voir avec les solutions qui existaient auparavant.
Grâce à atoum, chaque méthode publique d'un bouchon devient intégralement programmable à l'aide de fonctions anonymes.
Le développeur a donc la possibilité de redéfinir totalement le comportement de l'instance directement en PHP, sans avoir à maîtriser une syntaxe particulière.
De plus, une assertion spécifique permet de tester le comportement d'une telle instance, ce qui facilite les test sur leur comportement.
Comme nous venons de le voir, atoum a donc été conçu pour pouvoir être utilisé simplement et faciliter la rédaction et la maintenance des tests.
Cependant, tout cela ne serait rien s'il n'était pas capable de remonter efficacement les informations relatives à l'exécution des tests au développeur.
Il est capable de générer des rapports simples mais très complets basés sur une logique évenementielle et modulaire.
Un rapport est en effet composés de champs qu'il est très simple d'ajouter ou de supprimer, ce qui permet de les modifier facilement afin de les adapter à un besoin spécifique.
Le fait que atoum dispose de rapports puissants lui permette de s'intégrer très simplement dans une usine de code.
Il est ainsi très simple de l'utiliser en conjonction avec Hudson, TravisCI ou de générer le rapport de couverture du code par les tests au format HTML.
Dernière chose permettant de simplifier encore son utilisation, les fichiers de configuration de atoum sont écrits en PHP.
Le développeur n'a donc pas à apprendre une syntaxe particulière et dispose de l'intégralité de la puissance de PHP pour configurer atoum suivant ses besoins.
La modernité est la seconde valeur fondamentale de atoum, pour plusieurs raisons.
Tout d'abord, la version minimum de PHP nécessaire à son fonctionnement est la 5.3 car afin d'être simple à utiliser, il fait massivement appel aux espaces de nommage ainsi qu'au fonctions anonymes et aux fermetures lexicales qui sont à la base de son système de bouchonnage.
De plus, l'un des objectifs du projet est d'encourager la migration vers PHP 5.3, car la branche 5.2 est encore massivement utilisée même si elle n'est plus supportée.
La modernité de atoum se manifeste également par le fait que chaque méthode de tests s'exécute au sein d'un processus séparé afin de garantir l'isolation des tests.
De cette manière, il n'est pas possible pour une méthode de test d'avoir une influence, via par exemple des variables globales ou des variables statiques, sur les autres méthodes de test, et il devient donc par exemple très simple de tester un singleton.
De plus, l'isolation des tests permet d'éviter que l'exécution de l'ensemble des tests d'une suite de tests soit compromis si l'un d'entre eux provoque un plantage au niveau du moteur de PHP.
Enfin, elle permet de s'affranchir des problèmes de consommation mémoire qui peuvent survenir lorsqu'une ou plusieurs méthodes de test consomme l'intégralité de la mémoire disponible, empêchant ainsi l'exécution de la totalité de la suite de test.
Le fait que les tests soient exécutés dans des processus séparés a eu une conséquence intéressante puisque de ce fait, il devient possible de lancer les tests en parallèle, ce qui accèlere notablement leur exécution. Par défaut, atoum lance donc parallèlement un maximum de méthode de test au sein de processus distincts afin d'exploiter au maximum les ressources disponibles et garantir ainsi une vitesse d'exécution des tests la plus rapide possible.
Enfin, la dernière valeur fondamentale de atoum est l'intuition.
L'un des objectifs de l'outil est en effet de favoriser l'expression de l'intuition du développeur, afin qu'il ne réfléchisse pas consciemment soit à la façon de l'utiliser, soit à la façon de rédiger les tests.
En outre, atoum lui-même essaye d'être intuitif afin de faciliter la vie de son utilisateur.
Pour répondre à ce dernier objectif, atoum fait appel à la logique floue dans la gestion des arguments en ligne de commande défini par l'utilisateur.
Ainsi, ce dernier n'a plus à se préocuper de l'orthographe exact des arguments qu'il utilise pour lancer ses tests : peu importe qu'il mette une minuscule à la place d'une majuscule, ou qu'il loupe une lettre.
Dans le meilleur des cas, le framework fera la correction automatiquement pour lui, et dans le pire des cas, il lui proposera l'alternative la plus probable, ce qui dispensera l'utilisateur de la consultation de la documentation pour trouver le nom exact de l'argument qu'il veut utiliser.
Un soins particulier a également été apporté aux API de atoum, afin de rendre son utilisation la plus intuitive possible, notamment au niveau de la rédaction des tests.
Le recours aux interfaces fluides a été systématique dans la mesure du possible afin de permettre le chaînage des appels de méthodes.
De plus, une convention de nommage uniforme et logique au niveau des méthodes et des propriétés a été appliquée, et ils y a donc une grande uniformité dans l'API de atoum.
Le développeur n'a donc pas à se poser beaucoup de questions pour deviner le nom de la méthode ou de la propriété dont il a besoin.
Le développeur dispose de plus d'une grande latitude pour définir les tests qui doivent être exécutés.
Il est ainsi possible de lancer les tests d'un fichier spécifique, ou bien de lancer tout ceux contenus dans un répertoire.
Il est également possible, à l'aide d'annotations, d'ignorer les tests ou de les tagger, que ce soit au niveau des classes de test ou bien des méthodes, et de n'exécuter les classes ou les méthodes correspondant à un ou plusieurs tags.
Enfin, atoum permet de n'exécuter qu'une méthode d'une d'une classe, ou toutes les méthodes portant un nom précis parmi plusieurs classes.
Enfin, atoum dispose d'un mode "loop" qui permet au développeur de se concentrer sur les tests posant problèmes sans avoir besoin d'y réflechir consciemment et le dispense de devoir taper plusieurs fois la commande lançant les tests.
Lorsqu'il est lancé dans ce mode, le framework commence en effet par exécuter la totalité des tests demandés par l'utilisateur, et s'il détecte des erreurs, il ne re-exécutera à l'avenir que les tests posant problème jusqu'à ce qu'ils passent à nouveau au vert, et cela sans que l'utilisateur ait besoin d'intervenir.
Et une fois que les tests sont à nouveau au vert, il relance automatiquement l'intégralité des tests demandés afin de détecter les éventuelles régressions ou bugs introduit par la ou les corrections effectuées.
L'ensemble du mode "loop" se pilote uniquement à l'aide de la touche "Entrée", qui relance l'exécution des tests.
Dans ce mode, atoum se fait donc complètement oublié, ce qui permet au développeur de se concentrer sur le résultat de ses tests.
Le combo simplicité, modernité et intuition permet donc au développeur qui utilise atoum d'écrire facilement des tests fiables qui s'exécuteront rapidement tout en lui permettant de se concentrer sur l'essentiel, à savoir la rédaction d'un code de qualité.
Le but de atoum est donc très clairement de se faire oublier tout en s'intégrant totalement dans le flux de production du développeur afin d'augmenter à la fois sa productivité et la qualité de son travail.
Il semble que cette approche soit payante car atoum intéresse de plus en plus de monde, malgré sa visibilité récente.
Depuis sa mise à disposition sur GitHub, sa communauté est en croissance constante et à ce jour, un peu plus d'une dizaine de contributeurs ont participé à son développement à des degrés divers et les retours des utilisateurs sont très positifs.
Le projet est en effet mis en œuvre à titre personnel ou professionnel par de plus en plus de développeurs qui apprécies sa simplicité et sa puissance.
Atoum semble donc promis à un bel avenir, d'autant que son développement est loin d'être terminé et qu'il sera très certainement enrichie par les retours obtenus de ses utilisateurs, que j'espère de plus en plus nombreux.
Il est en effet développé en fonction des besoins exprimés, et plus il sera utilisé, plus son équipement de développement disposera de retour de la part des utilisateurs, plus il correspondra à leur besoin, d'autant que les valeurs de simplicité, de modernité et d'intuition dirigeront toujours sa conception.