Python >> Tutoriel Python >  >> Python

Les avantages mesurables des tests unitaires

Les articles faisant l'éloge de l'utilisation des tests unitaires se multiplient. Un peu moins populaires mais toujours facilement accessibles, des articles tenteront de vous convaincre que les tests unitaires sont une perte de temps, du moins dans certains cas.

La plupart d'entre eux (ou peut-être même tous ?) essaient de prouver leurs arguments en se basant sur des sentiments, sur la propre évaluation de l'auteur de ce qui est bon et efficace ou mauvais et inefficace.

Dans cet article, je n'essaierai pas de prouver quel camp a raison.

Au lieu de cela, je vais vous montrer un moyen de mesurer si vous pouvez bénéficier ou non des tests unitaires. Vous apprendrez tous les facteurs dont vous devez tenir compte pour prendre cette décision vous-même.

Qu'est-ce que les tests unitaires ?

En un mot, un test unitaire est un test rapide d'une petite unité . Qu'est-ce qu'une unité dépend du développeur. Il peut s'agir de n'importe quel petit morceau de code testable, comme une méthode ou une classe.

Bien sûr, ce n'est qu'une définition. Certains développeurs définiront les tests unitaires comme "une perte de temps", ce à quoi je dis :ne les embauchez pas . Passons à autre chose...

Les tests unitaires sont des tests de bas niveau. Ils forcent un petit morceau d'application à effectuer une action et ils vérifient le résultat final. Cette action est très simple et les résultats sont indépendants des autres éléments de l'application. L'échec d'un test unitaire montre sans aucun doute quelle partie du code ne fonctionne pas.

De plus, l'exécution de tests unitaires ne nécessite pas que l'application soit en cours d'exécution. Et cela peut être fait avant même que toute l'application ne soit construite.

Ce sont les faits. Les tests unitaires présentent de nombreux autres avantages souvent cités sur le Web, tels que :

  • les tests unitaires permettent de réduire le nombre de bogues dans le logiciel ;
  • les développeurs se sentent plus en confiance pour déployer du code couvert par des tests unitaires ;
  • Les programmeurs qui suivent le processus de développement piloté par les tests (TDD) affirment que les tests unitaires les aident à atteindre leurs objectifs plus rapidement, en résolvant les problèmes avec moins de code et une meilleure architecture de code.

Mais de tels arguments sont soit basés sur des sentiments, soit très difficiles à prouver et pour cette raison, je ne vais pas me concentrer sur eux.

Au lieu de cela, j'aimerais me concentrer sur un élément commun de chaque processus de développement, avec ou sans tests unitaires. A savoir :les bugs.

Les bugs arriveront toujours. La seule différence réside dans le temps que le développeur passera à trouver ces bogues, dans combien de temps il les remarquera. Cela peut être facilement mesuré et comparé, comme je vais vous le montrer ensuite.

Pouvons-nous mesurer si les tests unitaires apportent des avantages ?

Prenons un exemple pour analyser à quoi ressemble le développement avec et sans tests unitaires. Dans notre exemple, au lieu d'une application, nous allons construire une voiture. Au lieu de développeurs, nous travaillerons avec des ingénieurs en électronique.

Nous commençons avec un ingénieur en électronique à qui on a demandé de construire un contrôleur électronique pour une fenêtre de portière de voiture. Il a reçu toute la documentation dont il avait besoin. Après un certain temps, il a construit un contrôleur, selon ses connaissances et la documentation, et le moment est venu de vérifier s'il fonctionne.

Il décide de tester le contrôleur en l'installant dans les portes de la voiture. Cela peut sembler idiot, mais c'est exactement ce à quoi cela ressemble lorsque les développeurs testent leur travail sans tests unitaires.

Comme on pouvait s'y attendre, le contrôleur de la porte de la voiture ne fonctionne pas du premier coup. Peut-être que cela ne fonctionne même pas au deuxième ou au troisième essai, selon la situation. Même lorsque vous travaillez avec des spécialistes, des erreurs se produiront. Ce ne sont que des humains.

Enfin, lors d'un essai ultérieur, le contrôleur fonctionne.

Combien de temps notre ingénieur a-t-il consacré aux tests ?

Voyons voir. L'installation du contrôleur prend installation_time minutes. Les tests manuels prennent testing_time minutes. Il a répété cette séquence n fois - peut-être une fois, peut-être deux fois, peut-être quelques fois de plus - jusqu'à ce que le contrôleur fonctionne. Cela nous donne :

testing_time_without_unit_tests =n * (installation_time + testing_time)

Existe-t-il une autre solution à ce problème ?

Oui. L'ingénieur peut construire un circuit imprimé spécial qui peut effectuer tous les tests automatiquement. Ce tableau est son équivalent des tests unitaires.

Construire une carte lui prendra build_testing_board_time minutes. Cependant, l'exécution de tests avec cette carte est si rapide qu'on peut supposer qu'elle n'est pas pertinente. Au total, la formule devient :

testing_time_with_unit_tests =build_testing_board_time

Vaut-il la peine de construire cette carte ? Ça dépend. Je vais répondre à cette question dans un instant, mais nous devons d'abord ajouter un détail important à notre histoire.

Nous savons que la voiture symbolise un produit logiciel. Et nous savons que les projets informatiques ont au moins une chose en commun :ils changent constamment.

Revenons donc à notre ingénieur et contrôleur électronique. Au début, on a dit à l'ingénieur que le contrôleur devait fonctionner avec deux fenêtres. Mais quelques semaines après la fin de son travail, il s'avère qu'il y a eu un petit changement dans le projet et maintenant notre voiture aura quatre fenêtres.

Ça a l'air drôle, mais c'est généralement ainsi que fonctionnent les projets informatiques. Un petit changement du point de vue d'un client peut avoir d'énormes conséquences du point de vue de l'ingénieur.

Suite à la nouvelle documentation, notre ingénieur fait de son mieux et met à jour le contrôleur. Il l'installe dans la porte et... la nouvelle fonctionnalité ne fonctionne pas au premier essai, ne fonctionne pas au second, et ainsi de suite... Jusqu'à ce que finalement cela fonctionne à nouveau.

Voici la partie qui sépare le meilleur du reste. Un bon ingénieur testera toujours son travail. Mais un ingénieur de haut niveau vérifiera s'il n'a rien cassé d'autre.

Et nous travaillons avec les meilleurs, donc notre ingénieur vérifie si les fonctionnalités précédentes du contrôleur fonctionnent toujours bien. Supposons que certains d'entre eux ne le fassent pas, et notre ingénieur doit faire quelques corrections et plus de tests.

Dans l'ensemble, il passe autant de temps à tester après avoir créé la nouvelle fonctionnalité :

testing_time_without_unit_tests =n * (installation_time + new_feature_testing_time) + previous_feature_testing_time

Comment la situation changerait-elle avec un tableau de test ? L'ingénieur passerait extension_time minutes de mise à niveau de la carte de test. Et puis il testait simultanément les anciennes et les nouvelles fonctionnalités dans un temps si court qu'il n'était pas pertinent, bien sûr dans n itérations parce que des erreurs se produisent. Cela nous donne :

testing_time_with_unit_tests =n * testing_time + extension_time

Mais étant donné que testing_time est presque instantané en utilisant la carte de test, nous pouvons supposer que cette valeur est 0, ce qui aboutit finalement :

testing_time_with_unit_tests =extension_time

Demandez-vous maintenant :que va-t-il se passer lorsque nous ajouterons une troisième, quatrième ou n-ième fonctionnalité ?

Sans tests unitaires, chaque nouvelle fonctionnalité prolonge le temps de test car toutes les fonctionnalités précédentes doivent être testées manuellement pour la compatibilité. Si vous avez mis en place des tests unitaires, les fonctionnalités précédentes peuvent être testées presque instantanément.

De plus, un manque de tests unitaires rend difficile la prévision de la durée finale des tests. Le développeur peut estimer combien de temps il consacrera à la création d'une nouvelle fonctionnalité, mais personne ne sait combien d'itérations seront nécessaires pour les tests pendant le développement, ni combien de conflits avec les fonctionnalités précédentes seront créés.

D'un autre côté, avec les tests unitaires, la vie est beaucoup plus facile. Un ingénieur peut facilement déterminer le temps dont il a besoin pour créer de nouveaux tests unitaires.

Dans ce cas, le temps de test pendant le développement n'est pas pertinent. Le temps passé à corriger les bogues est le même que sans les tests unitaires. Mais ce que nous obtenons, c'est plus de prévisibilité au cas où des bogues surviendraient pendant le développement et moins d'argent dépensé en temps de test manuel.

Avec les tests unitaires, vous pouvez également améliorer le travail parallèle. Il n'est pas nécessaire d'attendre que la voiture soit entièrement assemblée pour tester le contrôleur de fenêtre. Il peut être testé à l'aide du tableau de test avant la construction de la voiture.

Ai-je besoin de tests unitaires ?

Comme indiqué dans la section précédente, créer des tests unitaires :

  1. prend du temps, mais…
  2. vous fait gagner du temps sur les tests pendant le processus de développement.

Laquelle des deux offre la plus grande valeur (le temps passé à créer des tests unitaires ou le temps gagné sur les tests) dépend de votre projet.

Certains facteurs peuvent indiquer que votre projet nécessite des tests unitaires :

  • votre projet grandira avec le temps,
  • vos fonctionnalités sont complexes,
  • les bogues dans votre projet peuvent vous coûter très cher,
  • un délai de mise sur le marché prévisible est crucial pour votre projet.

Si votre projet correspond à l'un des éléments ci-dessus, vous bénéficierez des tests unitaires. Plus il y a de facteurs adaptés, plus les tests unitaires vous aideront.

Mais attendez, j'utilise déjà des tests automatisés. Ils font la même chose, non ?

Pas exactement.

Il existe différents types de tests pour différents objectifs :

  • tests de composants vérifier le fonctionnement d'un composant complet (composé de plusieurs unités) ;
  • tests d'intégration vérifier comment un composant fonctionne avec d'autres composants ;
  • tests automatisés vérifier les chemins cruciaux dans l'ensemble de l'application.

Tous sont, à proprement parler, automatisés. Ils permettent tous de gagner du temps de la même manière que les tests unitaires :vous passez du temps à créer les tests pour passer moins de temps sur les tests manuels.

Alors pourquoi devrais-je créer des tests unitaires alors que j'ai ces tests ?

La réponse est simple :pour couvrir les niveaux de test élevés et bas.

Les tests automatisés sont des tests de haut niveau. Ils utilisent l'interface disponible pour forcer l'application à effectuer une action, puis ils vérifient le résultat final. Très souvent, cette action peut être complexe. Il peut invoquer de nombreuses petites étapes avant d'atteindre l'état final. Chacune de ces étapes peut échouer.

Ainsi, le résultat final de chaque test automatisé dépend de nombreux composants plus petits et il est difficile de dire lequel d'entre eux a échoué. Il indique seulement qu'un scénario ne fonctionne pas ou qu'un élément ne fonctionne pas correctement avec un autre élément.

Les tests unitaires sont des tests de bas niveau. Ils indiquent exactement quelle unité et quelle partie de cette unité ne fonctionne pas correctement. Ces informations permettent de trouver la source des bogues beaucoup plus rapidement et plus facilement.

Conclusion

Les tests unitaires présentent de nombreux avantages. Je me suis concentré uniquement sur ceux qui peuvent être facilement mesurés et comparés. J'ai souligné les facteurs qui peuvent vous dire si vous tirerez profit des tests unitaires.

Bien sûr, les projets sont aussi divers que les personnes qui y travaillent et chacun doit être analysé individuellement. Mais si vous gardez à l'esprit les valeurs ci-dessus (des valeurs numériques, pas des valeurs émotionnelles élevées), vous aurez alors une boussole à suivre.

Merci d'avoir pris le temps de lire ceci. Si vous avez des questions auxquelles je pourrais répondre, n'hésitez pas à laisser un commentaire.

Vous êtes curieux de connaître nos services de test de logiciels ? En savoir plus ici.