Tests : enjeux et bonnes pratiques dans un projet informatique

ELEPHANT Technologies
2026-03-26

Chez ELEPHANT Technologies, nous mettons tout en place pour aider nos ingénieurs hardware, embarqué, software et web à atteindre leurs objectifs. Travailler dans notre équipe, c’est rejoindre une ESN engagée, experte et humaine.

Dans cet article nous allons évoquer le sujet des tests et leur importance capitale au sein d'un projet informatique.  

Pour commencer voici la définition d’un “test”, proposée par l'Insee : « Le test consiste à exécuter et évaluer un système ou un composant sous des conditions spécifiques, pour vérifier qu’il répond à ses spécifications ou pour identifier des différences entre les résultats spécifiés et attendus et les résultats effectivement obtenus » (IEEE, 1990)

En résumé, le but d'un test, dans le cadre d’un projet informatique, est de tester une fonctionnalité de l'application afin d’en comparer un résultat obtenu et un résultat attendu. Il permet aussi de déceler des anomalies afin d'en améliorer la qualité.  

Au sein d'un projet informatique, il existe 3 types de tests majeurs :

  • Tests unitaires ;
  • Tests fonctionnels ;
  • Tests automatisés.

Les tests unitaires

Le fonctionnement d'un test unitaire est simple. Au sein de l'application, une classe est créée, dans laquelle nous allons faire appel à différentes fonctions tout en simulant les données en entrée. Le résultat obtenu est alors comparé au résultat attendu. La classe est composée d'une multitude de fonctions dont chacune d'entre elles va tester une ou plusieurs fonctionnalités et va effectuer la comparaison.

Les tests unitaires sont à la charge du développeur. En effet, lorsqu'une nouvelle fonctionnalité est mise en place par un développeur, il est de sa responsabilité, contractuelle ou non, de la tester.

Dans le cadre des tests unitaires, on entend beaucoup parler du Framework Mockito mais aussi du JUnit. Ces outils ont pour but de faciliter la mise en place des cas tests au niveau des jeux de données mais aussi la comparaison des résultats.

Afin d’être plus explicite, prenons l’exemple d’une voiture qui va nous servir d’analogie pour les tests unitaires, fonctionnels mais aussi automatisés.

Partons du principe que notre voiture est l'égal d'une application web : la carrosserie, les compteurs, tout ce qui appartient à l’extérieur est le front, donc ce que l'utilisateur voit au travers de son navigateur web. Le moteur, les câbles, etc., sont quant à eux, ce que l’on appelle le back, c’est-à-dire l’application contenant le code.

Dans cette analogie les tests unitaires seraient une sorte de petit boîtier branché directement au moteur ou à certains câbles. Ce boîtier enverrait des impulsions permettant de simuler l'utilisation de la voiture.  

Par exemple, si on souhaite accélérer, on va simuler, via ce petit boitier, l’appui de la pédale directement sur le moteur. On pourra ainsi constater si oui ou non le moteur monte dans les tours en raison de l’accélérateur.

Concrètement, les tests unitaires ont une place capitale au sein d’une application informatique. Ils permettent de tester les différents cas nominaux de l'application, de constituer une banque de tests de non-régression.  Ainsi lorsqu'une nouvelle fonctionnalité est déployée, l'ensemble des tests unitaires précédents vont être joués afin de déterminer si le nouveau code n'impacte pas le fonctionnement des anciennes fonctionnalités.

Aujourd’hui, dans la plupart des projets, les tests unitaires sont faits a posteriori du développement. De nombreuses études ont démontré que cette pratique n'est pas optimale. En effet, de façon consciente ou non, la personne aura tendance à orienter ces tests unitaires afin qu'ils ne posent pas de problème. Le risque est de passer à côté de bug ou d’un cas dont les limites ne seraient pas traitées par le développement.

La méthodologie TDD (Test-Driven Development) permet de pallier ces problèmes. Le principe est de commencer par les tests unitaires, puis d’effectuer le développement de la fonctionnalité.  

De ce fait, on pose directement les valeurs en entrée ainsi que le résultat attendu en partant du principe que la fonctionnalité n'est qu'une simple boîte noire dont le traitement nous permettra d'obtenir le résultat voulu. On peut dès lors poser tous les cas nominaux et les cas aux limites possibles. Le développement de la fonctionnalité devra répondre à tous ces critères.

Il sera toujours important de bien commenter les méthodes de tests afin de faciliter la compréhension des développeurs qui auront à les modifier dans le futur. On essayera donc toujours d’expliquer quelle partie du code est testée, sous quelles conditions, et quels sont les résultats attendus.

La structure des tests unitaires s'axe autour de trois blocs principaux, souvent délimités par des commentaires pour simplifier la lecture du test :

  • Prepare (point) : la première partie du test où l'on va créer les données passées en entrée de notre test et toutes les données renvoyées par des méthodes mockées.
  • Execute : la seconde partie, aussi appelée méthode testée, nous permet de récupérer le résultat du test.
  • Assert : dans la dernière partie, on effectue notre batterie de tests, sans oublier, si certains peuvent paraître obscurs, de les expliquer en commentaires.

Généralement, l'organisation est de retrouver dans un même fichier les tests provenant de méthodes, elles-mêmes dans un même fichier.  Mais attention, on se retrouve avec plusieurs tests dans le même fichier de tests, qui seront lancés à la suite. Voilà pourquoi il faut faire attention à ce qu’entre deux tests, on retourne toujours dans les conditions initiales, et qu’aucun test ne modifie le comportement d’un autre en changeant par exemple une variable globale.

Pour lire ou modifier une base de données fondant des tests de méthodes, il ne faut JAMAIS prendre la base utilisée normalement par l’application. Cela évite que les données en base ne changent et que le test ne soit en échec suite à des manipulations de données.  

On va donc créer des mini bases de données, par exemple des .xml, remplies à la main et regroupant juste les données dont on a besoin pour vérifier nos tests. Encore une fois, on retourne toujours dans les conditions initiales avant chaque test pour s’assurer qu’aucun test ne modifie le comportement d’un autre en modifiant la base de données avant son exécution.

Certes, les tests unitaires sont importants, mais tester pour tester n’est pas une bonne stratégie. Obtenir une couverture de 100% est impossible et faire des tests de getter / setter est très souvent inutile.  

En revanche, on exécute la méthode une seule fois par test, donc si le test écrit ne suffit pas à couvrir entièrement la méthode, il ne faut pas hésiter à faire plusieurs tests pour couvrir cette dernière, en faisant attention à utiliser des noms clairs et explicites.

Les tests fonctionnels

Les tests fonctionnels interviennent une fois que le développement de la fonctionnalité et ces tests unitaires sont établis. Cependant, contrairement aux tests unitaires, ces tests sont faits directement via l'application. On retrouve différentes étapes dans le test et aussi un résultat attendu.  

Pour reprendre notre analogie de la voiture, le test fonctionnel pourrait correspondre au fait d’appuyer sur la pédale d’accélérateur et de constater si le compte-tours augmente ou non.

Ici, les différents cas de tests pourront donc être une accélération franche, modérée ou de ne pas accélérer du tout. Le résultat devrait ainsi pouvoir être constaté sur le compte-tour.

Les tests fonctionnels sont divisés en deux étapes principales. D'abord la préparation qualification avec la mise en place de différents cas de tests et des différents résultats attendus avant même que la fonctionnalité soit développée. Puis une fois la fonctionnalité disponible, on passe à l'étape de la qualification. Une personne référente fonctionnelle déroule les différents cas de tests et vérifie que les résultats obtenus sont en adéquation avec les résultats attendus lors de la préparation de la qualification. Idéalement les deux étapes sont réalisées par deux personnes différentes pour éviter tout biais dans les résultats.

Lors de ces tests fonctionnels on peut déceler une erreur dans le développement de la nouvelle fonctionnalité mais on pourra aussi constater de nouveaux bugs ou nouvelles anomalies en dehors du périmètre de la fonctionnalité et ceux de manière fortuite.

Les tests automatisés

Pour terminer, intéressons-nous aux tests automatisés, qui se rapprochent d’ailleurs des tests fonctionnels. Ils ont eux aussi un cas de test avec différentes étapes à respecter et un résultat attendu à correspondre. Mais à l'instar des tests fonctionnels où une personne physique établit les différentes actions pour respecter le test ici dans les tests automatisés c'est une application qui va simuler l’utilisation de l’application.  

Des outils comme Cucumber permettent de simuler des clics souris ou encore des touches clavier. Pour reprendre l’exemple de la voiture ce n'est plus une personne à la place du conducteur qui va appuyer sur la pédale d'accélération mais plutôt une sorte de robot qui va s'en charger. Contrairement aux tests fonctionnels, le test automatisé va respecter le cas de test à la lettre. Au fil des différents tests automatisés misent en place, une banque de tests se constitue afin de s'assurer qu’au cours des futurs développements les anciennes fonctionnalités sont toujours opérationnelles.

Contrairement aux tests unitaires où la base de données doit être réinitialisée avant chaque test, il est souvent intéressant pour les tests automatisés de conserver les données créées lors des tests précédents car elles sont utilisées par la suite dans d’autres tests. Elles peuvent aussi permettre d’accéder à une autre fonctionnalité de l’application, qui serait bloquée autrement.

Conclusion

Pour clôturer sur le cycle de vie des différents tests au sein d’un projet informatique, il faut bien retenir qu'ils sont une composante essentielle si ce n'est prioritaire. Bien que chronophages et compliqués à mettre en œuvre au fur et à mesure que l'application étend ses fonctionnalités, les tests permettent d'assurer une utilisation pérenne de l'application.  

Ils apportent de nombreux avantages pour un projet informatique. En effet, les différents bugs et anomalies rencontrées pourront être traités directement à la source du problème.  
Ils permettent également de réduire les coûts de correction car une anomalie traitée avant même la mise en production coûtera logiquement moins chère. Ce n'est pas pour rien que de façon contractuelle un pourcentage de couverture de code est attendu des entreprises.  

Partager l’article
Qualité logicielle
ELEPHANT Technologies
2026-03-26