Ma réponse à ceux qui croient que la valeur du TDD est exagérée

Une fois, j'ai parlé à un développeur d'une entreprise cliente de logiciels. Je dois comprendre que la conversation a mal tourné lorsque l'interlocuteur a expliqué comment nous, les développeurs de logiciels, avons eu de la chance: «Nous incitons les organisations à nous payer pour ce qui semble être un travail simple.» Peu importe les progrès réalisés par quelqu'un en matière d'écriture de code, mais je pense que cela ne vaut pas la peine de parler de l'ensemble de l'industrie du développement logiciel comme d'une bande de fraudeurs.

Je ne me suis pas concentré sur cela, la conversation est arrivée à Agile. Le client, en général, était ouvert à l'idée de tester de nouvelles méthodologies et d'améliorer leurs processus de travail. Mais - jusqu'à ce que je mentionne le développement par le biais de tests (TDD, Test-Driven Development). La seule réponse à cela était la phrase suivante: "La valeur TDD est exagérée."



Non seulement cela m'a été douloureux de l'entendre, mais cela m'a fait réaliser que TDD est une autre de ces méthodologies Agiles qui pourraient ressembler à quelque chose comme des «légendes urbaines». C'est ce qui m'a fait écrire ce document, dans lequel je voudrais faire appel à ceux qui doutent de la valeur de TDD.

Qu'est-ce que TDD?


Permettez-moi de commencer par définir TDD. Il s'agit d'une stratégie de développement logiciel, lors de la mise en œuvre de laquelle, lors de la création d'un programme, ils sont entièrement guidés par la rédaction de tests. En fait, cela est compréhensible du nom de cette méthodologie. Cette idée a été proposée par Kent Beck dans son livre Development Through Testing, qui a été écrit en 2003. L'utilisation de TDD implique les trois étapes suivantes:

  1. Écriture d'un test qui échoue pour un petit morceau de fonctionnalité.
  2. Implémentation de la fonctionnalité qui mène à la réussite du test.
  3. Refactorisation de l'ancien et du nouveau code afin de le maintenir dans un état bien structuré et lisible.

Ce processus est également connu sous le nom de cycle «Red, Green, Refactoring».

Voici un exemple simple d'utilisation de TDD. Ici, nous voulons écrire une méthode en Python qui est conçue pour calculer une variable Cpar le théorème de Pythagore.

Voici le code de test (fichier test.py):

#!/usr/bin/env python

"""
test.py
"""

import unittest

from main import *

class TestDrivenDevelopment(unittest.TestCase):

        def test_pythagorean_theorem(self):
                a, b = 3, 4
                self.assertEqual(calculate_side_c(a, b), 5)

if __name__ == '__main__':
    unittest.main()

Voici le code de méthode ( main.py), dans lequel rien ne se passe jusqu'à présent:

#!/usr/bin/env python

"""
main.py
"""

def calculate_side_c(side_a, side_b):
    return True

Essayez maintenant d'exécuter le test.


Le test a échoué (la partie "rouge" du cycle TDD)

Réécrivez le code en amenant le contenumain.pysous la forme suivante:

#!/usr/bin/env python

"""
main.py
"""

def calculate_side_c(side_a, side_b):
    c_squared = (side_a * side_a) + (side_b * side_b)
    c = c_squared ** 0.5
    return c 

Relancez le test.


Le test s'est bien passé (la partie «verte» du cycle TDD)

Maintenant nousmain.pyrefactorisons lecode:

#!/usr/bin/env python

"""
main.py
"""

def calculate_side_c(side_a, side_b):
    return ((side_a ** 2) + (side_b ** 2)) ** 0.5


Le test a été réussi pour le code soumis au refactoring (partie «Refactoring» du cycle TDD)

17 ans se sont écoulés depuis la publication du livre de développement par le biais de tests. Mais même aujourd'hui, en 2020, il n'y a toujours pas de réponse définitive à la question très importante pour de nombreuses personnes de savoir si les avantages du TDD valent le temps et les efforts nécessaires pour mettre en œuvre cette méthodologie. En conséquence, de nombreux développeurs n'essaient même pas de se développer par le biais de tests.

À l'appui de TDD, j'ai demandé aux développeurs pourquoi ils n'avaient pas utilisé cette méthodologie. Voici 4 réponses que j'ai entendues le plus souvent:

  1. Nous avons un département QA. Écrire des tests, c'est leur travail.
  2. La création de tests dans lesquels des moki et des talons peuvent être nécessaires peut prendre beaucoup de temps et d'énergie.
  3. TDD n'a aucun avantage sur le développement conventionnel.
  4. TDD est lent.

Analysons ces idées.

Nous avons un département QA. Écrire des tests, c'est leur métier


Cette réponse à ma question sur pourquoi quelqu'un n'utilise pas TDD me fera toujours rire un peu. Je suis un grand partisan du principe « Vous le construisez, vous l'exécutez », lorsque celui qui a écrit le code en est responsable. Par conséquent, cela me dérange quand je vois que les développeurs se comportent comme si leur seule tâche était d'écrire du code fonctionnel.

Je suis profondément convaincu que les développeurs sont responsables de s'assurer que leur code a les qualités suivantes:

  • Exactitude - répondre aux besoins de l'entreprise.
  • Clarté.
  • Testabilité.
  • Extensibilité.
  • Simplicité.

Le transfert de la tâche de rédaction des tests au département QA, je crois, n'appartient pas à la liste des responsabilités du développeur. Les spécialistes du département AQ ont des questions plus importantes. Ils ne devraient pas consacrer leur temps de travail, principalement, à tester le code en utilisant la méthode de la "boîte noire".

Créer des tests dans lesquels des moki et des talons peuvent être nécessaires peut prendre beaucoup de temps et d'énergie


Je comprends les sentiments de ceux qui le disent. Par exemple, vous devez implémenter une méthode qui prend trois valeurs d'entrée différentes. Chacun d'eux est un objet, et chacun de ces objets n'a pas d'attributs facultatifs. Tout cela doit être testé en vérifiant les différentes options de la méthode. Pour ce faire, vous devez configurer des stubs et des mokas , ainsi qu'écrire une grande quantité de code supplémentaire. Et tout cela pour tester une seule méthode. J'ai déjà été dans des situations similaires. Mais je vois tout cela sous un autre angle.

Quand je pense à réduire l'effort et le temps passé à écrire des tests, je trouve les principes de la programmation SOLIDE et la pyramide des tests.

Commencez avec SOLID à partir d'ici.. Ici, je voudrais m'attarder sur le fait que dans l'abréviation SOLID est représenté par la lettre S, c'est-à-dire sur le principe de la responsabilité unique (le principe de responsabilité unique). C'est une idée selon laquelle les méthodes et les classes devraient résoudre un seul problème. Ils doivent fonctionner pour que leurs activités n'affectent pas le reste du système.

Je comprends que la plupart des méthodes des logiciels d'entreprise effectuent des tâches plus difficiles que de trouver la somme de plusieurs nombres passés à ces méthodes. Mais on ne peut nier le fait que l'utilisation de méthodes visant à résoudre un problème dans un projet facilite grandement les tests.

Parlons de la pyramide des tests.


Pyramide de test (image prise à partir d'ici )

La pyramide de test est souvent utilisée pour trouver le bon ratio de différents types de tests dans un projet.

Les tests d'interface utilisateur (tests d'interface utilisateur) et les tests de service (tests de service) nécessitent beaucoup de temps pour leur implémentation. Par conséquent, la majeure partie des tests doit être représentée par des tests unitaires (tests unitaires), car il faut des millisecondes pour exécuter même un grand nombre de ces tests. Cela, bien sûr, contribue à améliorer la boucle de rétroaction, qui est l'un des principaux objectifs de DevOps.

La réalisation de tests unitaires pour tester une petite partie du système nécessite également un niveau d'intégration beaucoup plus faible avec le reste du système. Cela facilite l'écriture de tels tests. La méthodologie TDD est conçue exclusivement pour l'utilisation de tests unitaires.

Bien sûr, tout est plus facile à dire qu'à faire, et pour écrire la plupart des tests, même les tests unitaires, vous devez faire des efforts. Cependant, s'il semble que la rédaction d'un test unitaire demande trop d'efforts, vous pouvez vous tester en vous posant quelques questions:

  • S'agit-il d'un test modulaire ou doit-il être considéré comme un test de niveau supérieur, comme un test de service?
  • Le code est-il bien conçu, chaque classe et chaque méthode sont-elles conformes au principe de la responsabilité exclusive (le code est-il très étroitement couplé)?

S'il s'avère que l'écriture des tests prend trop de temps et d'efforts, cela indique le plus souvent que le code peut et doit probablement être refactorisé.

TDD n'a aucun avantage sur le développement conventionnel


Ironiquement, le fait que TDD n'a aucun avantage sur le développement conventionnel est principalement dit par les programmeurs qui n'ont même pas essayé de travailler dans le style TDD. Mais jusqu'à ce que vous essayiez quelque chose, vous ne pouvez pas comprendre si c'est bon ou mauvais. Même le groupe Coldplay sait que "si vous n'essayez jamais, vous ne le saurez jamais".

TDD a deux points forts.

Le premier avantage du TDD est assez évident. Si, avant d'écrire un code de travail, quelqu'un écrit toujours des tests pour ce code, alors, par définition, le programmeur a toujours un code d'auto-test à sa disposition. Voici ce que Martin Fowler écrit à ce sujet: «Vous avez un code d'auto-test si vous pouvez exécuter une séquence de tests automatisés sur une base de code et, une fois les tests terminés avec succès, vous pouvez être sûr que le code est exempt de défauts importants.»

En d'autres termes, l'utilisation de TDD signifie que le code fonctionne exactement comme le programmeur a besoin.

C'est un fait merveilleux, car cela donne une confiance sérieuse dans la stabilité du code à tout changement défavorable. L'utilisation de TDD permet au programmeur de savoir instantanément si quelque chose dans la base de code s'est détérioré à la suite d'une refactorisation ou d'une extension du code. Mieux encore, il vous permet de savoir s'il y a des erreurs dans le système.

Le code autotesté permet aux équipes de développement de tirer pleinement parti des avantages des systèmes d' intégration continue et de déploiement de code.

Le deuxième avantage principal de TDD est que cette méthodologie de développement fait que les programmeurs, avant même d'écrire du code de travail, réfléchissent à ce qu'ils vont écrire et comment ils vont l'écrire.

Réfléchir au code avant de l'écrire conduit au fait que le développeur est vraiment immergé dans l'essence des besoins de l'entreprise et prend en compte les cas limites et les difficultés éventuelles dans la mise en œuvre des mécanismes appropriés. Par conséquent, lors de l'écriture de code de travail, l'effort est dépensé sur exactement ce dont vous avez besoin. En outre, l'utilisation de TDD conduit au fait que les développeurs envisagent un futur système de dispositifs en termes de structure et d'architecture. Si de telles choses sont planifiées et prises en compte dès le début des travaux sur le système, cela améliorera considérablement sa capacité à évoluer et à se développer.

TDD est lent


Les développeurs qui disent que TDD est lent, généralement ceux qui ont utilisé cette méthodologie pendant un certain temps, puis sont revenus à l'écriture de tests qui ont été exécutés après la création du code. En général, c'est la raison la plus souvent invoquée pour expliquer pourquoi quelqu'un n'utilise pas TDD.

Je peux également comprendre pourquoi les programmeurs le pensent. Penser au code avant de l'écrire prend du temps. Du temps est consacré à la création de tests pour tout ce qui doit être implémenté, même pour les méthodes pour lesquelles, dans des conditions normales, les tests peuvent ne pas avoir été écrits. Trouver des moyens d'utiliser efficacement les talons et les mobs peut parfois ne pas être la tâche la plus rapide et la plus agréable.

La situation est également aggravée par le fait que la productivité et l'efficacité des programmeurs sont souvent évaluées en fonction de la vitesse de leur travail et du temps consacré à la création du produit fini. Tout cela pousse l'équipe de programmeurs au désir de travailler le plus rapidement possible, au désir de s'intégrer dans les horaires de travail serrés.

Dans cet article, le système des quatre indicateurs pour évaluer l'efficacité de DevOps:

  1. Fréquence de déploiement.
  2. Modifier le temps d'exécution.
  3. Temps de récupération du service.
  4. La fréquence des échecs avec changements.

Je suis particulièrement intéressé par les indicateurs «Fréquence de déploiement» et «Fréquence de défaillance avec changements».

Lorsque j'utilise TDD, comme je l'ai dit, en supposant que le système a été construit exclusivement à l'aide de TDD, l'équipe de développement, immédiatement après avoir apporté une modification au système, saura si cette modification n'a pas affecté les performances de tout des parties du système. L'utilisation de TDD, en outre, augmente la vitesse de détection des erreurs. Le fait que les tests soient conçus pour tester de très petits fragments de code vous permet de retrouver très rapidement l'endroit du projet où la panne s'est produite. Cela conduit au fait que les erreurs sont moins susceptibles d'être détectées dans une version mise à jour du système déjà déployée, ce qui réduit le taux de «taux d'échec lors des modifications».

Le fait que l'équipe de développement ait un haut niveau de confiance dans la durabilité du projet et dans son bon travail signifie que l'équipe peut décider de déployer le projet une fois les tests réussis. Quelqu'un a-t-il fait un déploiement de projet à la demande?

Le projet Phoenix couvre quatre types de travaux. L'un d'eux est le travail inattendu. Un tel travail doit être fait lorsque les développeurs doivent se départir de ce qu'ils font et faire autre chose. Habituellement, une correction d'une sorte d'erreur. Si le projet est construit à partir de code d'auto-test, cela minimise le nombre d'erreurs. Ceci, à son tour, conduit à minimiser la quantité de «travail inattendu». Et moins il y a de telles «surprises» dans la vie du développeur - mieux il se sent et plus il est productif et meilleur.

Si les développeurs peuvent moins se soucier des bogues en production, cela signifie qu'ils peuvent consacrer plus de temps au développement de nouvelles fonctionnalités utiles du produit. Et si les développeurs réfléchissent au code à l'avance, appliquent des principes utiles comme SOLID et s'engagent constamment dans le refactoring, cela minimise le montant de la «dette technique». Lorsqu'une équipe est confiante dans la fonctionnalité et la qualité du code, elle peut littéralement le déployer en deux temps. Tout cela augmente la vitesse de travail.

Sommaire


Comme tout autre outil, comme toute autre approche de développement, la méthodologie TDD peut sembler maladroite au premier abord. Et avant que les programmeurs maîtrisent correctement cette méthodologie, cela peut leur sembler un peu lent. Que puis-je dire? Pour citer Jez Humble: «Si quelque chose cause de l'inconfort, faites-le plus souvent et vous pouvez le gérer.»

Et maintenant, je vous suggère de pratiquer la méthodologie TDD et de le faire jusqu'à ce que le TDD cesse de vous gêner :)

Chers lecteurs! Utilisez-vous la méthodologie TDD lorsque vous travaillez sur vos projets?

Source: https://habr.com/ru/post/undefined/


All Articles