Il y a dix ans, je développais des applications sans tests automatisés.
J'écrivais un bout de code, et je testais le résultat à l'aide de mon navigateur, de mon clavier et de ma souris, en cliquant sur des boutons ou des liens et en remplissant des formulaires, afin de voir si j'obtenais le comportement attendu.
Une fois ma tâche terminée, je testais d'autres parties de l'application que celle directement concernée par le code que je venais d'écrire pour vérifier que je n'avais pas créé de régressions.
Sauf que j'étais loin de tester la totalité de l'application, car ce processus était ennuyeux et laborieux, et en conséquence, malgré un développement déjà très normé et industrialisé à l'époque, les régressions étaient nombreuses.
De plus, je passerais sur les bugs que je pouvais laisser passer, notamment lorsque mon code était confronté, en production, a des situations que je n'avais pas prévu.
Maintenant, je travaille d'une tout autre manière.
Je commence par écrire mon test, qui place le code que je vais ensuite écrire dans l'une des situations dans laquelle il sera exécuté en production.
Je lance ensuite mon test en tapant sur une touche de mon clavier, sans quitter mon éditeur, et je rédige ensuite le code qui permet au test de passer au vert
, suivant l'expression consacré, et cela uniquement s'il était au rouge
, toujours suivant l'expression consacré.
Et, pour passer au vert
, j'écris juste la quantité de code nécessaire et suffisante permettant à mon code de passer le test, et de plus très facilement, car bien souvent, l'algorithme a implémenter est en filigrane dans le test.
De plus, à tout moment, je suis capable de détecter les régressions que j'aurais pu éventuellement introduire, toujours en appuyant sur une seule touche de mon clavier et sans quitter mon éditeur.
Aujourd'hui, je code donc plus rapidement, puisque je n'ai pas besoin de basculer en permanence de mon éditeur à mon navigateur, je suis plus productif car le test guide mon développement, et mon code est plus fiable.
Dans ces conditions, je m'interroge donc sur la nature du facteur qui ferait que je couterais plus cher aujourd'hui qu'il y a 10 ans, indépendamment évidemment de l'inflation économique et de l'expérience que j'ai acquise.
J'ajouterais que les méthodes agiles sont plébiscitées actuellement car elles permettent, et c'est démontré, de mieux respecter à la fois les délais et les budgets.
Or, ces méthodes préconisent toutes l'utilisation de tests automatisés lors du développement.
Je ne peux donc m'empêcher de penser que l'écriture de tests a, au minimum, un coût nul, à la fois en terme de temps et d'argent, dans le développement d'un projet.
Car s'ils est indéniable que les tests prennent du temps à écrire, en contrepartie, ils sécurisent le développement, ce qui permet au développeur de se concentrer exclusivement sur la production d'un code fiable et de qualité.
De plus, si d'aventure un bug survient, les tests facilitent sa résolution en facilitant sa reproduction et donc sa localisation, et de plus, ils permettent de s'assurer que la correction n'a pas engendré un autre problème.
Le coût financier qui semble donc à première vue induit par l'écriture des tests est donc largement compensé par les avantages, le confort, pour reprendre le terme d'Amaury, qu'ils apportent au développeur.
Faut-il pour autant tout tester ?
De mon point de vue, les tests ne servent pas uniquement à détecter les régressions et à aider au développement, ils sont également un indicateur de qualité.
Or, qu'est-il possible de déduire, en terme qualitatif, d'un code couvert, par exemple, à 50% par des tests ?
La réponse est absolument rien !
.
Le code couvert par les tests sera certainement de bonne qualité, mais le développeur n'a aucun indicateur lui permettant de jauger la qualité du code non couvert.
Si cela se trouve, ce code non testé est un nid de bugs qui fera tomber l'application lors de la mise en production... ou pas !
Bien souvent, dans ce genre de situation, la justification donnée à l'absence de tests est que le code est simple et évident, et qu'en conséquence, il n'est pas utile de le tester, puisque les bugs, s'il y en avait, seraient immédiatement visibles.
C'est oublier trop rapidement que ce qui peut sembler simple à un développeur ne l'est pas forcément pour un autre développeur et que surtout, l'erreur est humaine.
Je ne compte plus les erreurs induites par une faute de frappe que les tests unitaires ont détecté pour moi dans mon code, et cela même dans des méthodes ou des fonctions composées d'une seule ligne.
Je ne parlerais pas non plus des erreurs provoquées par l'utilisation d'un < à la place d'un ≤, ou d'autres joyeusetés de ce genre.
De plus, c'est également oublier un peu vite que le code d'une application évolue en permanence, et que ce qui semble simple et trivial aujourd'hui ne le sera peut être plus demain, car le besoin aura évolué, et que ce qui était non critique hier doit être extrêmement fiable aujourd'hui.
C'est donc la raison pour laquelle je dis, en bon extrémiste, qu'un maximum de tests doivent être écrit, car c'est le seul moyen d'avoir une indication de la qualité du code tout en pouvant le faire évoluer dans les meilleurs conditions, et cela même si, effectivement, comme le souligne Amaury, les tests ne sont que de la poudre aux yeux
, car ils peuvent laisser passer des bugs.
En effet, le fait que les tests ne soient pas une réponse parfaite au problème des bugs n'est pas une justification valable pour ne pas tester tout ce qui peut l'être, bien au contraire.
Je vais faire une analogie qui pourra sembler osée, mais, tout comme les tests ne sont pas une arme absolue contre les bugs, le préservatif n'est pas une arme absolue contre les MST.
Tout comme les tests peuvent laisser passer des bugs, le préservatif peut se rompre et ainsi permettre l'infection de son porteur.
Pour autant, faut-il ne pas l'utiliser, faut-il renoncer à en promouvoir l'utilisation, ou bien, encore plus stupide, n'utiliser que la moitié d'une capote pour faire des économies ?
Jusqu'à preuve du contraire, tout comme le préservatif est la meilleure arme dont nous disposons actuellement contre les MST, les tests automatisés sont le meilleur outil dont nous disposons pour lutter contre les bugs, et il est donc tout simplement stupide de s'en passer sous prétexte que leur efficacité est relative et non absolue.
De plus, comme nous l'avons vu, les tests apportent un confort réel.
Si Amaury semble reconnaître plus ou moins ce fait, il circonscrit ce confort au seul développeur.
Sauf que dans les faits, ce confort s'étend sur toute la chaîne de production, car chaque maillon sait qu'il peut compter sur la qualité du travail des autres.
Le développeur a confiance dans son code, et les autres membres de son équipe de développement savent qu'ils peuvent avoir confiance en son code.
Le responsable du développement a également confiance, car il dispose d'un indicateur de qualité raisonnablement fiable, mis à jour régulièrement et qu'il peut consulter à tout moment.
Le client dispose quand à lui d'un logiciel fiable, avec peu de bugs, et lorsqu'il y en a, ils sont corrigés définitivement et ne réapparaissent pas.
De part la maîtrise du code et du processus de production qu'ils permettent, les tests automatisés sont donc un vecteur de confiance global à la chaîne de production, et non local au développeur.
Enfin, Amaury dit que la politique du test intégral est une politique de fainéant, car elle évite de réfléchir et simple et facile à mettre en œuvre...
Bullshit !
L'écriture de tests unitaires est tout sauf facile pour un développeur, que ce soit au niveau psychologique ou intellectuel, car il demande de la discipline, du courage et une bonne dose de réflexion.
Il lui faut en effet de la discipline et du courage pour réussir à se mettre de manière récurrente en situation d'échec, pour accepter de se mettre en difficulté en écrivant un test qui lui fera réécrire tout ce qu'il a fait précédemment, ou pour coder un test qui lui montrera concrètement qu'il n'a pas fait correctement son travail.
Il lui faut de plus faire travailler ses méninges pour écrire un test qui a du sens, pour répondre aux questions, et elles peuvent être nombreuses, posées par un test, pour arriver à créer l'environnement d'exécution correspondant, ou tout simplement pour trouver ce qu'il faut tester.
Le développeur qui écrit des tests et qui veut le faire correctement est donc bien loin d'être le fainéant qui pense que les tests lui permettront de masquer sa bêtise décrit par Amaury.
C'est au contraire un technicien organisé et très compétent, qui a le soucis du travail bien fait et qui n'hésite jamais à se remettre en cause, à se poser des questions, à exercer son esprit critique, à affronter la réalité et les problématiques très réelles rencontrées lors du développement d'un logiciel.
L'écriture d'un test unitaire de qualité est à mon sens l'exercice le plus difficile qui soit pour un développeur, surtout lorsqu'il est pratiqué quotidiennement, et il ferait d'ailleurs un excellent test pour un entretien d'embauche, car il demande une somme de connaissances et de qualité intellectuelle et mentale que devrait posséder tout bon programmeur.
Supposons maintenant que tout ce qui précède est un tissus de bêtises, car après tout, tout comme Amaury, je n'ai aucune preuve scientifique
ou budgétaire
de ce que j'avance.
Si produire du code de qualité, c'est à dire exempt de bugs et qui répond aux besoins du client, coûte effectivement plus cher que de faire du code de merde, ne faudrait-il pas, au lieu de ne pas mettre en œuvre les bonnes pratiques qui permettent de faire du bon travail pour des raisons budgétaires, faire comprendre au client que la qualité a un coût, et qu'il a, au final, tout à gagner à mettre la main au porte-monnaie ?
Ou bien faut-il faire de la merde, dépasser les budgets, risquer le procès, mécontenter le client, ternir son image, j'en passe et des meilleurs pour qu'au final personne ne soit satisfait ?
Certes, arriver à faire payer la qualité supposerait une évolution des mentalités à la fois du côté du client et du vendeur, et un certain courage de la part du vendeur, mais je pense que le jeu en vaut largement la chandelle.
Le succès des méthodes agiles montre d'ailleurs qu'il existe des prestataires et des clients capables d'accepter cette démarche, dans laquelle tout le monde est gagnant.
Enfin, depuis le début de ce billet, vous avez peut être remarqué que je parle de tests automatisés ou automatiques, alors qu'Amaury se focalise sur les tests unitaires.
Encore une fois, il oublie trop vite que les tests unitaires ne sont qu'un outils parmi bien d'autres, et qu'ils ne sont qu'une des nombreuses couches composant l'oignon qu'est une usine de développement de qualité.
La couverture intégrale du code par les tests peut s'obtenir de bien des manières, aussi bien à l'aide de tests fonctionnels ou d'interface que de tests unitaires, et je pense de plus que quelque soit leur nature, les tests doivent être joués automatiquement et aussi souvent que possible pour être réellement utiles.
De plus, c'est lorsqu'ils sont utilisés en conjonction avec d'autres outils, tel que l'intégration continue ou la revue de code, qu'ils sont le plus efficaces.
Utilisés seuls, les tests unitaires ont effectivement une utilité moindre, même si elle reste suffisamment significative pour être intéressante, et il est possible que, au niveau financier, le jeu n'en vaille peut être pas la chandelle, mais dans ce cas, plutôt que de rogner sur la qualité en abandonnant les tests, c'est peut être tout une façon de produire et de vendre du code qui est à revoir !
23 réactions
1 De desfrenes - 21/02/2011, 13:33
Dommage de finir avec cette phrase, je pensais avoir trouvé l'article de blog parfait pour persuader.
2 De mageekguy - 21/02/2011, 13:39
@desfrenes : Les tests, on y vas à fond, avec automatisation, intégration continue et le reste de l'arsenal, ou on y va pas.
À mon sens, il n'y a pas de solutions intermédiaires viables, comme j'ai tenté dans le montrer dans le billet, et la conclusion du billet n'a pas d'autres vocations que d'enfoncer encore plus fort le clou !
À la relecture, je suis cependant d'accord avec toi sur le fait que cette conclusion ne reflète pas exactement ma pensée et est sujette à ambiguïté.
Je l'ai donc légèrement modifié en conséquence.
3 De Julien Breux - 21/02/2011, 13:56
En tant que développeur qui estime que la qualité et le respect de l'équipe qui l'entoure est un atout majeur pour l'élévation et la croissance continue d'un projet, je ne peux que plussoyer.
Note : Très belle analogie avec le côté MST.
4 De Julien Breux - 21/02/2011, 13:57
Arf, et pour le coup, meilleur fin
(désolé de double poster...)
5 De Michel Pigassou - 21/02/2011, 14:03
J'ai lu le billet d'Amaury à sa sortie et je pense que ce n'est la conclusion qu'il en a faite n'est pas celle que tu dis. Par exemple, les tests ne sont pas de la poudre aux yeux, mais une partie : il y a toujours du superflu, des chose mal testées, de la redondance, etc. Mais je suis bien d'accord pour dire que c'est plutôt un bénéfice qu'une perte de temps.
A mon sens, les tests doivent être pertinents et ne pas être faits à l'aveugle. Tout tester coute cher, et le temps passé entre tester le principal et "tout" tester n'est pas toujours une bonne dépense. Et je parle bien ici des tests en général, pas seulement unitaires. On peut très bien rajouter des tests à l'infini (qu'ils soient fonctionnels, d'intégration, unitaires, ...), quitte à couvrir les mêmes choses plusieurs fois, mais de nouveau, je ne trouve pas cela pertinent par rapport à une réflexion qui va déterminer les parties les plus importantes à couvrir (que ce soit en TDD ou non; par exemple le TDD peut être appliqué pour une partie du développement, en se laissant la possibilité de rajouter des tests pour le reste du code moins critique).
Si l'extrémisme va jusqu'à rajouter sans cesse des tests (comme je le disais on peut envisager des tests à l'infini) alors pour moi il n'est pas intéressant. Si c'est plutôt une politique de rajout ou de couverture intelligente qui accompagne une réflexion, j'y suis tout à fait favorable.
Au final, il ne s'agit que d'une question d'équilibre.
6 De Amaury - 21/02/2011, 14:13
Ta réaction me semble normale, dans la mesure où j'avais écrit mon article − entre autre − après les emails que nous avons échangé sur la question.
1. Quoi que tu en dises, j'espère sincèrement que tu ne te reposes pas uniquement sur tes tests unitaires, et que tu continues à faire des tests "à la main" dans ton navigateur. Parce que les tests d'intégration (on met ensemble les briques qui ont été testées unitairement), ce n'est pas uniquement de l'intégration continue automatisée.
2. Tu es peut-être un développeur exemplaire. Tous les autres à qui j'ai posé la question, même ceux qui disent faire du TDD dans des entreprises très à cheval sur la question, confessent écrire une partie des leurs tests après avoir écrit le code. Pourquoi ? Parce que les choses ne sont pas aussi simple que ce que tu décris. Un code, ça vit, ça évolue. Pendant qu'on l'écrit, on réfléchit, on gagne en expérience. Les tests qu'on écrit avant d'écrire le code sont forcément incomplets, et on rattrape ça forcément après coup. Et quand on maintient du code, il faut tenir les tests unitaires à jour, mais il devient bien plus difficile de pratiquer le TDD.
3. Comme je l'ai dit, tester 100% du code ne veut pas dire qu'on teste le code à 100%. Il restera forcément des cas non pris en charge. L'alternative, c'est de prendre le temps d'imaginer *toutes* les possibilités. On peut justifier d'en arriver là, sur du code particulièrement critique. Mais il ne faut pas croire (ou faire croire) que l'écriture de ces tests exhaustifs ne coûte rien à l'entreprise ; c'est un fantasme de développeur déconnecté des réalités économiques de son travail.
4. Le but de mon article n'a jamais été de dire que les tests unitaires ne servent à rien. Bien au contraire. Je voulais juste dénoncer la vision binaire (tout ou rien), qui pousse certaines personnes à penser que ça vaut la peine de passer 3 jours à écrire tous les tests unitaires possible et imaginables, pour couvrir un code dont la durée de vie est de moins d'un mois. Comme tu le dis en commentaire «Les tests, on y va à fond, ou on y va pas». Désolé, je ne suis pas d'accord. Chacun son opinion, hein, il n'y a rien de personnel là-dedans.
Tu travestis quand même un peu mon propos, au sujet de la fainéantise. Je sais très bien qu'il faut faire un effort intellectuel pour écrire des tests unitaires. Je parlais seulement de la facilité de se dire «Pas de question, je dois tester tous les cas !». C'est simple, et là il n'y a pas à réfléchir.
A contrario, avec mon équipe on prend le temps de réfléchir au "taux de couverture" qu'il faut avoir pour chaque objet. Certains objets doivent être très stables ; les couches les plus proches des bases de données et les objets métier, notamment ; ceux-là sont testés automatiquement le mieux possible. Par contre, les couches les plus proches du rendu final, comme les contrôleurs ou les templates, qui sont amenés à être modifiés profondément et régulièrement, ce serait inutilement coûteux de vouloir les tester "à fond" (pour reprendre ton expression). Donc on fait des compromis sur ces développements-là, en mettant plus l'accent sur les tests "humains", qui doivent être fait de toute manière (désolé, mais dès qu'un développement contient du webdesign de près ou de loin, tu ne peux pas te satisfaire de tests automatisés).
C'est facile, de dire que le curseur doit être placé complètement d'un côté ou de l'autre. Beaucoup d'informaticiens sont très forts à ce jeu-là. Mais la plupart du temps, la vérité est juste un peu plus nuancée.
7 De mageekguy - 21/02/2011, 14:23
@Amaury : Je pense que l'aspect itératif de l'écriture des tests t'a échappé en TDD t'as échappé, ainsi qu'à ceux avec qui tu en as parlé et qui t'avoue, toute honte bue, compléter leur test à postériori.
Un test n'est jamais exhaustif immédiatement (l'est-il un jour, d'ailleurs...), il se construit parallélement au code testé, à la nuance prés qu'il est le guide de la construction du code, et non l'inverse.
Le test construit le code, le code ne devrait jamais construire le test, sauf cas particulier comme celui d'Atoum, par exemple, pour lequel j'ai écris beaucoup de tests à postériori, vu que je ne disposais pas d'Atoum pour tester Atoum à l'initialisation du projet.
Sinon, c'est effectivement la porte ouverte à des dépassements, car écrire ou compléter des tests à postériori est loin d'être l'activité la plus productive et efficace qui soit...
Et j'avoue envier cette capacité que tu sembles avoir de pouvoir définir ce qui est critique et ce qui ne l'est pas dans un environnement que tu définis toi-même comme très changeant.
Quand aux tests manuels, je n'ai jamais prôné leur abandon, bien au contraire, d'autant que les méthodes agiles mettent l'utilisateur au centre du développement.
C'est donc pour moi essentiellement au client de réaliser ces tests, car lui seul dispose de la connaissance métier nécessaire pour valider l'implémentation, indépendamment des bugs
que les tests automatisés sont là pour éviter.8 De usul_ - 21/02/2011, 14:46
@amaury donc là tu es en train de dire que si ton code à une durée de vie d'un mois tu peux l'écrire à l'arrache et tout buggé ?
Si il me faut 3j de tests pour un code qui durera un mois, je préfère les faire et pas passer 5j à faire du debug ou de la maintenance pour un truc que j'aurais pu coder mieux en ayant pas la flemme de faire mes tests ...
9 De Amaury - 21/02/2011, 14:57
Eh, si tu modifies ton article et tes commentaires en fonction des commentaires qui sont postés, on ne va pas s'en sortir !
Je voudrais juste revenir sur quelques détails, si tu le permets.
«Enfin, depuis le début de ce billet, vous avez peut être remarqué que je parle de tests automatisés ou automatiques, alors qu'Amaury se focalise sur les tests unitaires.»
Oui, mon article parlais des tests unitaires automatisés, et de rien d'autre. C'est mon choix ; tu peux choisir de parler d'autre chose, pas de soucis. Mais n'essaye pas de faire s'affronter nos visions dans ces conditions.
«Encore une fois, il oublie trop vite que les tests unitaires ne sont qu'un outils parmi bien d'autres, et qu'ils ne sont qu'une des nombreuses couches composant l'oignon qu'est une usine de développement de qualité.»
Mon propos portait sur les tests unitaires. Je n'ai rien oublié "trop vite". J'ai le droit de choisir de quoi je parle non ? J'ai aussi écrit un article sur l'intégration continue, par exemple. Sujet différent. J'ai du mal à te suivre.
«Le coût financier qui semble donc à première vue induit par l'écriture des tests est donc largement compensé par les avantages, le confort, pour reprendre le terme d'Amaury, qu'ils apportent au développeur.»
En l’occurrence, le "confort" est ton expression, que j'ai reprise. Et citer le confort des développeurs comme avantage déterminant des tests unitaires, c'est bizarre. Parle d'augmentation de la qualité, de diminution des bugs de régression, et on sera d'accord. Mais il s'agit peut-être juste d'une question de vocabulaire.
«J'ajouterais que les méthodes agiles sont plébiscitées actuellement car elles permettent, et c'est démontré, de mieux respecter à la fois les délais et les budgets. Or, ces méthodes préconisent toutes l'utilisation de tests automatisés lors du développement.»
Là encore, tu tentes de me faire dire ce que je n'ai pas dit. Je n'ai jamais dit que les méthodes agiles ou les tests unitaires étaient inutiles. Je les utilise dans ma boîte !
«C'est donc la raison pour laquelle je dis, en bon extrémiste, qu'un maximum de tests doivent être écrit»
Quand tu dis "un maximum de tests", c'est reconnaître implicitement que la "bonne" quantité de tests est totalement subjective.
«Ou bien faut-il faire de la merde, dépasser les budgets, risquer le procès, mécontenter le client, ternir son image, j'en passe et des meilleurs pour qu'au final personne ne soit satisfait ?»
1) Les méthodes agiles prévoient de mettre le client au cœur du projet, plutôt que de simplement satisfaire un contrat. À chaque itération, la satisfaction du client doit être mesurée à partir de plusieurs indicateurs, pas simplement le taux de couverture des tests unitaires...
2) Il faut aussi être prêt à vivre avec un monde remplit de nuances. Tous les projets n'ont pas les mêmes contraintes ; pour certains d'entre-eux, faire un prototype (vite fait, pas cher, compromis sur la qualité) permet de se confronter au marché, ce qui peut (in)valider un projet avant de le lancer. De la même manière, les différentes briques logicielles qui composent un projet n'ont pas toutes les mêmes contraintes.
10 De mageekguy - 21/02/2011, 15:03
@Amaury :
Dans quelles conditions ? Celle de dire que les tests unitaires ne doivent pas être les seuls tests, ni le seul outil à utiliser pour produire du code de qualité, et qu'en conséquence, ton argumentation ne tient pas, puisque comme tu le dis toi-même, tu te limites au tests unitaires ?
Mon propos portait sur les tests unitaires. Je n'ai rien oublié "trop vite". J'ai le droit de choisir de quoi je parle non ? J'ai aussi écritun article sur l'intégration continue, par exemple. Sujet différent.Ces sujets ne sont justement pas différents.
Parler de ce sujet sans prendre en compte l'intégralité du processus n'a tout simplement pas de sens, mais ce n'est que mon avis.
L'un induisant l'autre bijectivement, c'est effectivement une question de vocabulaire.
Je ne te fais rien dire du tout, ce n'est qu'un argument qui ne te vise aucunement, je n'écris pas que pour toi ;).
C'est reconnaître objectivement que la bonne quantité de tests ne peut pas être définie, à moins de s'appeler Madame Soleil et d'avoir une boule de cristal. Et d'aimer les MST, ou les bugs, au choix :).
Et ou ai-je dis le contraire ? Pour le coup, c'est moi qui ai du mal à te suivre.
Et en quoi un prototype devrait être de qualité inférieure au produit final ?
Si le but est de valider un concept, autant le faire dans les meilleures conditions, non ?
À quoi bon tester avec de la merde, avec quelque chose qui ne sera pas représentatif du produit final ?
Mais il est vrai que tu semble persuadé qu'un produit de mauvaise qualité coûte forcément moins cher qu'un produit de bonne qualité, ce en quoi nous ne sommes pas d'accord.
Et je n'ai amendé mon billet que suite au premier commentaire, bien avant que tu n'es posté le tien...
11 De Amaury - 21/02/2011, 15:05
@mageekguy : En réponse à ton dernier commentaire, l'aspect itératif de l'écriture des tests ne m'a pas échappé (même dans le cadre des TDD), merci. Je suis d'accord que le code et les tests devraient être écris en parallèle. La plupart du temps, on essaye ; des fois (surtout quand on fait de la maintenance), c'est moins évident.
«Et j'avoue envier cette capacité que tu sembles avoir de pouvoir définir ce qui est critique et ce qui ne l'est pas dans un environnement que tu définis toi-même comme très changeant.»
Encore une fois, tu te plais à déformer mes propos.
J'ai dit qu'il y a certaines couche qui sont stables, et d'autres qui sont au contraire très souvent modifiées. Et donc qu'il faut s'adapter en fonction de ça.
«C'est donc pour moi essentiellement au client de réaliser ces tests (manuels), car lui seul dispose de la connaissance métier nécessaire pour valider l'implémentation, indépendamment des bugs techniques que les tests automatisés sont là pour éviter.»
Hum, pas d'accord. Comment un développeur peut dire que sont code fonctionne, s'il dit ne pas avoir la connaissance métier de comment ça devrait fonctionner ?
Je comprends qu'on puisse avoir des points de vue différents sur ces questions. J'ai l'impression que tu en fais une question de principe et que ça va finir en guerre de religion (ce que je dénonçais justement dans mon article). On peut calmer le jeu ?
12 De Amaury - 21/02/2011, 15:13
@usul_ : Je n'ai pas dit ça. Je dis qu'un bout de code qui a une durée de vie d'un mois doit quand même faire face à certaines réalités économiques. Et que, dans mon entreprise, il s'agit habituellement de code "frontal", dont les tests pourront être réalisés en une demi-journée avec un niveau de couverture très satisfaisant.
On pourra toujours trouver un développeur extrémiste qui déclarera qu'il lui faut une semaine de plus pour tester ce code à fond. Mais qu'on ne me dise pas qu'il n'y a aucun impact sur la validité économique du code en question.
Ma remarque avait pour but de mettre en avant le fait qu'il est très difficile de définir le seuil à partir duquel un code est suffisamment testé.
13 De Cyrano - 21/02/2011, 15:31
À travers cet intéressant débat, je regrette l'absence d'un élément un tout petit peu primordial dans l'élaboration de tout projet de développement : Le degré de détails dans l'expression du besoin de l'utilisateur final.
Tout projet, quel qu'il puisse être, doit répondre à un besoin. Or, corrigez-moi si je fais erreur, il m'apparaît évident que la qualité des tests dépendra de la précision du besoin. Si le besoin est flou, comment écrire un test pertinent et exhaustif ?
Et ceci m'amène à poser la question suivante : est-ce qu'en amont du développement proprement dit il ne serait pas opportun de s'attarder lourdement sur la phase analyse en partenariat le plus étroit possible avec l'utilisateur final ou l'expert métier ? Le cas échéant, si vous connaissez une recette pour obtenir ça d'un client, ça m'intéresse bougrement. Parce qu'effectivement, certains projets sont très vivants voire trop, et de façon parfois pénible lorsqu'une modification intervient en cours de développement précisément parce qu'un besoin fonctionnel n'a pas été isolé lors de l'analyse préliminaire.
Est-ce que les tests, qu'ils soient unitaires ou automatisés, ne commencent pas là en tout premier lieu ? Ce que j'entrevois à travers cette idée, c'est que si le besoin est clairement et précisément exprimé au départ, la difficulté d'écriture des tests sera d'autant plus réduite. En termes plus prosaïques, comment amener un client à nous dire s'il sait vraiment clairement ce qu'il veut ?
14 De desfrenes - 21/02/2011, 20:17
"Les tests, on y vas à fond, avec automatisation, intégration continue et le reste de l'arsenal, ou on y va pas."
Ouais, on a reconnu ton style ^^. Nous on y va doucement. A titre personnel je suis convaincu de l'intérêt, mais je ne maitrise pas encore bien la mise en place. Après il y a beaucoup de freins, parmis lesquels on peut avoir l'exigence du client ou la compétence des gens avec qui on travaille. Au final c'est souvent une question de compétence, ce qui a bien un coût... en temps, en formation, en recrutement, etc.
15 De wooshell - 21/02/2011, 20:34
A mon sens Fred :
- tout n'est pas testable : car tout n'est pas objet, car tout n'a pas besoin d'être testé (oui j'ai un <H1> sur ma page qui vaut "TOTO" => LOL)
- faire des applis sans tests NON, faire des applis avec tests OK : encore faut il savoir écrire un test : par ex je suis pour les tests boite noire, mais les tests boite blanche bof, je préfére pouvoir changer mes implémentations en me reposant sur mes tests boite noire
- le testing sur de l'existant en place implique parfois des refontes profondes d'architectures qu'il n'est pas possible de mener en cycle court de dev par ex.
- dernier point le plus difficile : je pense qu'il faut admettre qu'une appli peut avoir des bugs : une appli sans bug avec une ergo naze ou n'assurant que 2 features est ce une finalité ? Par ailleurs, on peux avoir écrire des tests bien sympas et qui passent (+ couverture maximale), pour au final constater des résultats erronés : la couverture n'est plus un critère qualitatif dans ces cas là.
Le client ne mesure pas la réussite d'un projet à la seule robustesse de l'applicatif (d'ailleurs difficile à démontrer) mais également à son coût (de mise en place / formation / en dollars), sa couverture fonctionnelle et son délai de livraison.
Je pense, qu'avant tout, il faut savoir chiffrer, coder xD et montrer des résultats : on retrouve de toute façon dans le développement/maintenance des tests les mêmes problèmes que dans le développement/maintenance d'un code non testé : test incompréhensible vs code incompréhensible, test useless vs code useless, test peu stable vs code peu stable, je dois jeter mes tests vs je dois jeter mon code, je dois mettre à jour tout le temps mes tests qui sont trop capricieux vs .., etc, etc
A moins d'etre testeur full time, tout devient une question d'intéret général.
16 De mageekguy - 21/02/2011, 21:12
@desfrenes : Je n'ai jamais dit que c'était simple, bien au contraire.
Je souligne même la difficulté de l'exercice dans mon billet.
Bon courage en tout cas, le jeu en vaut la chandelle.
Et en l'occurent, le
n'est pas une figure de style, mais un fait.17 De mageekguy - 21/02/2011, 21:14
@wooshell : Par un moyen ou par un autre, tout est testable, même le contenu d'une balise <h1 /> ou même du code non objet, même si dans certain cas, il faut que le code à tester soit écrit pour le permettre.
Quand aux tests boîtes blanches, tu te bases sur notre expérience commune, mais parfois, il faut faire avec ce que l'on a, même si ce n'est pas parfait.
Ce genre de problème est la raison d'être d'Atoum.
Et la reprise de l'existant est une autre problèmatique, mais cela me semblait évident puisque dans ce contexte, le TDD n'est pas de mise, mais au final, la mise en œuvre de tests est aussi pertinente au final.
Enfin, bien sur qu'un code peut contenir des bugs, et je ne le nie nullement dans mon billet.
Je dis que les tests sont un moyens efficaces qui permettent d'améliorer la qualité globale d'un logiciel, sans forcément augmenter son coût, ce qui permet ainsi d'augmenter à la fois la satisfaction du client et de son prestataire.
Et il semble que je sois pas le seul à penser cela.
18 De wooshell - 21/02/2011, 23:21
Nous sommes bien d'accord sauf sur le coût : car tout à un coût. Rédiger un scénario de test, automatiser des tests, maintenir des tests, maîtriser un framework de test représente un coût. Il en va de même évidemment pour la conception, architecture, intégration, dev ui, refactoring, maintenance corrective, maintenance évolutive et autres joyeusetés.
Le niveau d'exigence joue ici énormément (= croix des managers xD). Se baser sur l'expérience passée, pour anticiper et mettre en oeuvre un ensemble, aide => même si l'on peux se planter monumentalement :o. Si je m'aventure à donner une définition de ce que sont de "bons" tests, il s'agirait pour moi de tests autour :
- des traitements bas niveau : sur les éléments de base d'une archi par ex
- des traitements à risque
- des traitements impliquant de nombreux variables
Ces quelques principes me permettent d'avoir un testing "suffisant" et adapté à mon environnement et de dormir tranquille
Enfin, un logiciel naît pour vivre mais finit surtout par mourir (c'est triste désolé uhuh). Là encore Fred, je parle de la globalité : l'investissement à mettre sur le testing (ou n'importe quoi d'autre) se calcule par rapport à un ensemble (1 autre dev, 1 projet, des risques, des opportunités d'évolutions, etc) et non par rapport à un dev non testé
19 De mageekguy - 22/02/2011, 06:40
@wooshell : Tu as manifestement loupé un truc ou deux dans mon billet, par rapport au coût.
20 De mageekguy - 22/02/2011, 07:39
@Cyrano : En TDD, l'analyse est intégrée à la rédaction des tests (c'est d'ailleurs un moyen de contenir les coûts, à y réfléchir).
Faire une analyse poussée en amont n'a pas de sens, car on retomberait dans les travers des pratiques non agiles.
21 De desfrenes - 22/02/2011, 09:20
"le jeu en vaut la chandelle."
On le perçoit bien, cela dit pour l'instant ce n'est pas tant pour la non-régression que pour la conception. On avait déjà pas vraiment de problèmes de régression, par contre dans la conception d'une API je trouve ça très efficace. De fait, plus qu'avoir un code testé, on s'aperçoit qu'il faut surtout qu'il soit *testable*. Bref, c'est le progrès, je souhaite qu'Atoum y participe. Pour le test fonctionnel, je suis assez séduit par l'approche de Zombie (http://zombie.labnotes.org/), plus que par des trucs comme selenium.
22 De Nicolas - 07/05/2011, 16:57
Bonjour,
vraiment très de très bon argument, personnellement je fais du code sans test, on le vend très bien et les bugs sont corrigés sans problème, tout dépend des projets.
J'aimerais me mettre à écrire des testes automatisé, mais je suis fainéant (mais promis, je vais chercher comment faire ça proprement, je vais mettre le nez dans Atoum).
Personnellement, quoi de plus désagréable que de passer 5 minutes à corriger un problème dans une partie Importante du programme, de livrer et d'être appelé ensuite pour des bugs majeurs... Pas pro.
Tout les arguments cité plus haut sont pour moi, chacun, suffisant pour mettre en pratique les tests.
Bon, j'ai du boulot, la remise en question faite il ne reste plus qu'à prendre de la compétence.
<mode test>
23 De Clotaire - 29/03/2012, 10:08
Deux choses @Amaury :
- En tand que directeur technique, quand vous gérez une équipe de taille croissante, les tests unitaires et un moyen de responsabiliser les développeurs à leur travail et de les rendre autonome. Entre un "vieux Loulou" du code PHP qui sait se dispenser des tests tout en garantissant le minimum de bug, et un stagiaire qui débute, il y a un monde. Le test est donc pour moi pédagogique, il permet de m'assurer que le développeur a réfléchi à son code, qu'il l'a relu et quand je passe voir le développeur ou que quelqu'un relit son code, qu'on a déjà une base de dialogue. Une couverture raisonnable pour tout le monde me semble incontournable.
- Sur les aspects d'objets métier critiques, certes le test ne garanti rien, mais si on rencontre un bug, on l'ajoute un test et la prochaine fois qu'on modifie le comportement d'une méthode, ce comportement sera couvert.
Bref, si on a du bon sens, plus le projet est gros, ou plus il y a d'intervenants ou plus il y a de changements prévus à l'avenir, ou plus il y a de contraintes de production (visites, usage intensif, ...), plus les tests se font ressentir comme incontournables. Ce n'est pas une question dogmatique, c'est un besoin !