Si j'ai du code avec une couverture de test de 80% (tous les tests réussissent), est-il juste de dire qu'il est de meilleure qualité que le code sans couverture de test?
Ou est-il juste de dire que c'est plus maintenable?
Si j'ai du code avec une couverture de test de 80% (tous les tests réussissent), est-il juste de dire qu'il est de meilleure qualité que le code sans couverture de test?
Ou est-il juste de dire que c'est plus maintenable?
Réponses:
Au sens strict, il n'est pas juste de faire des réclamations tant que la qualité de la suite de tests n'est pas établie. Réussir 100% des tests n'est pas significatif si la plupart des tests sont triviaux ou répétitifs les uns avec les autres.
La question est: dans l'histoire du projet, l'un de ces tests a-t-il révélé des bogues? Le but d'un test est de trouver des bugs. Et s'ils ne l'ont pas fait, ils ont échoué en tant que tests. Au lieu d'améliorer la qualité du code, ils pourraient seulement vous donner un faux sentiment de sécurité.
Pour améliorer vos conceptions de test, vous pouvez utiliser (1) des techniques de boîte blanche, (2) des techniques de boîte noire et (3) des tests de mutation.
(1) Voici quelques bonnes techniques de boîte blanche à appliquer à vos conceptions de test. Un test de boîte blanche est construit avec un code source spécifique à l'esprit. Un aspect important du test de la boîte blanche est la couverture du code:
if
ou while
), avez-vous un test qui le force à être vrai et un autre qui le force à être faux? [Couverture de la décision]&&
) ou une disjonction (utilisations ||
), chaque sous-expression a-t-elle un test où elle est vraie / fausse? [Couverture de condition]break
d'une boucle est-il couvert?(2) Les techniques Blackbox sont utilisées lorsque les exigences sont disponibles, mais le code lui-même ne l'est pas. Ceux-ci peuvent conduire à des tests de haute qualité:
(3) Enfin, supposons que vous ayez déjà beaucoup de bons tests pour la couverture de la boîte blanche et des techniques de boîte noire appliquées. Que pouvez vous faire d'autre? Il est temps de tester vos tests . Une technique que vous pouvez utiliser est le test de mutation.
Sous test de mutation, vous apportez une modification à (une copie de) votre programme, dans l'espoir de créer un bug. Une mutation peut être:
Changer une référence d'une variable à une autre variable; Insérez la fonction abs (); Remplacez moins que par supérieur à; Supprimer une déclaration; Remplacez une variable par une constante; Supprimer une méthode prioritaire; Supprimer une référence à une super méthode; Modifier l'ordre des arguments
Créez plusieurs dizaines de mutants, à différents endroits de votre programme [le programme devra encore être compilé pour pouvoir tester]. Si vos tests ne trouvent pas ces bogues, vous devez maintenant écrire un test qui peut trouver le bogue dans la version mutée de votre programme. Une fois qu'un test a détecté le bogue, vous avez tué le mutant et vous pouvez en essayer un autre.
Addendum : j'ai oublié de mentionner cet effet: les bugs ont tendance à se regrouper . Cela signifie que plus vous trouvez de bogues dans un module, plus vous avez de chances de trouver plus de bogues. Donc, si vous avez un test qui échoue (c'est-à-dire que le test est réussi, car le but est de trouver des bogues), non seulement vous devez corriger le bogue, mais vous devez également écrire plus de tests pour le module, en utilisant le techniques ci-dessus.
Tant que vous trouvez des bogues à un rythme constant, les efforts de test doivent se poursuivre. Ce n'est que lorsqu'il y a une baisse du taux de nouveaux bogues trouvés que vous pouvez avoir confiance que vous avez fait de bons efforts de test pour cette phase de développement.
Selon une définition, il est plus facile à maintenir, car tout changement de rupture est plus susceptible d'être détecté par les tests.
Cependant, le fait que le code passe les tests unitaires ne signifie pas qu'il est intrinsèquement de meilleure qualité. Le code peut encore être mal formaté avec des commentaires non pertinents et des structures de données inappropriées, mais il peut toujours passer les tests.
Je sais quel code je préfère conserver et étendre.
Un code sans aucun test peut être de très haute qualité, lisible, beau et efficace (ou indésirable total), donc non, il n'est pas juste de dire qu'un code avec une couverture de test de 80% est de meilleure qualité qu'un code sans couverture de test.
Il pourrait être juste de dire que le code couvert à 80% de bons tests est probablement de qualité acceptable et probablement relativement maintenable. Mais ça garantit peu, vraiment.
Je dirais que c'est plus refactorisable. Le refactoring devient extrêmement facile si le code est couvert de nombreux tests.
Il serait juste de l'appeler plus maintenable.
Je serais d'accord sur la partie maintenable. Michael Feathers a récemment publié une vidéo d'un excellent discours sur son intitulé " La profonde synergie entre la testabilité et une bonne conception " dans lequel il discute de ce sujet. Dans l'exposé, il dit que la relation est à sens unique, c'est-à-dire qu'un code bien conçu est testable, mais que le code testable n'est pas nécessairement bien conçu.
Il convient de noter que le streaming vidéo n'est pas génial dans la vidéo, il peut donc être utile de le télécharger si vous souhaitez regarder en entier.
Je me pose cette question depuis un certain temps en ce qui concerne la "couverture conditionnelle". Alors que diriez-vous de cette page de atollic.com "Pourquoi analyser la couverture de code?"
Plus techniquement, l'analyse de la couverture du code trouve les zones de votre programme qui ne sont pas couvertes par vos cas de test, vous permettant de créer des tests supplémentaires qui couvrent des parties non testées de votre programme. Il est donc important de comprendre que la couverture du code vous aide à comprendre la qualité de vos procédures de test, pas la qualité du code lui-même .
Cela semble tout à fait pertinent ici. Si vous avez un ensemble de cas de test qui parvient à atteindre un certain niveau de couverture (code ou autre), vous invoquez très probablement le code sous test avec un ensemble assez exhaustif de valeurs d'entrée! Cela ne vous en dira pas beaucoup sur le code sous test (à moins que le code explose ou génère des défauts détectables) mais vous donne confiance dans votre ensemble de cas de test .
Dans un intéressant changement de vue de Necker Cube , le code de test est maintenant testé par le code sous test!
Il existe de nombreuses façons de garantir qu'un programme fait ce que vous avez l'intention de faire et de vous assurer que les modifications n'auront pas d'effets indésirables.
Les tests en sont un. Éviter la mutation des données en est une autre. Il en va de même pour un système de types. Ou une vérification formelle.
Donc, bien que je convienne que les tests sont généralement une bonne chose, un pourcentage donné de tests pourrait ne pas signifier grand-chose. Je préfère m'appuyer sur quelque chose écrit en Haskell sans test plutôt que sur une bibliothèque PHP bien testée