L'intégration continue avec les tests est utile pour s'assurer que le code "shippable" est archivé en permanence.
Cependant, il est vraiment difficile de maintenir une suite complète de tests et, souvent, il semble que la version sera de toute façon boguée.
Combien de tests devez-vous avoir pour avoir confiance en vos tests de pipeline CI? Utilisez-vous une sorte de métrique pour décider quand il y a suffisamment de tests?
Quand avez-vous suffisamment de tests automatiques pour avoir confiance dans votre pipeline d'intégration continue?
La réponse devient probablement claire si vous pensez à quoi vous voulez avoir confiance. En fin de compte, il mappe 1-1; chaque test vous donne confiance en la chose qu'il teste:
D'après la façon dont vous avez formulé votre question, vous pensez probablement dans un sens commercial global en ce moment, par exemple:
Je veux être sûr que mon application peut faire X.
Vous écrivez donc un test de bout en bout qui essaie de faire X et vérifie s'il le fait correctement.
Tout cela est très autoréférentiel, mais c'est parce que c'est à cela qu'il se résume. Il y a simplement n'est pas plus.
Par exemple, imaginez que vous écrivez une application pour créer des recettes de cuisine. Une caractéristique est que, si vous ajoutez différentes quantités de plusieurs sortes de fromages, cela vous donne la température et le temps corrects pour qu'ils fondent tous.
Vous pouvez donc écrire un test unitaire pour votre CheeseMeltCalculator
, où vous lui donnez 100 g de Gouda et 200 g d'Emmental, puis vous vérifiez que la température et le temps sont corrects. Cela signifie que vous pouvez désormais être sûr que CheeseMeltCalculator
fonctionne pour 100 g de Gouda et 200 g de fromage. Maintenant, si vous répétez ce test avec 300 g de Gouda au lieu de 200 g, vous pouvez être plutôt confiant qu'il fonctionne correctement pour différentes valeurs. Vous pouvez ajouter des tests pour 0
, -1
et int.MaxValue
g de Gouda pour être sûr que le code ne se déclenche pas (ou ne se déclenche pas correctement comme prévu) pour une entrée bizarre.
Vous pouvez écrire un test d'intégration pour vérifier que CheeseMeltCalculator
est correctement intégré dans le processus de calcul de la température et du temps des aliments. Si cela ne fonctionne pas, mais que les tests CheeseMeltCalculator
ci-dessus sont corrects, vous pouvez être sûr que le bogue se trouve dans d'autres calculatrices ou dans la façon dont les données de différentes calculatrices sont combinées.
Et enfin, vous pouvez écrire un test de bout en bout pour créer une recette entière, et l'une des choses que vous vérifiez est la température et le temps du résultat. Si les 2 niveaux de tests précédents sont corrects, mais que cela se passe mal, vous pouvez à nouveau être sûr que ces pièces sont correctes et l'erreur concerne la façon dont le calcul de la température est intégré dans l'application. Par exemple, l'entrée utilisateur n'est peut-être pas transférée correctement.
Et enfin, si tous ces tests sont bons, alors vous pouvez être sûr que " si vous ajoutez différentes quantités de plusieurs sortes de fromages, cela vous donne la bonne température et le temps pour qu'ils fondent tous "
Le fait est que vous ne pouvez pas avoir de test "cela fonctionne correctement". Vous ne pouvez tester que "Si je fais X, Y arrive"
Cependant, c'est exactement ce qui devrait figurer dans les spécifications techniques du projet. Une déclaration comme " si vous ajoutez différentes quantités de plusieurs sortes de fromages différents, cela vous donne la température et le temps corrects pour qu'ils fondent tous" non seulement donne au client des attentes claires sur ce que le fini produit fera l'affaire, mais peut également être transformé en tests automatisés.
L'utilisateur Richard a ajouté ces informations dans une modification:
Martin Fowler a un très joli résumé sur son site Web sur les stratégies les plus courantes: https://martinfowler.com/articles/microservice-testing/
Je ne veux pas supprimer cela, mais je veux dire ceci: Par rapport à cette réponse, ce n'est pas un "résumé", mais plutôt une explication beaucoup plus approfondie, avec de jolis graphismes et tout.
Mon conseil serait: si tout vous semble logique après avoir lu ma réponse, vous avez terminé. Si les choses ne semblent toujours pas claires, réservez un peu de temps et lisez l'article lié.
Il n'y a aucune métrique que vous pouvez calculer qui vous donnera la confiance que vous recherchez. La confiance se construit en faisant quelque chose, puis en réussissant ou en échouant et en apprenant quelque chose.
Les seules "mesures" que j'ai trouvées qui me donnent confiance dans notre couverture de test sont:
Les tests automatisés ne sont pas une solution miracle. Vous devez garder une trace du nombre de défauts de production détectés au cours de chaque cycle de publication. Lorsque ce nombre diminue, vous fournissez un meilleur logiciel. Les tests automatisés et l'intégration continue ne sont que outils que vous utilisez pour fournir de meilleurs logiciels.
La seule mesure que vous pouvez vraiment mesurer est "Offrez-vous un meilleur logiciel?
Et même alors, c'est subjectif.
Quand avez-vous suffisamment de tests automatiques pour avoir confiance dans votre pipeline d'intégration continue?
Dans la plupart des environnements économiques, vous n'aurez pas le budget pour mettre en œuvre suffisamment de confiance (> 99%) mais vous devez gérer un budget limité: tout dépend du rapport coût/bénéfice.
Ainsi, en réalité, les tests faciles/bon marché/risqués seront mis en œuvre alors que les tests coûteux/peu probables ne le seront pas.
Un sous-objectif du développement logiciel est de créer une architecture facile/bon marché à tester (conception pour la testabilité en appliquant Test-driven_development ) pour garder les tests automatisés abordables.
Je suppose que le Pareto_principle peut être appliqué ici aussi pour les logiciels maintenables/testables: Il dit qu'avec dépenser 20% plus d'argent, vous obtenez 80% d'avantages supplémentaires. Pour atteindre les 20% restants, vous devez dépenser 80% supplémentaires.
Vous pouvez appliquer des mesures de test comme couverture de code et couverture de mutation pour vous montrer le code source potentiel non testé.
Mais même avec une couverture à 100%, vous ne pouvez pas être sûr que votre code est exempt de bogues.
La direction aime les codemetrics. Si la "couverture du code> = 80%" est appliquée par la direction alors que les développeurs ne prennent pas en charge/comme les tests automatisés, il existe des moyens d'écrire un code de test avec une couverture élevée qui ne prouve rien donnant un faux sentiment de sécurité.
L'astuce ici n'est pas de se soucier de la couverture complète mais de gérer le risque de vos changements.
Supposons que vous utilisez votre pipeline pour déployer la même version que celle déjà en production - quel est le risque d'erreur de régression? Zéro (car il n'y a pas de changement).
Maintenant, disons que je veux changer un morceau de texte sur l'un des écrans. J'ai ajouté le test pour vérifier que le texte s'affiche désormais correctement (supposons, pour les besoins de l'argument, qu'il s'agit d'un morceau de texte vraiment important). De quels autres tests ai-je besoin pour vérifier qu'il n'y a pas d'erreurs de régression? En réalité, aucun ...
Ainsi, le nombre de tests automatisés requis pour chaque version en direct n'est pas fonction de la taille de votre application, mais de la taille de votre modification. Si vous effectuez de petits changements à faible risque, vous aurez besoin de beaucoup moins de tests pour atténuer les risques.
Mais attendez une minute ... cela ne cadre-t-il pas très bien avec le point de CI et CD?
Oui! En gardant tous vos changements et deltas très petits, vous atténuez de nombreux risques de régression par le biais d'un processus plutôt que par des tests. De plus, la question ne devient pas réellement une question d'automatisation (c'est juste l'outil que nous utiliserons) - c'est simplement une question de test et d'appétit pour le risque. Oubliez complètement l'automatisation, quels tests exécuteriez-vous contre une modification pour vous assurer qu'une modification n'a pas introduit de problèmes? La réponse à cette question ne change pas d'un processus de test manuel à un système CI - le seul avantage est que bon nombre de ces tests de régression peuvent avoir été précédemment développés dans les fonctionnalités précédentes et CI vous encourage à apporter des modifications plus petites et plus sûres.
TLDR
Vos tests visent à atténuer le risque de changement. Un déploiement avec un delta de zéro ne comporte aucun risque et ne comporte donc aucun risque. En gardant vos modifications petites, il devient beaucoup plus facile d'identifier les tests nécessaires pour les valider - la réutilisabilité de l'automatisation est un bonus.
Il s'agit de la même mesure que lorsque vous testez votre produit manuellement.
En pratique, il est facile d'identifier ces zones de faible confiance: en supposant que vous expédiez le produit, je suppose que vous avez des étapes manuelles post-pipeline qui améliorent votre confiance en matière d'expédition. Ce sont les domaines que vous devez automatiser pour améliorer la confiance dans le processus automatique lui-même.
Votre automatisation est un effort continu. Il grandit et s'améliore à mesure que votre produit s'améliore. Un défaut est une raison pour repenser votre code, ainsi que pour repenser le CI. Et le côté ensoleillé ici est que la confiance dans le produit lui-même est réalisable - la confiance dans l'automatisation est également réalisable.