Tests : bonnes pratiques et astuces pour développeurs

On le sait tous, les tests sont essentiels pour garantir la qualité, la performance et la sécurité des logiciels pourtant beaucoup de gens les négligent. Ils englobent diverses techniques, du test unitaire, qui vérifie chaque composant individuellement, aux tests automatisés, qui contrôlent les régressions, en passant par les tests d’intégration et de performances qui assurent la cohésion et la robustesse de l'ensemble.
Les tests sont indépendants du langage de programmation et comme chez FTEL nous utilisons C#, les exemples de cet article seront faits en C#.

Qu'est-ce qu'un test ?

Dans le contexte du développement d'applications web et mobile, un test est un terme englobant de nombreuses méthodes et approches visant à évaluer la qualité d'un logiciel. Les tests sont une étape cruciale que tout le monde dans l'équipe de développement doit intégrer, bien que la responsabilité ultime soit celle du testeur QA (Quality Assurance). Comme son nom l'indique, l'objectif des tests est de soumettre une application à une batterie d'évaluations rigoureuses afin de limiter l’apparition de défaillances. Cette qualité englobe non seulement la validation fonctionnelle, s'assurant que chaque fonctionnalité de l'application fonctionne comme prévu, mais aussi la validation visuelle, vérifiant que tous les éléments de l'interface utilisateur sont correctement alignés et esthétiquement conformes aux spécifications. 

La qualité d'une application ne se limite pas à son apparence et à sa fonctionnalité de base. Elle comprend également des aspects essentiels (et oubliés) tels que l'accessibilité. Tester une application signifie aussi s'assurer que toutes les fonctionnalités sont accessibles aux utilisateurs ayant des handicaps, conformément aux normes d'accessibilité en vigueur.

Les tests unitaires et d'intégration

Les tests unitaires

Les tests unitaires et d'intégration sont des piliers essentiels pour garantir la qualité des applications web et mobiles. Les tests unitaires se concentrent sur la vérification de la plus petite partie testable d'une application, généralement une seule fonction ou méthode, pour s'assurer qu'elle fonctionne correctement de manière isolée.

Afin d’écrire ces tests dans de bonnes conditions, les développeurs utilisent des frameworks comme xUnit, qui fournit une structure robuste et flexible pour écrire et exécuter des tests unitaires en .NET.

En supplément, la structure "Given-When-Then" est couramment utilisée dans l'écriture de tests pour garantir la clarté et l'organisation. 

  • Given (Précondition) : Définir le contexte initial et préparer l'état du système et/ou les données nécessaires.
  • When (Action) : Exécuter l'action ou la méthode que vous souhaitez tester.
  • Then (Vérification) : Vérifier les résultats de l'action exécutée pour s'assurer que le système se comporte comme attendu.

Exemple d'un test simple

Tester son code
Tester code

Lors de l'écriture de ces tests, il est nécessaire d’isoler les composants, les développeurs utilisent souvent des techniques de mocking (Le mocking est le fait de simuler des objets ainsi que leur comportement afin de se dissocier de la réelle implémentation). On peut se permettre de mocker tout appel externe car on suppose que tout est censé être testé, donc tout ce qui est mocké est considéré comme fonctionnel. NSubstitute est un framework de mocking populaire qui permet de créer des objets substituts pour imiter le comportement des dépendances réelles, facilitant ainsi la validation de l'intégration sans avoir besoin des composants externes réels.

Exemple d'un test avec un service mocké

Tester code
Tester code

Il est souvent important de créer des données de test réalistes et en quantité. C'est ici qu'interviennent des outils tels que Bogus, qui permet de générer rapidement des données factices cohérentes et diversifiées, facilitant ainsi la création de scénarios de test plus représentatifs.

Exemple de création de 20 livres avec Bogus

Tester code

Les tests d'intégration

En parallèle, les tests d'intégration vérifient que différents modules ou services de l'application fonctionnent correctement ensemble. Le but de ces tests étant le comportement dans un écosystème, il est idéal de ne pas mocker les dépendances pour avoir une fonction similaire à celui de l’application réelle.

Dans tous les cas, pour s'assurer que les résultats des tests soient clairs et précis, Fluent Assertions est un outil précieux qui offre une syntaxe fluide et expressive pour écrire des assertions, rendant les tests plus lisibles et maintenables.

Exemple d'un test avec et sans fluentassertions

Tester code
Tester code

Ensemble, ces outils et pratiques permettent de créer des tests unitaires et d'intégration efficaces, garantissant que chaque partie de l'application, ainsi que leur interaction, fonctionnent comme prévu. 

Les tests manuels et automatisés

Les tests manuels jouent un rôle crucial dans l'assurance qualité des applications web et mobiles. Ils comprennent des méthodes comme les tests exploratoires, où les testeurs utilisent l'application de manière intuitive pour découvrir des problèmes imprévus, et l'exécution du cahier des charges, qui consiste à vérifier que chaque fonctionnalité spécifiée est correctement implémentée. Les tests manuels permettent une compréhension approfondie et contextuelle de l'application, souvent identifiant des bugs subtils et des problèmes d'expérience utilisateur.

Cependant, les tests manuels peuvent être chronophages et répétitifs, surtout lors des phases de régression où les mêmes tests doivent être exécutés à chaque nouvelle version de l'application (coucou SCRUM). Pour remédier à cette inefficacité, l'automatisation des tests devient essentielle. Selenium est un outil puissant qui permet d'automatiser les interactions utilisateur avec l'application. En créant des scripts qui reproduisent les clics, les saisies et les navigations de l'utilisateur, Selenium peut exécuter rapidement des tests exhaustifs à chaque itération de développement. Cette automatisation libère du temps pour les testeurs, leur permettant de se concentrer sur des aspects plus complexes et créatifs des tests manuels, tout en garantissant que les tests de régression sont effectués de manière efficace et fiable.

Exemple d’un script Selenium pour le login

Tester code

Pour conclure ⬇

Si vous mettez un point d’honneur à la qualité des applications que vous produisez pour vos clients, l’implémentation d’une stratégie d’assurance qualité est importante. Cela peut aller de la simple augmentation de la quantité de tests manuels à l'implémentation de tous les tests cités précédemment dans votre pipeline CI/CD. Cela pourrait s’avérer judicieux afin d’éviter les douloureuses régressions lors de votre prochain lot d’évolutions. 

        L'équipe FTEL