web-dev-qa-db-fra.com

Méthodologie: Écriture de tests unitaires pour un autre développeur

Je pensais au développement de logiciels et à l'écriture de tests unitaires. J'ai eu l'idée suivante:

Supposons que nous ayons des paires de développeurs. Chaque paire est responsable d'une partie du code. L'un de la paire implémente une fonctionnalité (écriture de code) et le second écrit un test unitaire pour cela. Les tests sont écrits après le code. Dans mon idée, ils s'entraident, mais travaillent plutôt séparément. Idéalement, ils travailleraient sur deux fonctionnalités de taille similaire, puis échangeraient pour la préparation du test.

Je pense que cette idée a quelques avantages:

  • les tests sont écrits par quelqu'un, qui peut en savoir plus sur la mise en œuvre,
  • le travail doit être fait un peu plus vite que la programmation en binôme (deux fonctionnalités en même temps),
  • les tests et le code en ont la personne responsable,
  • le code est testé par au moins deux personnes, et
  • peut-être que la recherche d'erreurs dans le code écrit par une personne qui teste votre code donnerait une motivation particulière pour écrire un meilleur code et éviter de couper les coins ronds.

Peut-être que c'est aussi une bonne idée d'ajouter un autre développeur pour la révision du code entre le code et le développement des tests.

Quels sont les inconvénients de cette idée? Est-il déjà décrit comme une méthodologie inconnue et utilisé dans le développement de logiciels?

PS. Je ne suis pas un chef de projet professionnel, mais je sais quelque chose sur les processus de développement de projet et je connais les quelques méthodologies les plus populaires - mais cette idée ne me semble pas familière.

28
franiis

L'approche générale consistant à utiliser des paires pour diviser l'effort d'écriture de code de production et d'écriture des tests unitaires associés n'est pas rare. Je me suis même personnellement associé de cette manière auparavant avec un succès décent. Cependant, une ligne stricte entre la personne qui écrit le code de production et la personne qui écrit le code de test ne donne pas nécessairement des résultats.

Lorsque j'ai utilisé une approche similaire, la paire commence par parler et obtenir une compréhension partagée du problème. Si vous utilisez TDD, vous pouvez commencer par quelques tests de base en premier. Si vous n'utilisez pas TDD, vous commencerez peut-être par la définition de la méthode. À partir de là, les deux membres du couple travaillent à la fois sur le code de production et le code de test, une personne se concentrant sur chaque aspect, mais discutant des moyens d'améliorer le code de production ainsi que le code de test derrière.

Je ne vois pas l'avantage de donner à chaque paire deux fonctionnalités. Vous vous retrouveriez avec quelque chose qui ressemble à TDD pour certaines fonctionnalités et quelque chose qui ne l'est pas pour d'autres fonctionnalités. Vous perdez votre concentration. Vous ne bénéficiez pas des avantages de l'examen par les pairs en temps réel. Vous ne bénéficiez d'aucun des principaux avantages de l'association.

La pratique de la programmation par paires n'est pas une question de vitesse, mais de qualité. Donc, essayer d'utiliser une technique modifiée en allant plus vite va à l'encontre de la nature. En créant des logiciels de meilleure qualité via la révision de code parallèle et le développement de tests, vous finissez par gagner du temps en aval car il y a au moins deux personnes qui connaissent chaque changement et vous éliminez (ou réduisez) les cycles d'attente pour la révision et le test par les pairs.

30
Thomas Owens

Le principal problème avec votre idée est que vous ne pouvez pas simplement écrire des tests pour n'importe quel code. Le code doit être testable.

C'est à dire. vous devez être en mesure d'injecter des simulations, de séparer le bit que vous souhaitez tester, d'accéder à l'état modifié et à confirmer, etc.

À moins que vous n'ayez de la chance ou que vous n'écriviez le test en premier, les chances d'écrire le test signifient réécrire un peu le code. Ce qui, si vous n'êtes pas la personne qui a écrit le code en premier lieu, signifie des retards, des réunions, une refactorisation, etc.

37
Ewan

Le principal problème que je vois ici, au niveau de l'unité, lorsque j'écris du code, je veux le compiler, l'exécuter, et supprimer immédiatement les bugs les plus évidents - même lorsque le code est incomplet et que je sais l'unité, la fonction ou la fonction n'est implémentée que partiellement. Et pour exécuter le code d'une unité, j'ai besoin d'un programme appelant l'implémentation, généralement un test unitaire ou au moins un test unitaire partiel. Ce n'est pas forcément du "style TDD à la livre", un tel test peut être écrit après ou avant le code testé.

Lorsqu'une version de mon unité est "fonctionnalité complète" et exempte de tout bogue, je peux la trouver par moi-même, alors il est logique de la remettre à une deuxième personne et de la laisser écrire supplémentaire tests unitaires, ou revoir mon code. Mais pour moi, cela n'a aucun sens de le remettre dès que le compilateur n'affiche aucun avertissement, c'est définitivement trop tôt au cas où je sais que je devais expliquer en détail au testeur des choses qui ne fonctionnent pas "encore", ou fonctionneront différemment en deux heures puisque je travaille toujours sur ce morceau de code. Les frais généraux de communication nécessaires pour cela à ce niveau de détail ne seraient pas compensés par les avantages.

Donc oui, avoir un deuxième dev écrit des tests unitaires supplémentaires est logique, mais pas pour écrire les tests unitaires exclusivement .

15
Doc Brown

Il semblerait possible que l'une des situations suivantes se produise, toutes indésirables:

Confusion

Comme l'a souligné Ewan, la CUT pourrait devoir être modifiée pour la rendre testable. La raison du changement n'est pas toujours évidente pour le développeur (et peut provoquer un désaccord), c'est pourquoi les tests sont écrits en premier.

Contention

Developer A peut avoir terminé son code et vouloir le tester. Developer B peut également être en développement et peut donc être réticent à garer son code pour assister aux tests unitaires.

Changement de contexte

Même si développeur B est disposé à suspendre son développement pour tester le code écrit par développeur A - le changement d'activité a un coût.


Il a été accepté depuis des décennies que le doublement de la puissance humaine ne réduit pas de moitié le temps de développement. Compte tenu des facteurs que j'ai décrits ci-dessus, il est difficile de voir comment cet arrangement améliorerait les choses.

7
Robbie Dee

Lorsqu'il est utilisé en conjonction avec programmation par paire et TDD cela s'appelle Ping Pong Pattern :

  • A écrit un nouveau test et constate qu'il échoue.
  • B implémente le code nécessaire pour réussir le test.
  • B écrit le test suivant et constate qu'il échoue.
  • A implémente le code nécessaire pour réussir le test.

Etc. Le refactoring se fait chaque fois que le conducteur en a besoin.

Mais vous semblez proposer que les deux programmeurs codent avec des ordinateurs différents. Le faire séparément nécessiterait d'avoir une spécification de très bas niveau. Cela va à l'encontre des métodologies agiles. Chaque changement devrait être coordonné. Dans TDD, vous faites la conception de bas niveau à la volée et ce n'est pas un problème. Je suppose que votre approche nécessiterait d'avoir une sorte de squelette déjà codé.

Quoi qu'il en soit: vous pouvez en apprendre beaucoup en testant de nouvelles façons de faire, même si elles ne sont pas efficaces à 100%. Vous pouvez le tester et partager votre expérience de la vie réelle

4
Borjab

Je viens en retard à cette fête, mais je pense que j'ai quelque chose à ajouter.

Est-il déjà décrit comme une méthodologie inconnue et utilisé dans le développement de logiciels?

Vous décrivez Peer Testing .

Supposons que nous ayons des paires de développeurs.

Ah, bon vieux Programmation par paire .

Chaque paire est responsable d'une partie du code. L'un de la paire implémente une fonctionnalité (écriture de code) et le second écrit un test unitaire pour cela. Les tests sont écrits après le code. Dans mon idée, ils s'entraident, mais travaillent plutôt séparément.

Ce n'est pas de la programmation par paires.

Idéalement, ils travailleraient sur deux fonctionnalités de taille similaire, puis échangeraient pour la préparation du test.

C'est certainement un test par les pairs. Voici n article ACM à ce sujet . J'ai fait ça. J'ai travaillé là où c'était une partie formelle du processus Peer Review . C'est utile, mais ce n'est certainement pas censé être la première ligne de test, et ce n'est certainement pas la programmation par paires classique.

Un autre nom pour cela est Whitebox Testing . Bien que cette définition ne se préoccupe pas autant de qui fait les tests que du fait que le testeur voit le fonctionnement interne de la chose qu'ils testent, par opposition aux tests de la boîte noire où ils ne voient que ce qui se passe et ce qui sort. La boîte noire est généralement ce que fait QA.

La première ligne de test repose fermement entre les mains du codeur. Si ce n'est pas le cas, vous me demandez de ne pas tester moi-même mon code, ce que je refuse catégoriquement. Je teste mon code depuis l'âge de 10 ans. Je n'ai peut-être pas testé avec des tests unitaires sophistiqués à l'époque, mais mon code a été testé. Il a été testé chaque fois que je l'ai exécuté.

Ce que j'attends d'un testeur de pairs, ce sont des tests qui s'ajoutent à mes tests. Des tests qui clarifient en profondeur les problèmes rencontrés par le pair avec le code lorsqu'ils l'ont examiné. En exprimant ces problèmes avec un test automatisé, il est beaucoup plus facile de comprendre ce qu'ils signifient. En fait, j'ai eu des conversations techniques avec des pairs qui ne pouvaient tout simplement pas voir mon point de vue, puis j'ai réalisé que la meilleure façon de leur montrer le problème était d'écrire un test unitaire. C'est le test par les pairs.

Maintenant, si vous voulez me donner des tests écrits avant d'écrire correctement mon code. Rien de tel qu'un document d'exigences si formel qu'il compile.

3
candied_orange

J'ai fait du DDT (tests axés sur le développement, alias. Tests après le code), la programmation de paires et le TDD red-green-refactor pendant plusieurs années chacun. Pour répondre point par point à vos affirmations:

les tests sont écrits par quelqu'un, qui peut en savoir plus sur la mise en œuvre

La personne qui écrit des tests doit connaître l'implémentation aussi intimement que possible, pour écrire des tests avec une bonne couverture sans sur-tests. L'exemple classique de ceci est le test avec trois entrées lorsque deux prouveraient ce que vous essayez de tester. Bien qu'ils puissent se familiariser à la surface avec le code en le lisant, ils ne seront pas en mesure de comprendre exactement ce que le développeur d'origine a traversé pour arriver à l'état actuel. Ils auront donc une compréhension moins qu'optimale du code.

le travail doit être fait un peu plus rapidement que la programmation en binôme (deux fonctionnalités en même temps)

Je ne comprends pas pourquoi tu dis ça. Pendant que quelqu'un écrit des tests, il ne travaille pas sur de nouvelles fonctionnalités. Vous ne pouvez pas par magie doubler la capacité de travail d'une personne en lui donnant deux types de travail différents. D'après mon expérience, l'écriture de tests est généralement plus difficile que l'écriture de code de production, vous ne pouvez donc certainement pas travailler de manière productive et responsable sur des tests pour du code tout en écrivant une autre fonctionnalité.

les tests et le code ont une personne responsable

Tout d'abord, teste sont le code. Pour le code de test d'entreprise est presque aussi important que le code de production, car il permet à l'entreprise de changer le logiciel sans crainte. Deuxièmement, ce n'est pas différent d'une personne écrivant les tests et le code de production, ou même un paire écrivant les deux.

le code est testé par au moins deux personnes

Non, c'est seulement testé par la personne qui écrit le test. À moins que vous ne vouliez consacrer encore plus de temps au test, dans ce cas, pourquoi s'arrêter à deux?

peut-être que la recherche d'erreurs dans le code écrit par une personne qui teste votre code donnerait une motivation particulière pour écrire un meilleur code et éviter de couper les coins ronds.

Les développeurs (même les seniors) ont des idées très différentes de ce qui constitue un "bon" code. Le coup de coin d'une personne est le moyen parfaitement valable d'une autre pour arriver au code de travail dès que possible. C'est une recette pour blâmer et pour jouer au système.

Red-green-refactor TDD (en fait écrire un seul test avant d'écrire le code de production, l'exécuter, le voir échouer, modifier le code de production seulement, relancer le test, le voir réussir, puis refactoriser, et ne pas sauter ou échanger aucune de ces étapes) et révisions de code travail.

1
l0b0

Je pense que cette idée a quelques avantages:

Le'ts les parcourent un par un.

les tests sont écrits par quelqu'un, qui peut en savoir plus sur la mise en œuvre,

Donc, vous voulez dire que le premier développeur a passé du temps à écrire une implémentation, dont il n'est pas sûr qu'elle fonctionne. Ensuite, un autre développeur vient et écrit des tests, basant son raisonnement sur du code que personne ne sait s'il est correct, et en espérant qu'il apporte un avantage tactique par rapport à l'écriture de tests uniquement en ce qui concerne ce que le code est censé faire. Si l'implémentation est incorrecte, mon avis sera qu'elle n'apporte aucune aide à l'écriture des tests.

le travail doit être fait un peu plus rapidement que la programmation en binôme (deux fonctionnalités en même temps)

Une fois que les deux développeurs ont terminé leur développement initial, personne ne sait si l'un ou l'autre de leurs codes est correct. Cela reste à vérifier, personne ne peut cocher qui que ce soit comme fait, et personne ne peut prédire quand cela sera fait. Comparez cela à TDD: vous écrivez d'abord le test, puis vous échouez, puis vous passez avec du code. C'est du code prenant en charge de plus en plus de scénarios. C'est une motion avancée.

Si vous les faites progresser en parallèle, le code qui pourrait être réutilisé dans les deux fonctionnalités sera écrit deux fois et coûtera deux fois plus.

les tests et le code en ont la personne responsable,

Examinez la propriété collective du code, comme proposé par XP. Vous aurez encore plus de personnes responsables du code. Si votre objectif est de partager les connaissances entre les développeurs, pourquoi essayez-vous de les séparer?

le code est testé par au moins deux personnes

Avec paire TDD aussi. Lors du couplage, les deux personnes doivent convenir que le code écrit est adéquat ou ne pas l'écrire. Si cela se traduit par un combat, certaines personnes de l'équipe ont un problème d'ego mal placé.

peut-être que la recherche d'erreurs dans le code écrit par une personne qui teste votre code donnerait une motivation particulière pour écrire un meilleur code et éviter de couper les coins ronds.

La recherche d'erreurs implique qu'à un moment donné, vous avez toléré qu'ils pénètrent. S'ils sont entrés, ils n'ont pas été remarqués. Refuser d'écrire des tests en premier, c'est autoriser les erreurs à entrer.

Le coin de coupe peut être involontaire. C'est à cela que sert la programmation par paires. Chaque membre de la paire devrait être chargé de ne pas laisser l'autre couper les coins ronds, car nous le faisons tous. Cela nécessite de laisser votre fierté dans le placard et de le reprendre lorsque vous quittez le bureau. Si vous vous attendez à ce que votre personnel soit infailliblement rigoureux, vous ne pensez pas à la situation courante et vous vous préparez à l'échec.

XP dit explicitement que toutes les pratiques XP sont faites pour se renforcer mutuellement en couvrant les défauts les uns des autres. Vous ne devez pas écouter les critiques d'une pratique de XP séparées de Aucune pratique n'est parfaite, TDD n'est pas parfait, la programmation par paires n'est pas parfaite, la propriété collective de code n'est pas parfaite, mais ils se couvrent tous les uns les autres.

1
Laurent LA RIZZA