on peut améliorer les choses, mais à quel prix ? Et pour combien de temps ?! Globalement la stratégie de tests “en boîte noire” n’est ni des plus efficaces, ni très rentable.
J’en entends plus d’un sourire (jaune) en lisant cela, mais rassurez-vous : vous n’êtes pas seuls…
Avant de vous parler de la sempiternelle pyramide des tests, rappelons quelques critères qu’il est important d’évaluer dès lors que l’on réfléchit à une stratégie de tests. Afin de lever une ambiguïté trop courante, précisons que nous parlons dans cet article de tests automatisés.
Le test, quel qu’il soit, n’a d’autre intérêt que de vous donner un feedback : “mon programme fait-il bien ce qu’il doit ?” On peut juger de la qualité de ce feedback sur 3 aspects :
La précision du feedback. Si un test échoue, suis-je capable de déterminer précisément quelle partie du code ne fonctionne pas ? Combien de temps faut-il à un développeur pour identifier le morceau de code qui met le test en échec ? Plus un test est fin (au niveau de la méthode), plus le feedback sera précis. Au contraire, comment savoir si c’est l’accès à la base de données ou une erreur JavaScript qui provoque l’échec d’un test de bout en bout ?
Source : Culture Code, OCTO Tehnology
La fiabilité du feedback. La répétabilité d’un test est primordiale : Peut-on faire confiance à un test dont les résultats varient d’une exécution à l’autre, sans qu’aucune modification apparente n’ait été faite sur le code, la configuration ou une dépendance ? Encore une fois, les tests de bout en bout ont cette fâcheuse tendance à exploser pour des raisons obscures et souvent incontrôlables : une latence réseau, un passage de Garbage Collector qui ralentit la JVM, le navigateur qui fait des siennes, un compte désactivé, un schéma de base de données modifié…
“Les tests instables sont pires que pas de tests”, concluent les ingénieurs de LinkedIn après avoir calculé qu’ils avaient 13.4% de chance d’avoir un build stable avec 200 tests et seulement 1% de risque d’échec sur chaque test.
"Stop calling your tests flaky. Instead, call it ‘Random Success’ or ‘Sometimes Success.’ Would you want to release a product that ‘sometimes works’?"
La rapidité du feedback. La plupart d’entre nous n’étions pas nés lorsque l’on utilisait les cartes perforées pour programmer. Cette époque glorieuse, mais heureusement révolue, où il fallait des heures voire des jours pour savoir si la pile de cartes “compilait” et recommencer dans le cas contraire... Il n’est plus envisageable aujourd’hui d’attendre autant avant de savoir si notre code compile (c’est instantané dans l’IDE). Il en est de même pour les tests : plus rapidement vous saurez si un test échoue, plus vite vous pourrez corriger le problème et moins cher il vous en coûtera de le faire ^<a id="post-5-footnote-ref-1" href="#post-5-footnote-1">[1]</a>^ :
Source : Code complete, 2nd edition, by Steve McConnell ^<a id="post-5-footnote-ref-2" href="#post-5-footnote-2">[2]</a>^
On constate même un cercle très vertueux lorsque les tests sont rapides : ils sont confortables à exécuter^<a id="post-5-footnote-ref-3" href="#post-5-footnote-3">[3]</a>^ et fournissent une sérénité sans pareille, incitant à en écrire encore davantage.
La stratégie de tests visera donc à maximiser le nombre de tests qui remplissent ces trois critères (précision, rapidité, fiabilité).
Sachant qu’il est peu probable que vous ayez un budget infini, la stratégie de tests va nécessairement en dépendre. Il vous faudra mettre le coût des différents types de test en regard de leur intérêt, ou dit plus simplement évaluer leur ROI :
Le tableau suivant synthétise les principaux critères en matière de choix du type de test à privilégier :
Vu comme cela, on pourrait se dire “chouette, je n’ai qu’à faire des tests unitaires”, mais il est bien évident que les autres types de tests existent pour une bonne raison : les tests unitaires ne valident pas tout.
Nous en arrivons donc à la fameuse pyramide des tests (automatisés), initialement décrite par Mike Cohn dans le livre Succeeding with Agile et qui sera d’une aide précieuse dans la définition de votre stratégie de test.
Voilà pour la théorie. Le prochain article traitera plus en profondeur de la base de la pyramide : les tests unitaires et leur mise en pratique sur un projet Java / Spring.