Utilisez-vous des tests unitaires au travail? Quels avantages en retirez-vous? [fermé]


18

J'avais prévu d'étudier et d'appliquer des tests unitaires à mon code, mais après avoir parlé avec mes collègues, certains d'entre eux m'ont suggéré que ce n'était pas nécessaire et que cela avait très peu d'avantages. Ils affirment également que seules quelques entreprises effectuent des tests unitaires avec des logiciels de production.

Je suis curieux de savoir comment les gens ont appliqué les tests unitaires au travail et quels avantages ils tirent de leur utilisation, par exemple, une meilleure qualité de code, un temps de développement réduit à long terme, etc.


13
"Ils affirment également que seules quelques entreprises effectuent des tests unitaires avec des logiciels de production." Cela signifie que seules quelques entreprises produisent des logiciels de haute qualité. Avec quel groupe voulez-vous vous aligner? Comment «seulement quelques entreprises» peuvent-elles être une déclaration négative? Seules quelques entreprises sont extrêmement rentables; est-ce que cela le rend mauvais? Seules quelques entreprises sont des lieux de travail vraiment agréables; est-ce que cela le rend mauvais? Seules quelques entreprises minimisent leur création de déchets; est-ce que cela le rend mauvais? Leur commentaire "seulement quelques entreprises" est insensé.
S.Lott

2
c'est aussi probablement incorrect, anecdotique, je n'ai pas encore travaillé pour ou avec une entreprise qui n'a pas au moins fait un certain niveau de test unitaire
jk.

1
Je dirais qu'un programmeur qui pense que les tests unitaires "ont très peu d'avantages" est inexpérimenté ou ne sait tout simplement pas comment écrire des tests unitaires efficaces.
Toby

Combien de tests unitaires les développeurs de ce site utilisent-ils?
JeffO

1
@ S.Lott: insensé oui, pourtant, il est toujours utilisé comme argument pour ne pas faire de test unitaire par ceux qui ne veulent pas le faire. Je ne défends pas ici leur point de vue, bien au contraire. Cependant, cette déclaration est toujours faite et ceux qui la font sont convaincus de sa valeur et puisque ce sont eux, nous devons convaincre des avantages réels du test de le brosser comme insensé ne va pas aider beaucoup plus la cause.
Newtopian

Réponses:


20

certains me suggèrent que ce n'est pas nécessaire

Eh bien, au sens strict, ils ont raison: les tests, les révisions de code, le contrôle des sources, etc. ne sont pas non plus strictement nécessaires . Seul un très petit nombre de développeurs sensés travaillent sans eux à long terme. La plupart d'entre nous ont appris (souvent à la dure, à partir de nos propres erreurs) pourquoi ce sont les meilleures pratiques.

et cela a très peu d'avantages.

Ce n'est pas vrai dans la plupart des cas. Autrement dit, si nous parlons d'un logiciel de production qui est censé être utilisé - donc en maintenance - pour les années à venir.

Ils affirment également que seules quelques entreprises effectuent des tests unitaires avec des logiciels de production.

Cela peut être vrai (quoique de moins en moins d'après mon expérience), mais cela n'a rien à dire sur la valeur des tests unitaires. Contrairement à cela, la vieille blague "La merde est bonne - 50 milliards de mouches ne peuvent pas se tromper!" ;-)

avez-vous appliqué le test unitaire à votre travail et qu'en retirez-vous? (par exemple, meilleure qualité de code, réduction du temps à long terme, etc.)

J'utilise des tests unitaires dans mon travail, chaque fois que cela est possible, depuis plus de 10 ans maintenant. Ce sentiment de confiance dans mon code, sachant qu'il fonctionne - et je peux le prouver à tout moment, n'importe où, en quelques secondes, encore et encore, au lieu de simplement y croire - n'a pas de prix. Cela me donne le courage de refactoriser mon code, d'améliorer sa conception, ou de corriger des bugs, sans craindre de casser les fonctionnalités existantes. Je ne reviendrais jamais à ces vieux jours de «code et prier».


14

Je fais des tests, mais pas (ou peu) au travail

Les principaux avantages des tests que j'obtiens sont que le refactoring est beaucoup plus facile et que la régression (c'est-à-dire la réintroduction d'erreurs déjà corrigées) est remarquée.

Tester des vies avec «la build»: vous extrayez des logiciels avec des tests en cours et vous ne vous connectez pas tant que tous les tests ne sont pas en cours avec votre modification.

Ainsi, d'après mon expérience, l'écriture de tests est presque inutile lorsqu'elle est effectuée à la manière d'un loup solitaire. Lorsque vous devez toujours corriger vos tests pour s'adapter aux modifications apportées par les autres, lorsque les tests peuvent être supprimés par vos collègues (comme dans mes emplois précédents) parce qu'ils ne me laisseront pas déployer, etc., ils ne sont qu'un travail supplémentaire avec les avantages instantanément brûlés par le reste de l'équipe.

Lorsque toute l'équipe est d'accord (et, dans une équipe de 1, c'est facile), d'après mon expérience, les tests sont un grand avantage pour la qualité, le style et la robustesse du projet.

Mais dans une équipe qui croit honnêtement que «seules quelques entreprises testent leur code automatiquement» et sont convaincues qu'elles sont une perte de temps de toute façon, il semble y avoir peu d'espoir de gagner les avantages, mais une grande possibilité que vous soyez fait responsable de la «perte de temps» en signalant les erreurs.

La meilleure chance d'introduire des tests serait un petit projet sous votre seule responsabilité. Là, vous auriez l'occasion de briller et de démontrer la valeur des tests.


1
Désolé de paraître négatif, mais je suis toujours brûlé par `` comment faire avancer les choses comme un grognement '';)
keppla

Très bon conseil. Le problème est que, une fois bien fait, vous ne voyez pas réellement l'avantage des tests unitaires. Vous ne voyez potentiellement le mal que lorsque vous ne faites pas de tests unitaires. Donc, si vous devez convaincre les autres avec des statistiques plutôt que de la théorie, vous êtes à peu près foutu.
Peter Kruith du

12
@keppla, j'ai écrit des tests unitaires dans des projets où mes coéquipiers n'avaient jamais entendu parler de tests unitaires auparavant. Une fois que mes tests ont réussi à détecter quelques bogues qui auraient autrement échappé à la vue, les autres ont commencé à en prendre note et ont rapidement voulu apprendre eux-mêmes les tests unitaires. La preuve concrète est reine.
Péter Török

1
@keppla, assez bien, si les coéquipiers sont biaisés au point de perdre leur bon sens, il n'y a aucun moyen de les convaincre par une preuve logique :-( Dans un tel cas, avec un solide soutien de la direction, vous pourriez toujours réussir à pousser l'idée à travers , mais sans cela, il n'y a pas d'espoir.
Péter Török

3
Vous «cassez» les tests souvent en changeant l'interface, en supprimant les classes, etc. Lorsque vous «testez d'abord», vous ne ressentez pas cela comme «cassant», mais comme la première étape «rouge». Mais lorsque vous êtes dans l'état d'esprit «Ajoutez simplement quelques lignes jusqu'à ce que cela fonctionne», les tests ne sont que plus de lignes. Et lorsqu'ils sont «fixés» par quelqu'un comme celui-ci, les tests ont tendance à se dégrader en utilité, jusqu'à ce qu'ils ne servent vraiment à rien. Selffulfilling prophecy 4tw!
keppla

7

J'ai tendance à me ranger du côté de vos collègues, mais seulement jusqu'à un certain point.

Le problème avec les tests unitaires est qu'ils sont fréquemment et inconsidérément écrits sur des cas triviaux où une enquête rapide du code révèle qu'il fonctionnera quoi qu'il arrive. Par exemple:

def add(x, y)
  x + y
end

Avec une douzaine de tests pour s'assurer que l'addition fonctionnera bien pour des cas d'utilisation choisis arbitrairement. Duh ...

La prémisse générale derrière les tests unitaires est la suivante: si votre code ne contient aucun bogue, c'est parce que vous n'avez pas suffisamment testé. Maintenant, quand écrire des tests unitaires appropriés. Réponses:

  1. Lorsque vous testez
  2. Lorsque vous déboguez
  3. Alors que vous développez des choses vraiment délicates

Passons en revue chacun, en supposant que vous développez une sorte d'application web.

Vous écrivez du code pour de nouvelles fonctionnalités, et cela devrait fonctionner raisonnablement bien maintenant. Vous recherchez ensuite votre navigateur et vérifiez qu'il fonctionne en effectuant des tests plus intensifs, non? Bzzzt! ... Mauvaise réponse. Vous écrivez un test unitaire. Si vous ne le faites pas maintenant, vous ne le ferez probablement jamais. Et c'est l'un des endroits où les tests unitaires fonctionnent très bien: pour tester des fonctionnalités de haut niveau.

Vous découvrez alors un bug (qui n'en manque jamais?). Cela nous amène au deuxième point. Vous replongez dans le code et commencez à suivre les étapes. Comme vous le faites, écrivez les tests unitaires aux points d'arrêt clés où il est crucial d'avoir des données cohérentes et correctes.

Le dernier point est l'inverse. Vous concevez des fonctionnalités velues qui impliquent des charges de méta-programmation. Il génère rapidement un arbre de décision avec des milliers de scénarios potentiels, et vous devez vous assurer que chacun d'entre eux fonctionne. Lors de l'écriture de telles choses, un simple changement ici ou là peut avoir des conséquences inimaginables plus bas dans la chaîne alimentaire. Supposons que vous concevez une implémentation MPTT à l'aide de déclencheurs SQL - afin qu'elle puisse fonctionner avec des instructions à plusieurs lignes.

Dans ce type d'environnement épineux, vous souhaiterez généralement automatiser fortement vos tests. Vous écrivez donc des scripts pour automatiser la génération de données de test et exécutez une charge de tests unitaires sur ces données de test. Une chose cruciale à ne pas perdre de vue pendant que vous faites cela, c'est que vous devez également écrire des tests unitaires pour votre générateur de tests unitaires.

Conclusion: des tests unitaires, certainement oui. Mais épargnez-vous celles sur les fonctionnalités de base - jusqu'à ce que vous en ayez réellement besoin pour le débogage, ou pour vous assurer que certaines fonctionnalités velues fonctionnent correctement (y compris, dans ce dernier cas, les tests eux-mêmes).


Comme le dit Kent Beck: "testez tout ce qui pourrait éventuellement se casser".
Péter Török

1
D'accord sans réserve avec lui. Mon principal espoir est que le PO prenne note de: n'oubliez pas de tester les tests le cas échéant. :-)
Denis de Bernardy

7

Tout le code doit être testé. Il n'y a pas de choix là-dessus.

Le code non testé est inutile: on ne peut faire confiance à rien.

Vous pouvez écrire des tests unitaires ou vous pouvez espérer écrire des tests d'intégration de niveau supérieur ou des tests d'acceptation.

Les tests unitaires sont plus faciles à écrire, à déboguer et à gérer.

Les tests d'intégration sont basés sur des hypothèses que les unités fonctionnent réellement. Sans tests unitaires, comment savez-vous que les unités fonctionnent? Comment pouvez-vous déboguer un test d'intégration si vous ne savez pas que les unités individuelles intégrées fonctionnent réellement?

De même, les tests d'acceptation dépendent du fonctionnement de toutes les pièces et pièces. Comment savoir si les pièces et les pièces fonctionnent sans avoir une suite de tests unitaires?

Le test est obligatoire. Tous les tests de niveau supérieur dépendent des unités qui fonctionnent réellement.

Cela rend les tests unitaires une nécessité logique. Il n'y a pas d'autre choix.


1
Il n'y a pas d'autre choix ... si vous vous souciez de la qualité. La plupart des organisations de logiciels ne se soucient pas vraiment de la qualité (dans la mesure où elles refusent d'expédier des logiciels connus pour être défectueux).
Joeri Sebrechts

@Joeri Sebrechts: Ce n'est pas un problème de qualité. C'est un problème "c'est fait". Même un mauvais logiciel doit être testé pour prouver qu'il fait quelque chose - n'importe quoi. Une logique simple dicte qu'il doit y avoir un test pour prouver que cela fonctionne. Même un mauvais test est un test. La logique simple veut qu'un test de l'ensemble doive inclure des tests des parties. Les tests unitaires sont simplement requis par la logique, rien d'autre. Pas des considérations de qualité, mais par définition de "fait".
S.Lott

1
L'utilisation du logiciel est un test en soi. De nombreuses organisations sont ravies de faire effectuer les tests par l'utilisateur. Je ne dis pas que c'est une bonne chose, mais c'est comme ça. Vous pouvez en effet choisir de ne pas tester avant la livraison, en déchargeant les tests sur l'utilisateur final. Vous pouvez, mais vous ne devriez pas.
Joeri Sebrechts

1
@Joeri Sebrechts: En fait, vous ne pouvez pas. Vous ne pouvez pas remettre un logiciel - au hasard - à un utilisateur pour un test d'acceptation. Vous devez avoir exécuté le logiciel au moins une fois pour vous assurer qu'il semble fonctionner. C'est un test - un mauvais test - mais un test. Logiquement, ce mauvais test comportait de mauvais tests unitaires. Ils existaient, même s'ils étaient très mauvais.
S.Lott

votre définition d'un test unitaire est inutile pour cette discussion. Un test unitaire est un test codifié et ce n'est pas du tout nécessaire pour expédier un logiciel. (mais ça fait du bien dans de nombreuses circonstances)
Martin Ba

6

J'utilise des tests unitaires pour tout ce que j'écris, et je ne laisse aucun code non testé passer l'examen sans un cas de test. (Mais je n'ai pas d'outil de couverture, donc je dois raisonner sur la couverture du test. Une chose à la fois ...)

C'est assez simple: si vous ne pouvez pas démontrer que votre code fonctionne (et quoi de mieux qu'une spécification exécutable sous forme de test?), Alors cela ne fonctionne pas .

Cela me donne:

  • Tranquillité d'esprit: mon serveur CI me dit tout mon travail de base de code.
  • La possibilité d'améliorer mon code: je peux restructurer mon code - le refactoriser - sachant qu'après la restructuration je n'ai rien cassé.

2
J'ajouterais une mise en garde très importante à cela - les tests unitaires ne garantiront pas à eux seuls que "toute votre base de code fonctionne". Cela garantira que toutes les unités de code fonctionnent de manière isolée, mais il existe toujours une énorme possibilité d'erreurs d'intégration, d'erreurs dans la présentation visuelle des données, etc.
Ryan Brunner

À moins que votre environnement ne passe "si vous ne pouvez pas démontrer que votre code ne fonctionne pas, alors cela fonctionne." : p
Davy8

@Ryan: Bien sûr, vos tests d'intégration devraient conduire l'ensemble du projet. La question portait sur les tests unitaires, j'ai donc parlé de tests unitaires, mais bien sûr, vous devriez démontrer la nécessité d'un morceau de code en ayant un test d'intégration qui échoue. Et bien sûr, vous devriez avoir un serveur CI déployant automatiquement votre base de code et exécutant tous les tests
Frank Shearar

@ Davy8: Dans ce cas, vous avez des problèmes plus sérieux qui "fonctionnent les tests unitaires?".
Frank Shearar

4

Les tests unitaires sont une discipline. Parce qu'il n'est pas nécessaire que le code fonctionne, il est souvent supprimé.

Il s'agit cependant d'une méthode éprouvée qui conduit à un code robuste et moins bogué. Je ne pense pas avoir besoin de vous expliquer les avantages, comme vous en avez déjà mentionné certains. Si vous regardez certains des principaux projets open source, qu'il s'agisse de bibliothèques javascript, de frameworks à pile complète ou d'applications à usage unique, ils utilisent tous des tests unitaires.

Je soupçonne que vos collègues qui déconseillent de l'utiliser ne sont pas des programmeurs. Si c'est le cas, disons qu'il n'y a pas beaucoup de gens que j'apprécie plus que des gens comme Martin Fowler ou Kent Beck ;).

Comme la plupart des meilleures pratiques, les avantages sont à long terme, vous devez y investir un certain temps. Vous pouvez écrire un long script de code procédural, mais nous savons tous que vous souhaitez l'avoir écrit dans un style orienté objet lorsque vous devez le refactoriser après 2 ans.

Il en va de même pour les tests unitaires. Si vous écrivez des tests unitaires pour les pièces critiques dans votre application, vous pouvez vous assurer que cela fonctionne comme prévu, tout le temps, même après refactorisation du code. Peut-être que vous codez si bien que vous n'avez jamais de bogue de régression. Mais si vous ne le faites pas, ou si un nouveau programmeur rejoint votre équipe, vous voulez vous assurer que les bogues du passé ne se reproduisent plus. Je pense que votre patron serait également satisfait de cela, au lieu d'avoir à déposer un rapport de bug qu'il pensait avoir été résolu il y a six mois.


3

Les tests unitaires nécessitent un langage convivial pour les tests unitaires, une conception conviviale pour les tests unitaires et un problème convivial pour les tests unitaires.

C ++, la conception multithread et l'interface graphique seront un cauchemar, et la couverture du problème sera épouvantable.

.NET, assemblage de dll à filetage unique réutilisable, la logique de calcul pure sera un jeu d'enfant.

Est-ce que ça vaut le coup, je ne peux pas vraiment le dire.

Vous refactorisez beaucoup? Voyez-vous beaucoup de "bugs stupides" comme "off by one" dans votre code?

Quoi que vous fassiez, ne soyez pas ce type qui critique les autres par "vous n'avez pas de tests unitaires, donc vous êtes nul". Si les tests vous aident, allez-y, sinon, ce n'est pas comme s'ils étaient une solution miracle.


1
Pourquoi le design multithread serait-il un cauchemar? Concevez des points de synchronisation et testez-les.
Frank Shearar

1
Parce que le timing dépend des phases de la lune, de l'horloge du processeur, de la corbeille et de presque tout. Lors d'un enregistrement, le test peut échouer, si vous êtes chanceux, sur 1000 autres, il ne le fera pas.
Coder

1
J'ai écrit des trucs multithreads pilotés par les tests. C'est certainement faisable.
Frank Shearar

4
ordures, vous pouvez effectuer des tests unitaires dans toutes les langues.
jk.

1
Il est difficile d'écrire des tests unitaires pour les interactions GUI, mais c'est pourquoi nous avons isolé quelque chose (notre code moteur) de ne pas faire avec l'interface graphique. Cela nous a aidés à prendre une bonne décision pour séparer le moteur de l'interface graphique, de plus, les tests unitaires agissent comme notre interface à la place de l'interface graphique, demandant et fournissant les informations dont nous aurions normalement besoin.
Chance

3

Je veux , mais j'ai eu la malchance de travailler presque entièrement dans des entreprises qui ne se soucient pas de la qualité, et sont plus concentrées sur le fait de jeter des ordures qui fonctionnent un peu comme si vous plongez. J'ai mentionné les tests unitaires et je reçois un "Huh?" type de look (le même look que j'obtiens lorsque je mentionne les principes SOLID , ou ORM, ou des modèles de conception au-delà de "classe avec toutes les méthodes statiques", ou en suivant les conventions de dénomination .NET). Je n'ai été que dans une seule entreprise qui comprenait ce genre de choses, et malheureusement c'était un contrat à court terme et le département a été réduit pour réduire les coûts, donc il n'y avait pas assez de temps pour vraiment apprendre.

J'ai essayé des tests unitaires dans des projets factices jetables, mais je ne me suis pas vraiment fait une idée du TDD / BDD à part entière, et le fait de ne pas avoir de mentor qui puisse l'aider rend la tâche plus difficile à faire correctement.


2

Nous les utilisons. Un grand avantage que nous obtenons est notre cadre de test unitaire vérifie les fuites de mémoire et les échecs d'allocation . Parfois, le problème est dans le code de test unitaire lui-même, mais souvent dans le code de production.

C'est un excellent moyen de trouver les éléments manquants dans une révision de code.

Les tests unitaires (devraient) également s'exécuter très rapidement et peuvent s'exécuter dans le cadre de votre intégration continue après chaque validation unique, ainsi que par les développeurs avant la validation. Nous en avons plus de 1 000 qui prennent moins de 20 secondes à courir.

Comparez avec plus de 40 minutes pour les tests d'automatisation au niveau du système et les heures / jours pour les tests manuels. Bien sûr, les tests unitaires ne sont pas les seuls tests que vous devriez faire, mais à un niveau de code fin, ils peuvent aider à trouver des bogues et à tester les cas limites que les tests système / d'intégration ne peuvent pas toucher. Notre code doit être testé avec une couverture de décision de plus de 75% et avec une couverture de fonction de 100%, ce qui serait très difficile à réaliser sans tests unitaires.


2

Je dirais que les tests unitaires ajoutent de la valeur, mais je ne suis pas un grand disciple de TDD. Je trouve le plus d'avantages avec les tests unitaires quand je fais des moteurs de calcul, ou n'importe quel type de moteur vraiment et ensuite les classes utilitaires, les tests unitaires sont alors très utiles.

Je préfère les tests d'intégration automatisés pour les blocs plus dépendants des données, mais tout dépend, je suis dans le domaine des données, donc beaucoup d'erreurs sont plus liées aux données dans notre environnement qu'autre chose, et pour cela les tests d'intégration automatisés fonctionnent bien. Vérification des données avant et après et génération de rapports d'exception à partir de ces tests.

Ainsi, les tests unitaires ajoutent vraiment de la valeur, surtout si l'unité que vous testez peut être fournie avec toutes les entrées dont elle a besoin et fonctionner seule avec l'entrée donnée. Encore une fois, dans mon cas, les moteurs de calcul et les classes utilitaires en sont de parfaits exemples.


2

Coûts: plus lent à coder, courbe d'apprentissage, inertie du développeur

Avantages: En général, je me suis retrouvé à écrire un meilleur code lors de mes premiers tests - SOLID sage ...

Mais à mon humble avis, le plus grand avantage, je pense, est la fiabilité dans les grands systèmes qui changent fréquemment. De bons tests unitaires vous permettront d'économiser (a fait le mien) lorsque vous publiez plusieurs versions et peuvent éliminer une grande partie des coûts associés aux processus manuels d'AQ. Bien sûr, cela ne garantira pas un code sans bogue, mais il en détectera quelques-uns difficiles à prévoir. Dans les grands systèmes complexes, cela peut effectivement être un très grand avantage.


0

Je fais des tests unitaires au travail quand j'en ai l'occasion, et j'essaie de convaincre mes collègues de faire de même.

Je ne suis pas religieux à ce sujet, mais l'expérience montre que les méthodes utilitaires et commerciales qui ont été des testes unitaires sont très robustes et ont tendance à avoir peu ou pas de bogues apparaissant pendant la phase de test, ce qui en fin de compte réduit les coûts du projet.


0

Là où j'ai vu le véritable avantage de coder les tests unitaires et d' intégrer l'exécution des tests unitaires au processus de construction quotidien, c'était sur un projet avec plus de 30 développeurs travaillant sur 3 continents différents. Là où les tests unitaires brillaient vraiment, c'était quand quelqu'un changeait subtilement une classe qu'il maintenait sans comprendre comment les gens utilisaient cette classe. Au lieu d'attendre que le code atteigne le groupe de test, il y a eu une rétroaction immédiate lorsque les tests unitaires d'autres personnes ont commencé à échouer à la suite du changement. [C'est pourquoi tous les tests unitaires doivent être exécutés régulièrement, pas seulement ceux que vous avez écrits pour votre code.]

Mes directives pour les tests unitaires sont les suivantes:

  1. Testez toutes les conditions auxquelles vous pouvez penser pour votre code, y compris les mauvaises entrées, les limites, etc.
  2. Tous les tests unitaires pour tous les modules doivent être exécutés régulièrement (c'est-à-dire dans le cadre des builds nocturnes)
  3. Vérifiez les résultats du test unitaire!
  4. Si quelqu'un trouve un bogue dans votre code qui a dépassé vos tests, écrivez-en un nouveau!

0

J'ai récemment appris le TDD et je trouve que c'est très utile. Cela donne une plus grande confiance que mon code se comporte comme prévu. En plus de rendre toute refactorisation que je souhaite faire plus facile. Chaque fois qu'un bogue est détecté, vous pouvez vous assurer que les tests ne réapparaîtront pas.

La partie la plus difficile est d'écrire de bons tests unitaires.

C'est une bonne référence pour votre code.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.