Les tests unitaires sont surestimés : repenser les stratégies de test

Alors que l’industrie s’efforce d’avoir des cycles de publication plus courts, elle a du mal à maintenir la confiance dans la qualité du code publié, ce qui met en évidence le besoin fondamental d’une stratégie de test continue réussie.

Bien que les entreprises se soient concentrées sur DevOps et la livraison continue, la triste vérité est que la tendance à publier des logiciels est restée relativement stable, avec seulement 10 % des équipes qui publient au moins quotidiennement. Plusieurs stratégies se déploient — décaler à gauche (par exemple, plus de tests unitaires), décaler vers la droite (par exemple, test en production), en passant des tests manuels aux tests automatisés et même en supprimant des rôles de testeurs distincts et en essayant de tenir les développeurs responsables de la qualité du code qu’ils écrivent.

Ces stratégies de test rencontrent divers degrés de succès et peuvent même différer d’une équipe à l’autre en fonction du niveau de compétence, de la maturité et de la culture. Les tests retardent souvent les versions parce que les équipes n’optimisent pas – et sont souvent découragées de se concentrer sur – les composants les plus importants de la confiance numérique.

Les tests unitaires (le processus de vérification de petits morceaux de code pour fournir des informations tôt et souvent) ont été considérés comme les meilleures pratiques, souvent soutenus par l’argument selon lequel les tests unitaires offrent le plus de valeur pendant le développement, car les développeurs peuvent détecter rapidement les erreurs.

Cette idée est devenue si largement acceptée que le terme « tests unitaires » est maintenant quelque peu confondu avec les tests automatisés en général, perdant une partie de son sens et contribuant à la confusion.

Le test n’est pas un monolithe

Tout d’abord, il est essentiel de distinguer les types de tests qui sont écrits car ils sont faciles à confondre et peuvent prêter à confusion. Cet article se concentre sur les tests fonctionnels qui vérifient que les fonctionnalités fonctionnent correctement ; cela peut être distingué des tests d’accessibilité, des tests de performances, des tests de sécurité et des tests de charge.

Lorsque l’on pense aux tests fonctionnels, il y a deux utilisations principales : les tests d’acceptation qui vérifient que la nouvelle fonctionnalité ou la correction de bogue fait ce qu’elle était censée faire et les tests de régression qui sont exécutés régulièrement pour vérifier que le nouveau code n’a pas cassé l’ancien. code.

Les développeurs se concentrent traditionnellement sur les tests d’acceptation, qui sont généralement entièrement composés de tests unitaires qui vérifient le niveau de code le plus bas, comme toutes les différentes entrées possibles pour chaque méthode d’une classe. Dans les cercles Agile, cela se fait souvent avec le développement piloté par les tests (TDD) où les développeurs écrivent d’abord les tests, puis implémentent les fonctionnalités afin que ces tests réussissent. TDD lui-même est également surestimé, car l’écriture de code testable est beaucoup plus importante que les tests réels.

Les tests d’acceptation incluent de plus en plus des tests de composants qui isolent un ensemble de code partageant une fonction commune et garantissent son bon fonctionnement, et incluent parfois des tests d’intégration qui vérifient que divers composants interagissent correctement les uns avec les autres. Dans les équipes ou les départements qui n’ont pas d’équipes d’assurance qualité ou de test distinctes, les tests d’acceptation peuvent inclure des tests DOM vers base de données (D2D), qui sont plus souvent désignés par des termes moins précis comme les tests de bout en bout (E2E) ou l’interface utilisateur (UI) Essais. Les tests D2D évaluent la pile complète des interactions de l’utilisateur final avec l’interface utilisateur à l’API à la couche de service à la base de données et inversement.

Des problèmes surviennent lorsque les tests d’acceptation sont utilisés comme tests de régression. C’est la promesse réelle du Behavior Driven Development (BDD), qui est un processus souvent approuvé par les consultants Agile pour encourager la communication entre les parties prenantes – bien qu’en pratique, cela puisse ajouter plus de complexité au processus – où tout le monde s’accorde sur les tests et les utilise ensuite. eux.

La pyramide des tests

La pyramide des tests est le guide typique sur la façon d’aborder les tests de régression fonctionnelle. La pyramide place les tests unitaires en bas, les tests d’intégration au milieu et les tests D2D en haut. Cela explique que, parce que les tests unitaires sont plus rapides et plus fiables, ils devraient être l’objectif principal alors que les tests D2D reçoivent le moins d’attention (ils sont nettement plus lents et beaucoup plus floconneux), les tests d’intégration se situant quelque part entre les deux.

Un problème avec cette approche est que pour les organisations qui séparent plus distinctement les rôles de testeur et de développeur, la couche intermédiaire est effectivement ignorée. Les développeurs se concentrent sur les tests unitaires car ils sont évalués par des mesures de pourcentage de couverture des tests unitaires. Ces tests ne sont pas suffisants ; les testeurs se concentrent sur les entrées de l’interface utilisateur car c’est ainsi que les tests ont traditionnellement été effectués. Ces tests sont faciles à mal faire et tous ceux qui finissent par devoir les écrire finissent par se débattre avec eux.

Un autre problème est que la pyramide des tests n’est pas basée sur des mesures appropriées. Quiconque a passé du temps à tester des sites Web régulièrement mis à jour sait que la partie coûteuse n’est pas le temps qu’il faut pour créer le test ou même le temps d’exécution du test, c’est tout ce qui entre dans la maintenance des tests.

C’est pourquoi obtenir des projets d’intelligence artificielle pour créer des tests de base n’est pas l’accomplissement impressionnant que les gens semblent penser. La vitesse n’est pas la bonne mesure et la comparaison ici se concentre sur les mauvais coûts. La métrique doit être le degré de confiance fourni pour la quantité de ressources nécessaires pour maintenir le test.

Les tests unitaires réussissent beaucoup moins bien avec cette métrique que la plupart des gens ne le pensent. Le premier problème est qu’ils ne fournissent souvent pas d’informations utiles sur l’état réel du système en cours d’examen. Lorsque les tests unitaires sont écrits en tant que tests d’acceptation, ils sont souvent intimement liés à l’implémentation spécifique.

Ils n’échoueront que si l’implémentation change, pas quand les changements cassent le système (par exemple, vérifier la valeur d’une constante de classe). L’utilisation des tests d’acceptation comme tests de régression doit être faite de manière intentionnelle et réfléchie, en supprimant tout ce qui ne fournit pas d’informations utiles sur le comportement du système.

Un autre problème majeur avec les tests unitaires est que pour tester les entrées d’une méthode, vous devez souvent simuler les réponses des autres méthodes. Lorsque vous faites cela, vous ne testez plus le système que vous avez, vous testez un système que vous supposiez avoir dans le passé. Le système peut tomber en panne et un test unitaire n’échouera pas car il supposait qu’une entrée serait reçue que le système du monde réel ne fournit plus. Le meilleur endroit pour se moquer est au niveau de la couche d’intégration où vous pouvez simuler les deux côtés d’une interface avec des ensembles de tests distincts et utiliser des tests contractuels pour vous assurer que ces simulations représentent correctement l’état réel du système des deux côtés. De plus, se moquer des services appartenant à d’autres sociétés est une bonne pratique, surtout si elles ont une API stable.

En raison de ces éléments, bien qu’ils soient en effet rapides à exécuter, ils ne sont pas nécessairement plus faciles à entretenir. Pour chaque modification de produit, les développeurs doivent faire preuve de diligence pour examiner tous les tests avec des simulations dans la suite de tests pour s’assurer qu’ils s’appliquent toujours. Ensuite, tous les tests qui cassent suite à des changements d’implémentation doivent être mis à jour, même s’ils sont souvent remplacés par des tests tout aussi inutiles pour détecter les régressions futures.

Testez la confiance plutôt que la facilité

Bien que les tests unitaires soient considérés par beaucoup comme la pierre angulaire des meilleures pratiques de développement logiciel, ce n’est pas une panacée pour tous les besoins de test. À mesure que l’industrie évolue et vise des cycles de publication plus courts, elle doit également faire évoluer son approche des tests. Une stratégie de test réussie et continue exige un équilibre minutieux entre les différents types de tests ; au lieu de se concentrer uniquement sur la vitesse d’exécution, les équipes doivent donner la priorité au niveau de confiance que chaque test fournit par rapport au temps et aux efforts investis pour le maintenir précis.

En adoptant une approche de test plus holistique, les équipes peuvent fournir de meilleurs logiciels plus rapidement. Comme pour tant de choses dans la vie, la clé est d’utiliser le bon outil pour le travail, pas seulement l’outil qui est le plus pratique pour le moment. En matière de test, intelligent et stratégique bat la force brute à chaque fois.

Groupe Créé avec Sketch.
www.actusduweb.com
Suivez Actusduweb sur Google News


Ce site utilise des cookies pour améliorer votre expérience. Nous supposerons que cela vous convient, mais vous pouvez vous désinscrire si vous le souhaitez. J'accepte Lire la suite