IV. Outils et méthodes avancées▲
IV-1. Tests d'application Web▲
L'erreur est humaine. Même les meilleurs développeurs écrivent parfois du code avec des bogues. C'est inévitable. Ces problèmes peuvent être techniques, le résultat d'un calcul est erroné, ou ergonomiques, un formulaire de l'application ne fonctionne pas comme attendu.
Tout développeur vérifie que le code qu'il a produit fonctionne. Cependant, plus l'application se complexifie et plus il lui devient difficile de vérifier toutes les combinaisons. Cela prend beaucoup trop de temps et les risques d'oublis sont importants. Les tests sont alors reportés à la phase de recette.
Cette phase permet à des testeurs qui peuvent être des personnes payées pour cette tâche ou bien directement les utilisateurs finaux de s'assurer de la conformité de l'application livrée avec les spécifications. Elle est longue et demande beaucoup de rigueur pour s'assurer que l'ensemble des scénarios utilisateurs ont été vérifiés. Un scénario utilisateur est un ensemble d'actions qui doivent aboutir à un résultat reproductible. Par exemple, mettre un produit dans le panier d'achat ou bien encore effectuer une recherche sur un produit.
Si des problèmes sont trouvés pendant cette phase de recette, les développeurs sont chargés de les corriger avant qu'une nouvelle phase de recette ne valide les correctifs. Ce cycle peut être long et donc coûteux. Par ailleurs, plus un bogue est constaté tardivement plus sa correction est difficile et donc coûteuse car un développeur est beaucoup plus apte à corriger rapidement un morceau de code une heure après l'avoir écrit que plusieurs semaines après. D'autant, que plusieurs semaines plus tard, il est probable qu'un autre développeur se voit assigner la correction du problème. C'est alors que les conventions de programmation l'aideront à s'imprégner plus rapidement du code.
Dans une application, aucune modification n'est triviale. Les effets de bord, c'est à dire les effets inattendus d'une modification a priori simple et maîtrisée, peuvent être très difficiles à repérer.
Comme pour le déploiement, l'automatisation des tests est la clé de la qualité d'un code. Nous allons plus particulièrement nous pencher sur trois types de tests : les tests unitaires, les tests IHM (Interface Homme/Machine) et les tests fonctionnels.
Tester unitairement le code d'une application consiste à isoler une unité de ce code afin d'en vérifier le comportement dans différents contextes. Par exemple, on testera individuellement chaque méthode d'une classe afin de s'assurer qu'en lui passant des paramètres déterminés, elle produit le résultat attendu. Les tests unitaires sont souvent accompagnés d'une vérification de la couverture de code, qui consiste à s'assurer que le test conduit à exécuter l'ensemble (ou une fraction déterminée) des instructions présentes dans le code à tester.
Les tests fonctionnels décrivent en langage non technique une fonctionnalité. Par exemple, pour vérifier le calcul d'un ratio comptable, on fournira les valeurs d'entrée et le résultat attendu.
Les tests IHM, ou tests de recette, quant à eux permettent de s'assurer que les comportements de l'application sont ceux attendus. Par exemple, lorsqu'on soumet ces valeurs à ce formulaire les messages d'erreur sont conformes aux attentes.
Lors de la création des tests, une erreur courante consiste à ne rédiger que les tests pour les actions qui doivent réussir. Il est tout aussi important de s'assurer que ce qui doit échouer échoue bien. Ainsi, la saisie d'une valeur erronée dans un champ de formulaire doit être interceptée et le message correspondant affiché. Si la valeur est accepté sans erreur alors il y a un problème.
Une fois créés, ces tests peuvent être lancés de manière automatisée. Cela est beaucoup plus rapide car un analyseur logiciel effectue les vérifications bien plus efficacement qu'un humain et sans risque de distraction ou de fatigue. Ils peuvent également être lancés des dizaines de fois par jour sans lassitude ni problème d'horaires.
Une application reste rarement figée au cours de sa vie. Elle évolue régulièrement au gré des besoins de ses utilisateurs. Grâce aux tests automatisés, ce changement n'est plus vécu comme un stress. Les équipes sont plus sereines car sûres de la qualité du code de l'application.
Il existe deux types de modifications :
- la réécriture qui consiste à modifier le comportement d'une partie de l'application. Les tests doivent être mis à jour dans ce cas ;
- la refactorisation qui consiste à réorganiser et optimiser le fonctionnement d'une application sans en changer le comportement. Les tests doivent continuer de passer. Ainsi, si les tests passent toujours, le développeur est assuré de ne pas avoir cassé l'application en la modifiant.
Dans le monde PHP, il existe deux grands frameworks de tests unitaires : SimpleTest et PHPUnit. Conceptuellement proches, ces deux frameworks se distinguent par certaines fonctionnalités spécifiques comme un navigateur virtuel pour SimpleTest ou une extension permettant de tester facilement le code lié à une base de données pour PHPUnit.
Nom | Editeur | Tests unitaires | Tests IHM |
---|---|---|---|
SimpleTest | Open Source | Oui | Oui |
PHPUnit | Open Source | Oui | Oui (avec Selenium) |
Il n'existe pas à l'heure actuelle d'outils spécifiques à PHP pour les tests fonctionnels. Cependant, les tests fonctionnels étant peu liés aux aspects
techniques, il est parfaitement possible d'utiliser des outils venus d'autres univers.
Nom | Editeur |
---|---|
Fitnesse | Open Source |
GreenPepper | Open Source |
Les tests, quelque soit leur nature, concourent à la qualité de code et à la tranquillité d'esprit des équipes.
Il est important de s'assurer de la qualité du code d'une application car sinon viendra un jour où il sera impossible de faire les modifications attendues et il faudra entièrement réécrire l'application pour repartir sur des bases saines. Cette pratique est au coeur des méthodes agiles de développement qui en font un élément crucial de leurs préceptes.
IV-2. Intégration continue▲
La pratique des tests ajoute une étape dans le processus de développement : il faut faire tourner les tests unitaires avant de progresser, soit vers d'autres versions, soit vers le déploiement. A chaque fois, il faut mettre en place le système de tests, les faire tourner et réagir en fonction des retours d'erreurs.
Or, l'historique des résultats de tests unitaires est une source d'information intéressante : quels types d'erreurs reviennent le plus souvent ? Quelles fonctionnalités sont les plus sensibles à des modifications ? Quand se produisent les commits les plus erronés ? Comment le projet est-il surveillé durant l'absence du chef de projet ?
Une réponse à ces questions est fournie par l'eXtrême Programming : elle tend à fluidifier au maximum la transition depuis le développement jusqu'au déploiement. Pour cela, elle automatise le déploiement et l'exécution des tests unitaires.
Un serveur d'intégration continue est mis en place, sous la forme d'un outil fonctionnant en permanence. Régulièrement et indépendamment de l'effort de programmation, il va extraire le code PHP du dépôt de code, le déployer sur un serveur de test, puis collecter les résultats et les informations obtenues à chaque étape. Le tout est publié sous forme de graphiques d'évolution.
Par exemple, avec phpUnderControl, les indicateurs suivants sont rapportés :
- Métriques sur le code PHP (complexité, couplage, etc.) ;
- Vérification des conventions de programmation ;
- Nombre de tests unitaires présents ;
- Couverture de code ;
- Résultats des tests ;
- Génération de la documentation PHPDoc.
Il devient alors possible de suivre des indicateurs de qualité de l'ensemble de l'application. Cela sert à nombre d'intervenants :
- Le chef de projet, qui a un rapport régulier de l'état du projet ;
- Les membres de l'équipe, qui suivent le travail du groupe. Ils ont aussi une image immédiate de leur impact sur le projet : un commit de code non compilable se voit immédiatement dans les statistiques du projet ;
- Les clients et utilisateurs, qui ont plus de détails sur les rouages internes du projet. Cela donne des descriptions chiffrées sur le fonctionnement interne, et non plus des évaluations qualitatives.
Dans la pratique, l'intégration continue tend à réduire le temps de publication des applications, à réduire les problèmes d'intégration, et généralement à donner plus de confiance dans le processus de déploiement.
Cette approche permet aussi de s'affranchir du chef de projet comme ressource limitante dans les projets de moyenne à grande taille : les tests unitaires sont effectués indépendamment de sa charge de travail.
L'intégration requiert une mise en place significative. Il est plus facile de la faire évoluer au cours du projet, que de l'ajouter lorsque le projet est déjà bien avancé : en effet, le faisceau de contraintes qu'elle applique aux pratiques de codage est important, et faire rentrer de bonnes habitudes dans ces pratiques est un défi important.
PHP utilise beaucoup les outils écrits pour d'autres technologies comme serveur d'intégration continue. Récemment, des projets spécifiques à PHP, comme phpUnderControl et Xinc, ont vu le jour et gagnent à adopter des démarches et indicateurs spécifiques à PHP.
Outil | Description |
---|---|
Cruise Control | Serveur d'intégration continue écrit en Java |
PhpUnderControl | Adaptation du serveur précédent aux outils PHP |
Hudson | Serveur d'intégration continue, avec modules spécialisé en Java mais utilisable avec PHP |
Maven | Java Server d'intégration continue, édité par la fondation Apache |
Xinc | Premier serveur d'intégration continue en PHP |
L'intégration continue consiste à rendre l'opération de test permanente. L'adjectif continu peut aussi s'appliquer aux autres aspects d'un projet
logiciel.
La conception continue consiste à faire évoluer les documents de spécifications au fur et à mesure que les spécifications fonctionnelles sont converties en termes techniques. Cette approche est encore expérimentale, car elle perturbe beaucoup le travail de développement.
Le déploiement continue consiste à pousser en production les modifications, dès qu'elles sont archivées dans le dépôt de source. Le processus applique immédiatement les tests, et si cela fonctionne, il produit une nouvelle version.
IV-3. Déploiement automatique▲
Le déploiement d'application est une tâche trop négligée. Souvent, elle n'est même pas explicitement prévue. La tâche elle-même est suffisamment complexe et ponctuelle pour qu'il soit naturel de confier cela à un être humain, et non pas une machine. Chaque nouvelle version entraîne des modifications particulières, sur différents aspects du logiciel (données, configurations, code PHP, structure des bases de données, etc.) qui rendent la programmation difficile à planifier et tester.
Le déploiement se fait donc le plus souvent manuellement. Il s'agit d'exporter l'application depuis le dépôt de code, de copier ses fichiers vers un serveur puis de passer les scripts de mise à jour de la base données.
Parfois, cela s'accompagne également de vidage de cache, de mise à jour de fichiers de configuration voire d'adaptation de la structure des répertoires. Le processus est long et s'allonge rapidement, pour de multiples raisons : nombre de serveurs croissant, nombre de technologies croissant, nombre de systèmes de protections croissant, etc.
Dans la pratique, il est aisé d'oublier une étape, d'en modifier l'ordre. C'est alors la catastrophe, qui demande une réparation immédiate et impérieuse, avec à la clé, une nuit blanche. De toutes ces difficultés résulte souvent un espacement des déploiements. Les mises en recette sont moins fréquentes les retours des testeurs sont donc moins rapides et il y a un ralentissement général du processus de développement.
Le coup de grâce survient quand un problème est détecté et qu'il faut mettre immédiatement en production le correctif. Est-ce que le remède n'est pas pire que le mal ?
L'automatisation est la clé de la réussite en matière de déploiement. Un processus automatisé n'oubliera pas une étape parce qu'il aura été interrompu par un mail ou un appel téléphonique. Il sera aussi capable de faire la publication de la même manière sur tous les serveurs qu'il doit gérer, et même, assurer l'installation sur les nouveaux qui sont ajoutés à la plate-forme : ce n'est plus le travail du développeur, mais de l'administrateur.
Ce processus pourra souvent être testé unitairement ou fonctionnellement afin de garantir son fonctionnement.
Le déploiement sur de multiples serveurs pourra donc se faire en parallèle en ne mobilisant qu'une personne ce qui permet un gain de temps et de ressources important. Ainsi, plusieurs personnes peuvent être formées afin de s'assurer que ce savoir-faire sera disponible à tout moment dans la société.
L'automatisation permet aussi de programmer le retour en arrière vers une version précédente. Ainsi, si le processus échoue en cours de route, il devient alors possible de demander à revenir à une version fonctionnelle du site, sans intervention humaine. C'est un gain de sécurité appréciable pour le déploiement.
Enfin, le système de déploiement automatique permet aussi d'installer des versions de tests sur différentes plate-forme cachées, pour faire tourner des tests unitaires, ou mettre à disposition rapidement des versions aux clients internes.
Il existe de nombreuses manières d'automatiser le déploiement d'une application PHP. Le moyen le plus simple est d'utiliser PHP lui-même : ce dernier est capable de fonctionner en ligne de commande et de s'interfacer virtuellement avec toutes les technologies qu'il va lui-même utiliser sur la plate-forme Web. C'est donc une solution valide et accessible, quoiqu'un peu laborieuse à utiliser.
Un autre moyen très simple est d'écrire un script Shell contenant les commandes que nous aurions passé manuellement. Le gain fonctionnel est nul, mais nous sommes assurés que les commandes seront passées en totalité et dans le bon ordre. La sortie écran permettra également de s'assurer du succès de l'opération.
Pour procéder de manière plus professionelle, il est recommandé d'utiliser un outil d'automatisation de tâches dédié à cela. Les tâches à confier à un outil de déploiement sont des actions simples comme :
- Afficher un message ;
- Manipuler des fichiers ;
- Exporter du code depuis un dépôt Subversion ;
- Exécuter une commande en local ou via SSH ;
- Effectuer une transformation XSLT ;
- Créer une archive.
De nombreuses autres tâches sont disponibles par défaut et il est simple d'en créer de nouvelles.
Dans la liste ci-dessous, PEAR dispose d'un avantage de taille : il fournit une architecture pour la diffusion des paquets sur le réseau, à l'aide d'un système de serveur central. Un paquet PEAR est similaire à une archive mais il est possible d'y ajouter des dépendances vers d'autres paquets ainsi qu'un script qui sera exécuté après l'installation. Dans le cas d'un déploiement simple, par exemple pour une librairie ou une application peu complexe, ce moyen de distribution peut être très pratique.
Outils | Origine |
---|---|
Ant | L'outil le plus répandu pour les installations automatiques. Il se commande en XML, et fonctionne sans problème avec PHP. |
Phing | La version PHP de l'outil précédent. |
Capistrano | L'outil de référence pour Ruby. |
Fredistrano | La version totalement PHP de l'outil précédent. |
PEAR | Disponible avec toutes les installations PHP. Il est possible de créer aisément un canal de diffusion PEAR, interne ou public. |
PHP | Très souple, pas guidant. |
Phar | Archives PHP, auto exécutables. |
Depuis la version 5.3, l'extension Phar est disponible par défaut dans PHP. Elle permet de créer des archives à la manière des fichiers Jar de java, ou
War de J2EE. Les fichiers contenus dans une archive Phar peuvent être manipulés par PHP sans avoir besoin de la décompresser au préalable.
Au final, la vitesse et la facilité de déploiement pousse les développeurs à publier rapidement : Flickr indique qu'il publie son site jusqu'à soixante fois par semaine. Avec une publication rapide, on peut publier rapidement des correctifs importants, ou tester des micro-améliorations sans avoir à dépendre d'un processus plus important. Cela améliore considérablement la stabilité perçue de l'application. Et la répétition de l'installation améliore aussi la confiance des développeurs dans leur application.
Dans le cas de montée en charge extrême, le déploiement automatique est une arme redoutable pour pouvoir assurer des installations rapides et propres, même dans un environnement sous forte pression.
IV-4. Analyse statique▲
La vie d'un script PHP se décompose en 2 espaces distincts : l'écriture et l'exécution. Entre les deux, il y a l'analyseur PHP, qui réalise la compilation et l'exécution du code initial, lors de la sollicitation des internautes.
L'analyse statique a pour objectif d'étudier PHP avant la compilation, pour détecter très tôt des situations à problèmes.
L'analyse s'appuie sur le code PHP avant exécution. Elle exploite des motifs de code pour reconnaître des situations : par exemple, une instruction echo ou print, appliquée à une concaténation des variables superglobales est un signe fort d'injection HTML.
L'analyse statique permet d'obtenir des résultats avant exécution, et donc sans risque pour les données ou la plate-forme de production.
L'analyse statique doit être automatisée pour pouvoir être exécutée aussi souvent que possible, et notamment tout au long du développement. De cette manière, les erreurs sont traquées lorsque le code est peu volumineux, et les incréments faciles à corriger au fur et à mesure.
L'automatisation donne aussi la maîtrise du processus de vérification aux développeurs et aux chefs de projets. Les premiers peuvent valider leur code eux-mêmes, sans passer trop de temps à implémenter les règles d'analyse ou à analyser le code PHP. C'est toujours une bonne idée que de ne pas être juge et partie dans ce type de surveillance. Pour les chefs de projets, le volume de code à analyser, dans l'absolu ou simplement après une période d'absence, a finalement peu d'impact sur les erreurs trouvées.
L'analyse statique doit être complétée par l'analyse dynamique, à l'aide de profileurs. En effet, le langage PHP est dynamique par essence : à l'exécution, il est possible de définir des classes, fonctions, variables et leur type, d'inclure ou exécuter du code PHP : tout cela modifie considérablement le fonctionnement du script si des valeurs mal intentionnées ou erronées sont introduites.
L'analyse statique doit donc affronter l'ensemble des cas possibles, alors que l'exécution d'un script donne plutôt l'aperçu du comportement lorsque des valeurs concrètes sont affectées.
Il existe quelques outils pour mesurer divers indicateurs dans le code PHP.
Outil | Objet |
---|---|
PHP_CodeSniffer | Analyseur de code PHP, détecteur de motifs |
Pixy | Analyseur d'injections HTML et SQL |
Phpcpd | Détecteur de copier-coller dans le code |
PHP_Depend | Compile différents indicateurs |
Phploc | Compteur de lignes de code PHP |
SLOCCount | Compteur de lignes de code supportant une multitude de langages dont PHP |
L'analyse statique de PHP en est à ses débuts. Il existe peu d'outils et la majorité des indicateurs sont issus des plates-formes concurrentes. Les
spécificités de PHP, tels qu'une grande sensibilité aux inclusions de fichiers, sont rarement prises en compte pour des concepts issus des
développements pour le bureau. Il reste donc beaucoup d'expérience à aller chercher sur le terrain.
L'analyse statique pourra notamment aller chercher des jalons naturels dans le code, telles que les structures de classes, ou fonctions, afin d'identifier les dérives dans la programmation, ou la divergence avec la conception. Par exemple, des fonctions en trop, des fonctions qui ne suivent pas les conventions de nommage, ou encore des fonctions qui ne sont pas utilisées sont autant d'informations qui doivent être gérées dans une politique générale du projet, et qui sont rarement maîtrisées, faute d'outils pour faire un rapport accessible aux intervenants du projet qui ne font pas de la programmation.
IV-5. Outils de conception▲
La conception est souvent l'étape oubliée dans les projets en PHP : entre des spécifications souvent récurrentes, et des fonctionnalités déjà prêtes, il est trop facile de passer outre cette phase critique des projets.
Au delà de ces problèmes, les projets menés à 100 à l'heure ont tendance à repousser progressivement la conception au rang de tâches administratives sans valeur ajoutée. La conception technique, issue des spécifications, est toujours en retard sur cette dernière, quand bien même elle existe. Il y a ainsi un cercle vicieux qui s'accélère dans la vie d'un projet : moins de conception, donc moins de visibilité dans la programmation, donc plus de bogues, donc moins de temps à consacrer à des tâches considérées comme importantes, mais trop consommatrices de temps.
L'approche du terrain est alors de faire et d'évaluer la situation après la réalisation. Cette approche est aussi issue d'assujettissement des priorités techniques aux délais de réalisation, et de la même façon conduisent à une perte de contrôle.
Bien que l'idée que la conception ne sert qu'à perdre du temps soit bien répandue, force est de reconnaître que PHP dispose de quelques outils pour faire le pont entre la conception et la production de code.
IV-5-1. UML▲
Avec l'avènement de l'objet en PHP, il est devenu plus efficace d'utiliser des éditeurs UML pour mettre en place les classes. Si toutes les formes de communication du langage de spécifications UML ne sont pas encore maîtrisée en PHP, le langage est supporté par nombre d'entre eux :
Outil | Objet |
---|---|
ArgoUML | Produit du code PHP à partir d'un diagramme de classe, Open Source |
StarUML | Open Source, uniquement sur Windows |
Rational Rose | Très puissant, PHP supporté par module externe |
BOUML | Éditeur très dépouillé, possibilité d'extensions |
Les générateurs de diagramme permettent donc de gérer l'ensemble des classes dans des diagrammes de classes. On a une vue d'ensemble des
classes et des méthodes, de leur relation, sans s'embarrasser des détails d'implémentation. Quand le projet commence à prendre de la taille, c'est
un point crucial.
Une fois les diagrammes de classe établis, il est facile d'obtenir du code prêt à l'emploi, sans perdre de temps à recopier les noms des méthodes. ArgoUML produit aussi la documentation au format PHPDoc : au final, on peut donc préparer le travail de programmation dans un seul éditeur et produire automatiquement plusieurs objets qui feront gagner du temps au développement. Avantage encore, ArgoUML est capable de reprendre le code déjà produit, si jamais la conception change.
Il manque toutefois un outil de retroingénierie, qui partirait du code existant pour le transformer en diagrammes UML.
IV-5-2. Modèles de données▲
De la même façon, les générateurs de modèle de données apportent un gain de maîtrise important.
Outil | |
---|---|
PowerArchitect | Open Source, interfacé avec une large variété de bases, et disponibilité d'outils de manipulations de données |
MySQL WorkBench | Spécialisé pour MySQL, intensément développé par l'éditeur (MySQL AB), multiplateforme |
Toad | Très répandu dans les grands comptes, mais payant et propriétaire. |
IV-5-3. ORM▲
Les ORM sont aussi un domaine où les outils de génération de code peuvent faire gagner du temps. Il s'agit des Object-Relationnal Mappings, c'est à dire des correspondances entre les classes PHP et les tables SQL. Il existe en effet une similitude entre les deux qui rend naturel un rapprochement : un nom de colonne devient une propriété d'un objet, et une table est associée à une classe.
Ce type d'approche est efficace si les objets métiers sont représentés par des tables simples en base, ce qui est souvent le cas dans les applications Web. On en vient donc à produire souvent les mêmes fonctionnalités de correspondances, sans plus-value.
Il y a trois approches :
- l'ORM se base sur la base de données et en déduit des classes PHP (Propel) ;
- L'ORM lit un fichier de configuration indépendant et en déduit les classes PHP ;
- L'ORM adapte la base de données aux classes PHP produites.
C'est surtout les deux premières approches qui sont utilisées, car la base de données reste la chasse gardée des administrateurs qui n'autorisent pas facilement aux scripts PHP de modifier les modèles. De plus, les clients comprennent bien cette notion de modèle de données, et c'est aussi un moyen de discussion avec eux, alors que les classes PHP sont plus difficiles à lire ou à comprendre.
La troisième approche est plutôt adaptée aux entrepôts clé-valeur, de type CouchDB.
Outil | Méthode |
---|---|
Doctrine | Extrait les objets d'un fichier de description |
Propel | Extrait les objets de la base de données |
EzPDO | Extrait les objets du code PHP |
CouchDB | Pas besoin d'ORM |
IV-5-4. Documentation technique▲
La documentation technique est la documentation interne du projet, elle est destinée aux développeurs. La plupart du temps, ce type de documentation est totalement absent d'un projet, ce qui handicape malheureusement beaucoup la prise en main du projet par un nouveau collaborateur, ou par un prestataire externe.
La documentation technique doit être de deux types : de référence, et globale.
La documentation de référence est le catalogue de toutes les classes, méthodes et fonctions qui ont été mises en place dans le code. La pratique recommandée ici est d'utiliser la syntaxe JavaDoc, directement dans le code. Lorsque cette documentation est présente, plusieurs outils de documentation sont capables d'analyser le contenu et de produire un ouvrage avec toutes les informations, ainsi que les indexes croisés adaptés pour naviguer rapidement dans l'ouvrage.
La documentation de référence doit être complétée par une présentation globale de l'architecture de l'application. En effet, la référence tend à donner une vue morcelée de l'application, en se concentrant sur les briques élémentaires. Il faut donc compléter la vue par une description littérale du fonctionnement de l'application, afin de placer les grosses masses.
Outil | Description |
---|---|
PhpDocumentor | Outil de référence dans le monde PHP pour la génération de documentation technique au format JavaDoc |
Les outils de conception permettent d'anticiper de nombreux problèmes et de donner des guides importants lors de la phase de développement. UML
est un standard en PHP, comme dans le reste du monde informatique, et à l'heure actuelle, seuls les diagrammes de classes sont réellement
exploités.
Les informations de conceptions aident aussi à suivre la qualité du projet, en fournissant un référentiel par rapport auquel se comparer pour savoir si la programmation suit le fil du projet. C'est aussi un outil important pour la planification du projet : à partir du diagramme UML, on peut découper les classes en tâches, vérifier que l'ordre de développement est cohérent pour pouvoir les tester ou les imbriquer et obtenir un premier rendu visible. Cela a donc un impact direct sur la gestion du chef de projet, et la mesure du délai de livraison.
Le besoin de documentation technique s'atrophie de lui-même lorsque la conception prend le relais : à l'aide de ces spécifications, il est possible de produire le code et la documentation associée, pour préparer le travail des développeurs, et les soulager par la même de cette tâche.
IV-6. Méthodes de programmation▲
Convertir les besoins fonctionnels d'un client en spécifications techniques est un défi. De nombreuses connaissances à la fois métier et techniques sont nécessaires. Pourtant, les méthodes traditionnelles de développement (modèle en cascade, cycle en V, etc.) prônent la rédaction de spécifications fonctionnelles complètes avant de commencer la programmation. Celles-ci doivent décrire dans le détail chaque aspect de l'application à créer et replacer chaque fonctionnalité dans la globalité de l'application. La rédaction nécessite une forte capacité d'abstraction et beaucoup de rigueur pour n'oublier aucun aspect du besoin. Des mois sont souvent nécessaires pour aboutir au document final.
A partir de là, la programmation commence. Suivant sa durée, cela produit l'effet tunnel : le client a livré ses spécifications, mais n'obtient aucun résultat concret avant la phase de recette. Le développement progresse, mais comme l'application n'est pas fonctionnelle, il n'y a rien à voir, ni a évaluer. Au bout du tunnel, le client attend la surprise : elle sera bonne ou mauvaise. Outre les raisons évidentes d'exécution et de compétences, d'autres raisons peuvent avoir un impact important lors de la recette : si le développement est trop long, il arrive tout simplement que le besoin évolue durant le développement.
Les applications sont de plus en plus complexes, de plus en plus longues, et les besoins des clients sont de moins en moins précis : pour conserver le lien entre les utilisateurs et les développeurs, de nouvelles approches méthodologiques ont émergé.
Des méthodes plus réactives ont été inventées, avec notamment des cycles de développement plus courts. Elles sont rassemblées sous le nom de méthodes agiles, dont les principaux représentants sont Scrum et l'eXtreme Programming (XP). Ces deux méthodes abordent les choses sous deux angles différents et, loin de se concurrencer, ont plutôt tendance à se compléter.
Ces méthodes sont destinées à des équipes de petites tailles.
Sur des projets de grande envergure, il est parfois possible de scinder le projet en plusieurs petites équipes, avec une équipe de coordination.
IV-6-1. Scrum▲
Scrum a été développée au début des années 1990. Cette méthode est adaptée à la gestion de projets de tout type et pas seulement informatiques. Son fonctionnement se base sur une terminologie précise. Scrum définit trois rôles principaux :
- le directeur de produit : il est le représentant des clients et utilisateurs. C'est lui qui définit les priorités fonctionnelles et qui oriente le projet ;
- le ScrumMaster : il est chargé de protéger l'équipe de tous les éléments extérieurs et de résoudre ses problèmes non techniques. Il veille également au respects des valeurs de Scrum ;
- l'équipe : ce sont les développeurs, graphistes, intégrateurs et tout autre poste technique du projet. Il n'y a pas de hiérarchie au sein de l'équipe et elle est autogérée. C'est-à-dire que ses membres s'organisent à leur guise pour le bien du projet.
Des intervenants peuvent également s'intégrer au projet de façon plus ponctuelle. Ils souhaitent suivre le projet sans y participer directement.
Au lancement du projet, l'équipe découpe le besoin fonctionnel en tâches auxquelles le directeur de produit attribut un certain nombre de points. Ces points n'ont pas d'unité. Leur valeur est relative à la vitesse de travail de l'équipe. La planification est itérative dans Scrum. Chaque itération est appelée sprint et dure entre 2 et 4 semaines. Au début du projet, l'équipe estime combien de points elle peut réaliser par sprint.
Au début de chaque sprint, le directeur de produit indique quelles tâches il souhaite voir réaliser pendant celui-ci en tenant compte des points associés à chaque tâche afin de ne pas dépasser la capacité de travail de l'équipe. En fin de sprint, on calcule le nombre de points réalisés par l'équipe et on en calcule la moyenne par sprint. C'est ce qu'on appelle la vélocité. Elle sert à estimer de manière assez réaliste la capacité de travail de l'équipe.
L'application est livrée au directeur de produit à chaque fin de sprint pour qu'il puisse la tester. A ce stade, elle est incomplète en termes de fonctionnalités, mais elle est normalement utilisable. Le directeur de produit a donc très régulièrement une version testable de l'application. Il peut ainsi signaler très vite d'éventuels bogues ou écarts fonctionnels.
Une autre conséquence de ce fonctionnement est de laisser au client la possibilité de se tromper. C'est-à-dire qu'il peut s'apercevoir en testant l'application que le comportement demandé n'est pas adéquat. Il pourra donc demander à le rectifier dans l'itération suivante. Comme le client se rend compte très tôt des problèmes, cela réduit les coûts de correction et ne risque pas de faire échouer le projet in fine.
A chaque fin de sprint, le client peut décider que l'application lui convient et que le niveau de fonctionnalité attendu est atteint, même s'il reste des tâches à accomplir. En effet, il peut décider à tout moment de la pertinence des points. Quand il n'y a plus de points, le projet s'arrête.
La méthode Scrum ne couvre aucune technique d'ingénierie logicielle. Son utilisation pour le développement d'une application informatique nécessite donc de lui adjoindre une méthode complémentaire comme l' eXtreme Programming.
IV-6-2. eXtreme Programming▲
L'eXtreme Programming (XP) est un ensemble de valeurs et de pratiques qui visent à faciliter les développements informatiques. Cette méthode reprend des principes existants, mais les pousse à l'extrême, d'où son nom.
Les valeurs de l'eXtreme Programming sont :
- La communication ;
- La simplicité ;
- Le feedback ;
- Le courage ;
- Le respect.
Ces valeurs vont dans le sens d'un développement apaisé au sein d'une équipe ouverte et intelligente. Elles se déclinent en treize pratiques qui se renforcent mutuellement :
- Client sur site : pour assurer une grande réactivité le client doit idéalement être sur le site où travaille l'équipe. Si ce n'est pas possible, quelqu'un peut le représenter ;
- Jeu du Planning : le client crée des scénarios pour les fonctionnalités qu'il souhaite obtenir. L'équipe évalue le temps nécessaire pour les implémenter. Le client sélectionne ensuite les scénarios en fonction des priorités et du temps disponible ;
- Intégration continue : afin de détecter au plus tôt d'éventuels défaut, les nouveaux développements sont intégrés à l'application très régulièrement ;
- Petites livraisons : les livraisons doivent être les plus fréquentes possible ;
- Rythme soutenable : le développement est un exercice intellectuel créatif qui demande d'être en forme. On veillera donc à garantir un rythme de travail soutenable et notamment à ne pas faire faire d'heures supplémentaires à l'équipe deux semaines d'affilée ;
- Tests fonctionnels : à partir des scénarios définis par le client, l'équipe crée des procédures de test qui permettent de vérifier l'avancement du développement ;
- Tests unitaires : l'équipe rédige au fur et à mesure des tests validant le comportement technique de l'application ;
- Conception simple : cette méthode encourage la simplicité de conception afin de ne pas introduire de complexité inutile dans l'application ;
- Utilisation de métaphores : on évite le jargon technique ou métier car l'équipe et le client se comprennent beaucoup mieux en parlant un langage simple ;
- Remaniement du code : amélioration régulière de la qualité du code sans en modifier le comportement. Cette valeur est intimement liée aux tests unitaires et fonctionnels ;
- Responsabilité collective du code : l'ensemble de l'équipe est responsable du code. Personne n'a la propriété exclusive d'une partie de l'application ;
- Convention de programmation : afin de faciliter le travail collaboratif, il est important de définir des règles communes ;
- Programmation en binome : les développeurs travaillent à deux sur un même poste. L'un tape le code tandis que l'autre dialogue avec lui afin de concevoir à deux le code. Les binomes changent régulièrement pour faciliter la communication et le partage des connaissances au sein de l'équipe.
Certaines des pratiques de l'eXtreme Programming peuvent sembler radicales, mais elles ne sont souvent que du bon sens poussé au maximum.
De prime abord, les méthodes agiles sont déroutantes car elles remettent en cause de nombreuses habitudes : elles demandent même un certain courage de la part des développeurs. Il faut accepter de livrer le fruit de son travail et donc une partie de soi au regard et à l'appréciation des autres. Cela peut être difficile, mais cela pousse également à l'excellence.
Les méthodes agiles ne sont pas forcément adaptées à tous les projets, ni à toutes les entreprises. Certaines pratiques peuvent rendre difficile voire impossible leur adoption comme :
- un blocage culturel devant l'absence de hiérarchie et l'autonomie accordée à l'équipe ;
- des équipes de taille trop importante ;
- un client peu disponible ;
- la résistance au changement.
Enfin, le principe même des méthodes agiles rentre souvent en conflit avec l'aspect commercial d'un projet. Comment chiffrer un projet dont on ne connaît pas précisément le périmètre fonctionnel final ? La facturation en mode forfait est peu adaptée à ce genre de méthode. Il faut que le client accepte un fonctionnement au temps passé, au prix d'une moindre visibilité sur le budget final.
IV-7. Maîtrise de la qualité du code▲
Trop souvent, la qualité du code est vérifiée après programmation : la raison avancée pour cela est qu'il n'y a pas moyen de faire de vérification tant que la programmation n'est pas faite. La solution consiste alors à faire appel à un expert externe au projet, pour relire le code, identifier des points de non-qualité et suggérer des corrections. Ces dernières touchent parfois à la conception, parfois au code, ou encore à des pratiques de la programmation : la charge de correction fait alors qu'il est alors trop tard pour les appliquer.
La première réaction est alors de relancer l'audit dès la prochaine étape importante du projet : nouvelle version majeure, nouvel ajout important, nouvelle fonctionnalité stratégique. Le rythme est alors pris mais les interventions sont toujours en retard. Il faut prendre le problème beaucoup plus en amont pour pouvoir assurer une qualité continue et prévisible.
Pour faire progresser la qualité de la programmation, deux ingrédients essentiels sont nécessaires :
- Une référence, qui porte le nom de "Mantras PHP" ;
- Un processus de surveillance, qui est baptisé "audits croisés".
Les mantras PHP sont une liste courte de recommandations de qualité à appliquer au code PHP lors de la programmation. Ces recommandations peuvent être de plusieurs types, et doivent être entre 5 et 7 au maximum.
L'objectif est de proposer un référentiel simple et facile à mémoriser, pour que chaque développeur les connaisse bien. L'analogie est faite avec les mantras (ou le chapelet) où les mêmes litanies sont répétées : ici, le développeur doit les ressasser en même temps qu'il produit du code PHP. Les mantras PHP sont différents des guides de références : ces derniers sont trop littéraires ou trop volumineux pour être applicables facilement durant la production de code.
Voici quelques idées de mantras PHP :
- Toujours valider les données en entrées;
- Toujours protéger les données en sortie ;
- Vérifier l'application des conventions de programmation ;
- Utiliser un dossier hors Web ;
- Éviter de lire plus de 100 lignes dans la base de données;
- Ne pas mettre de tableaux dans les sessions ;
- Éviter les "ereg".
Idéalement, cette liste doit avoir été créée avec les développeurs, afin de produire un référentiel auquel ils pourront s'identifier facilement et qu'ils comprendront aisément. Le mieux est de rédiger cette liste lors d'une réunion de remue-méninges commun, puis de publier cette liste de manière très visible : fond d'écran, impression à coté de l'écran, ou à la machine à café.
Une fois bien connus des développeurs, les mantras PHP sont alors la référence à utiliser pour évaluer la qualité de chaque production de code. On peut s'en servir dans un audit croisé, ou revue de code, pour vérifier que les mantras PHP sont bien appliqués.
Les audits croisés consistent à organiser les développeurs en binomes (ou éventuellement en trinomes) : avant chaque archivage de code dans le dépôt, le binome d'un développeur doit relire le code qui va être publié, et s'assurer que les PHP Mantras ont bien été appliqués. Il doit alors identifier les points à corriger, et les faire modifier par l'auteur initial.
Les audits croisés ont de multiples avantages :
- Le chef de projet ou l'expert ne sont pas une ressource limitante, puisque l'audit ne passe pas forcément par eux. Ils peuvent évidemment apporter un regard supplémentaire et différent aux audits ;
- Les audits croisés dépassent les cloisonnements des projets : tant qu'un développeur connaît suffisamment PHP, il peut être mis en binome avec un autre. Cela permet de créer un espace commun et entièrement technique et d'éviter la fragmentation des connaissances techniques ;
- Le rythme des audits peut être facilement adapté à celui du projet : en l'absence de développeurs, les audits peuvent être réorganisés pour s'assurer que le code a bien été relu.
- L'effet principal de cet organisation est de montrer clairement les objectifs de qualité et de rappeler aux développeurs qu'une vérification sera effectuée inévitablement ;
- Il est recommandé de mettre en binome un développeur sénior et un développeur junior : le premier sera mieux capable d'assimiler les suggestions originales d'un nouveau au projet et de guider le nouveau dans les mantras locales, sans le noyer dans trop de règles.
Il n'existe actuellement aucune référence de mantras PHP. Toutefois, la bibliographie autour de ces sujets propose suffisamment de recommandations et les développeurs disposent de suffisamment d'expérience pour savoir être force de proposition.
Pour les audits croisés, il est apparu récemment des outils de revue collaborative : l'objectif est de fournir un dépôt central pour relire le code, l'annoter, et prévenir directement l'auteur des portions de code visée. Ce type d'outil doit pouvoir s'interfacer avec les dépôts de code et prendre en compte les différentes versions des fichiers.
Plusieurs outils existent actuellement :
Outil | Avantage |
---|---|
Groogle | Open Source, écrit en PHP et pour PHP |
Review Board | Simple et universel, écrit en Python |
Rietveld | Écrit par Google, fonctionne sur Google Apps |
SmartBear | Logiciel commercial |
Le principe de base des audits croisés est d'accélérer les audits qui se font généralement à grands frais et trop rarement. On arrive aussi à remonter
le cycle de la vie du projet en plaçant la création des mantras PHP dès le début du projet, voire même avant la conception de l'application.
Par la simple application de la discipline du code, on élève nettement la conscience dès l'écriture du code et on obtient en bout de compte un niveau de qualité supérieur. Au passage, les équipes gagnent en cohésion et en niveau de collaboration.
IV-8. Implication des utilisateurs▲
Le volume des interactions avec les utilisateurs est un aspect primordial dans les projets Web : cela demande généralement du temps, du temps et encore du temps. La notion d'utilisateur couvre plusieurs personnes :
- Les clients, qui expriment leurs besoins ;
- Les vérificateurs, qui identifient un dysfonctionnement ;
- Les utilisateurs, qui souhaitent simplement tirer profit de l'application.
La plupart du temps, ce sont les mêmes personnes qui portent ces mêmes casquettes tout au long du projet. Ils sont à l'origine du projet ou ils fournissent des documents sous le nom de spécifications ; ils sont aussi utilisateurs et demandent des documentations, un suivi assez lâche du projet et remontent des problèmes, que ce soit dans le cadre d'une recette ou d'une utilisation routinière.
En fait, la communication avec les utilisateurs est toujours de même nature, mais comme elle porte des noms différents suivant les phases du projets, elles sont souvent dissociées. Par exemple, un bogue et une spécification sont finalement des prescriptions identiques, mais dans des circonstances différentes : le premier intervient après livraison, et représente une erreur du développeur. Le second est émis au début du projet et ne se compare pas à une réalité de programmation. De la même façon, un souci de documentation engendre un bogue, ou une nouvelle spécification.
Une fois cela remarqué, le volume et la qualité de la communication entre les utilisateurs et l'équipe de développement subit une accélération permanente, dès le début du projet. A ce moment, la communication est bourrue, et se résume souvent à des échanges rapides et oraux. Les spécifications sont parfois livrées à l'avance, et relues par les développeurs, avec parfois l'accompagnement des utilisateurs. Comme le projet est encore à un stade immature, la communication se fait par voie orale, avec un nombre d'intervenants très limité : peu de développeurs, peu d'utilisateurs. C'est le règne des communication instantanées, comme le téléphone ou les messageries instantanées, avec très peu d'archivage.
Puis, avec les premières livraisons, apparaissent les premiers volumes : il faut livrer une documentation pour expliquer comment fonctionne l'application, assurer le suivi des bogues, et augmenter les spécifications de nouveaux éléments ou de rétroactions. Cette phase se fait souvent par mail, pour conserver l'aspect réactif des premières communications : la communion entre les développeurs et les clients est toujours de mise, mais elle a maintenant pris un caractère supplémentaire : elle est traçable. Cela reste valable pour de petites équipes et des dossiers peu complexes.
Les systèmes par mail ou messagerie instantanée restent des outils immédiats et cantonnent les échanges à des relations directes (asynchrones, mais directes). L'étape suivante est de disposer d'un outil de centralisation pour organiser plusieurs nouveaux aspects :
- Différencier les bogues des spécifications (nouvelles ou réitérées) ;
- Capitaliser sur les expériences précédentes ;
- Etablir les priorités des tâches et savoir lesquelles sont terminées, sans interroger les développeurs ;
- Assurer des communications canalisées autour de sujets précis.
C'est à ce stade que les applications de gestion de bogues interviennent. Dans leur version minimale, elles offrent une interface Web où se retrouvent développeurs et utilisateurs, pour décrire des points particuliers de l'application et suivre les modifications qui s'en suivent.
Les versions les plus sophistiquées s'interfacent avec le dépôt de code, pour marquer la version dans laquelle les modifications ont été apportées, et ainsi transmettre automatiquement aux utilisateurs les versions de publications qui supporteront leurs demandes ; elles s'interfacent aussi avec les outils de tests unitaires ou fonctionnels pour faire correspondre une fonctionnalité à un ou plusieurs tests spécifiques. Cette dernière approche pousse à l'utilisation des tests unitaires, et à une capitalisation technique des demandes de corrections.
Outil | Description |
---|---|
Mantis | Probablement l'outil PHP le plus répandu. Un peu austère, mais très adaptable à nombre de situations. |
Jira | Gestion fine des équipes et des utilisateurs ; configuration plus facile. Propriétaire ; interfacable avec GreenPepper ou les outils Atlassian. |
Trac | Testé sur de nombreux projets, même non-PHP. La gestion de bogues y est assez austère. |
Bugzilla | L'outil de gestion des bogues le plus connu dans le monde Open Source. Puissant mais assez spartiate. |
Les aspects documentations sont aussi à prendre en compte : outre les bogues, qui signalent un dysfonctionnement, il est aussi important de
mettre à disposition des utilisateurs des explications écrites. Il y a alors deux types de documentations qui sont produits : les documentations de
référence et les manuels.
Les documentations de référence sont générées automatiquement à partir du code PHP. Elles sont intéressantes uniquement pour les développeurs, et si la prise en main de l'application est simple. En effet, elles présentent en détails les briques disponibles, mais pas la manière de les utiliser.
Les manuels empruntent aux documentations de référence, mais ajoutent des tutoriels, qui assistent les utilisateurs à l'utilisation d'une fonctionnalité. Ils sont clairs et faciles à aborder pour un néophyte, mais cantonnent les experts dans des rails fixés à l'avance.
Dans les deux cas, les manuels sont à produire initialement par les développeurs. En effet, comme ce sont ces derniers qui ont produit l'application, ce sont les mieux placés pour décrire le fonctionnement. L'exemple typique est la documentation PHP, qui est organisée en fichiers XML, produite à la base par les auteurs des fonctionnalités, puis prise en charge par l'équipe de documentation, pour les traductions, les corrections et les ajouts.
Toutefois, c'est un travail laborieux pour les équipes et il est difficile de faire passer le message aux utilisateurs, qui n'évoluent pas dans le même monde. Toujours dans le cas de la documentation, il est souvent répété que les notes de bas de page sont souvent plus utiles aux utilisateurs que la documentation elle-même. En fait, c'est surtout que les utilisateurs se heurtent aux même problèmes et qu'il est crucial d'organiser la communication entre eux, pour profiter d'une expérience qui est totalement étrangère aux développeurs.
Ainsi, à partir de la documentation officielle, il est souvent intéressant d'ouvrir un système d'annotation ou de commentaires, destiné à faire participer la communauté. Au fil de l'augmentation de la taille de la communauté, on peut passer à un niveau de wiki et remettre aux développeurs la charge d'un blog. Le blog sert à communiquer les nouveautés à l'ensemble de la communauté et les utilisateurs prennent le relais.
L'avantage de remettre la documentation aux utilisateurs est qu'ils utilisent une approche très appliquée à un objectif (i.e. « j'utilise strip_tags pour limiter les possibilités d'injection HTML »), alors que la fonctionnalité a été pensée souvent dans un esprit très généraliste («strip_tags permet de retirer les balises d'une chaîne»).
La transition ne se fait pas naturellement et il est important d'avoir une communauté suffisamment large pour susciter des vocations à la gestion de la documentation. Malgré sa qualité reconnue, la documentation PHP n'est gérée que par une petite centaine de personnes, alors qu'il y a plus de 17 traductions et 250 miroirs à travers le monde.
Outil | Description |
---|---|
MediaWiki | Le wiki de Wikipedia, facile à maîtriser, et à faire monter en puissance |
Kmwiki | Un Wiki optimisé pour la gestion des connaissances |
Au delà des wikis, la transition de la documentation vers la communauté peut prendre d'autres formes encore : écriture de tutoriels, livres,
conférences, podcast, vidéocast, rencontres de groupe d'utilisateurs, ouverture d'une API publique, etc.
Les utilisateurs doivent aussi prendre en charge une partie des tests unitaires et fonctionnels : c'est à la fois un outil de communication avec les développeurs, d'assurance qualité et de documentation. Certains projets établissent un pont entre l'application et la documentation à l'aide de tests, ce qui permet de vérifier que la documentation est synchrone avec le développement. De plus, l'approche métier des utilisateurs est cruciale pour que l'application atteigne sa propre utilitée.