Nous avons essayé d'introduire plusieurs fois les tests automatisés pour développeurs dans mon entreprise. Notre équipe d’assurance qualité utilise Selenium pour automatiser les tests d’interface utilisateur, mais j’ai toujours voulu introduire les tests unitaires et les tests d’intégration. Dans le passé, chaque fois que nous essayions, tout le monde était excité pendant les deux premiers mois. Ensuite, après plusieurs mois, les gens cessent tout simplement de le faire.
Quelques observations et questions:
Les tests automatisés fonctionnent-ils réellement? La plupart de mes collègues qui travaillaient dans d’autres sociétés ont essayé sans succès de mettre en œuvre une stratégie de test automatisé. Je n'ai toujours pas vu une société de logiciels de la vie réelle qui l'utilise réellement et ne se contente pas d'en parler. Un si grand nombre de développeurs considèrent les tests automatisés comme quelque chose de génial en théorie mais ne fonctionnant pas en réalité. Notre équipe commerciale aimerait que les développeurs le fassent même avec un coût de 30% de temps supplémentaire (au moins, ils le disent). Mais les développeurs sont sceptiques.
Personne ne sait vraiment comment faire correctement des tests automatisés. Oui, nous avons tous lu les exemples de tests unitaires sur Internet, mais les utiliser pour un grand projet est tout autre chose. Le principal responsable est de se moquer de la base de données ou de tout ce qui n’est pas trivial. Vous finissez par passer plus de temps à vous moquer qu'à écrire des tests réels. Ensuite, quand il faut plus de temps pour écrire des tests que du code, c'est à ce moment-là que vous abandonnez.
Existe-t-il de bons exemples de tests unitaires / tests d'intégration de systèmes utilisés dans des applications Web complexes centrées sur les données? Des projets open source? Notre application est centrée sur les données, mais a également beaucoup de logique de domaine. J’ai essayé l’approche de référentiel à un moment donné et j’ai trouvé que c’était très bon pour les tests unitaires, mais c’est au prix de pouvoir optimiser facilement l’accès aux données et cela ajoute une couche de complexité supplémentaire.
Nous avons un grand projet entrepris par 20 développeurs expérimentés. Cela semblerait être un environnement idéal pour introduire les tests unitaires / tests d'intégration.
Pourquoi ça ne marche pas pour nous? Comment l'avez-vous fait fonctionner dans votre entreprise?
Réponses:
La partie la plus difficile des tests unitaires consiste à amener la discipline à écrire les tests d’abord / au début. La plupart des développeurs ont l'habitude de se plonger dans le code. Cela ralentit également le processus de développement dès le début, car vous essayez de comprendre comment écrire un test pour le code. Cependant, à mesure que vous améliorez vos tests, cela accélère. Et à cause des tests d'écriture, la qualité initiale du code commence plus haut.
Lorsque vous débutez, essayez simplement d’écrire des tests. Ne vous inquiétez pas tellement de vous moquer ou de vous moquer de choses au début. Gardez les tests simples. Les tests sont codés et peuvent / devraient être refactorisés. Même s’il est difficile de tester quelque chose, cela pourrait aussi être la conception. TDD cherche à utiliser la plupart des modèles de conception (selon mon expérience, en particulier le modèle Factory).
Assurez-vous que les tests ont un niveau de visibilité. Intégrez-les dans le processus de publication, demandez-leur lors de la révision du code. Tous les bugs trouvés devraient faire l'objet d'un test. Ces choses sont où le TDD brille.
Voici quelques ressources que j'ai trouvées utiles:
http://misko.hevery.com/attachments/Guide-Writing%20Testable%20Code.pdf
http://www.agitar.com/downloads/TheWayOfTestivus.pdf
Modifier:
Une chose à garder à l'esprit lorsque vous écrivez des tests. Vous n'essayez pas de spécifier quoi que ce soit à propos de l'implémentation du code, mais seulement du comportement. Lorsque vous écrivez du code, vous le testez tout le temps. Essayer de l'exécuter avec des instructions de débogage, etc. L'écriture de tests formalise ceci et fournit un enregistrement des tests que vous avez. De cette façon, vous pouvez vérifier vos fonctionnalités en toute confiance sans ignorer accidentellement un scénario de test dont vous vous souveniez au milieu du processus de développement.
la source
À bien des égards, je suis d’accord avec votre équipe.
La plupart des tests unitaires ont une valeur discutable. Depuis la grande majorité des tests semble être trop simple.
Il est beaucoup plus difficile d'écrire un bon code testable qu'un code fonctionnel. Un grand pourcentage de la communauté des développeurs qui croient qu’il est essentiel de le faire fonctionner, par opposition à la qualité du code / de la conception en soi. Et un pourcentage encore plus important qui ne sait même pas ce qu'est un code de qualité.
L'écriture du code de test unitaire peut prendre beaucoup plus de temps que le code lui-même.
Déterminer comment tester de manière adéquate le code plus compliqué (c'est-à-dire les éléments que vous souhaitez réellement tester à fond) va au-delà des capacités de nombreux développeurs.
Maintenir les tests unitaires prend trop de temps. De petits changements peuvent avoir de gros effets d'entraînement. L'objectif principal des tests unitaires automatisés est de déterminer si les modifications ont violé le code. Cependant, 99% du temps, ce sont les tests et non le code qui finissent par casser.
Avec tous les problèmes ci-dessus, il n’existe toujours pas de meilleur moyen de modifier le code et d’avoir la certitude que quelque chose ne se brise pas de façon inattendue par rapport à l’automatisation de vos tests.
Une partie de ce qui précède peut être atténuée dans une certaine mesure en ne respectant pas le manuel de tests unitaires.
De nombreux types de conceptions / applications sont mieux testés en automatisant les tests au niveau du module / package. D'après mon expérience, la plupart des erreurs de codage ne sont pas dues au fait que le code d'une classe a été mal codé, mais au codeur qui n'a pas compris comment leur classe était supposée fonctionner avec d'autres classes. J'ai vu beaucoup de bénéfices pour ce type de tests. Mais encore une fois, ces tests sont plus difficiles à écrire que les tests unitaires (niveau classe).
Tout se résume à savoir si les développeurs croient ou non au processus. S'ils le font, ils écrivent de bons tests unitaires, trouvent les erreurs tôt et sont des promoteurs. S'ils ne le font pas, leurs tests unitaires seront généralement inutiles et ne trouveront aucune erreur. Leur théorie selon laquelle les tests unitaires seront inutiles sera prouvée (dans leur esprit).
L’essentiel est que je n’ai jamais vu l’approche complète des tests unitaires automatisés fonctionner pendant plus de deux mois moi-même, mais l’idée des tests unitaires automatisés persiste, bien que nous soyons sélectifs quant à ce qui doit vraiment être testé. Cette approche a tendance à avoir beaucoup moins de critiques et est plus acceptée par tous les développeurs que par quelques-uns.
la source
Frobinate()
méthode de niveau supérieur (au lieu des dizaines de méthodes plus petites appelées en dessous) après que le système a été vérifié par un autre moyen de servir comme test de fumée qu'aucun des changements de niveau inférieur n'a rien cassé. Généralement, ces tests ont utilisé les mêmes données que celles incluses dans les tests utilisateur fournis au clavier afin que le client puisse voir que le système fait ce qu'il veut. Ensuite, les outils de couverture de code peuvent identifier les cas où les cas périphériques ne sont pas encore couverts.Et voilà votre problème.
Tout le monde insiste sur la manière d'intégrer les tests unitaires dans votre environnement. Comment forcer les gens à le faire suffisamment pour qu'ils voient la valeur pratique et que cela «colle». Mais si c'est très pénible à faire et / ou n'apporte aucun bénéfice, cela ne collera pas.
Stubbing sur une base de données devrait être extrêmement simple. Au lieu que votre interface accède à une base de données pour fournir ses résultats, vous insérez un simple objet codé en dur. Si vous ne pouvez pas faire cela, alors votre conception / architecture a des problèmes. Votre code suppose qu'il va dans une base de données ou que vous n'avez pas l'abstraction d'interface pour le faire varier.
Ce n'est pas simplement un problème de test / qualité. Dès que vous souhaitez changer de fournisseur de base de données, ou aller plutôt dans le cloud, ou prendre en charge des applications mobiles non connectées, votre conception échoue tout simplement. Si vous ne pouvez pas prendre en charge les cas de flexibilité les plus simples, vous ne pourrez certainement pas prendre en charge les tâches plus complexes que votre entreprise nécessitera inévitablement.
la source
Vous devez commencer par quelque chose de petit, simple à automatiser et de grande valeur. Arrachez quelques fruits faciles à mettre en place et vous pourrez vendre le processus. Montrez comment cela a permis à quelqu'un de sauver une fin de soirée ou un appel de fin de semaine. Ensuite, vous pouvez développer à partir de là.
Pour bien faire les tests automatisés, vous avez besoin de quelqu'un qui est une ressource et un évangéliste, et qui a acquis le soutien des cadres supérieurs.
Traitez votre développement de test automatisé comme n'importe quel autre projet agile. Produire des tests terminés régulièrement.
Ajout du commentaire: C'est plus un problème de gestion. Le code est-il considéré comme "terminé" avant d'être documenté? Avant qu'il soit enregistré? Avant d'inclure et de réussir les tests unitaires?
Votre approche dépend vraiment de votre rôle. Êtes-vous un pair? Si tel est le cas, montrez aux autres comment il est plus facile pour votre code de le réutiliser et de le gérer. Êtes-vous un plomb? Choisissez votre programmeur qui a le plus de problèmes de code et aidez-le à ajouter des tests pour les éviter. Êtes-vous un patron? Définissez comme norme que "le code n’est pas terminé tant que les tests unitaires ne sont pas passés et ne passent pas.
la source
Suivez ces règles de base. Tests:
doit courir régulièrement! Vous pouvez effectuer des tests sur chaque build, avant / après chaque enregistrement ou juste tous les matins. Le déclenchement automatique est hautement préférable au déclenchement manuel. Parce qu'en théorie, tous les membres de l'équipe sont responsables de l'exécution des tests. Si ce n'est pas automatisé, cela ne se produit probablement pas assez souvent! Et si vous n'exécutez pas assez souvent vos tests, ils trouveront tous les deux le bogue trop tard, ce qui encouragera de nombreux tests cassés, ce qui conduit au point 2:
Vous ne réussirez toujours que si ces tests, qui se déroulent maintenant régulièrement, ne vous gênent pas . On entend par tests:
une. ne doit pas prendre trop de temps (subjectivement) pour la valeur qu'ils fournissent! Faites vos tests flambant vite. Ne laissez pas les gens enregistrer des tests qui vont être une perte de temps pour les laisser courir!
b. ne doit pas être fiable. Évitez les tests multithreads dans la mesure du possible. Appliquez des pratiques d'ingénierie à vos tests, tout comme votre autre code: en particulier, vérifiez le code de vos tests!
c. ne doit pas être plus difficile à réparer et à maintenir que le code réel testé. Votre vélocité de codage va vraiment être nulle si un petit changement d'une ligne dans votre base de code vous oblige à effectuer 10 tests différents.
Enfin, règle numéro 3. Les tests doivent non seulement échouer pour fournir une valeur négative, comme dans la règle 2, ils doivent aussi fournir une valeur positive. Tests ...
Un moyen populaire de violer la règle n ° 3 est de tester la mauvaise chose . Cela est parfois dû à un test trop grand ou trop flou. Mais cela vient généralement du fait de ne pas tester quelque chose qui importera à un client et de tester des détails de mise en œuvre non pertinents. (Mais parfois, tester les détails de la mise en œuvre est également un test efficace - à l’OMI, il suffit de s’entraîner pour décider lequel.)
Conclusion: ces règles de base vous orientent dans la direction d’une discipline de l’essai durable , ce dont vous avez désespérément besoin. Lors du test, demandez-vous si ce test est vraiment durable et maintenable. Rappelles toi:
Le test est réellement difficile. Vous devez vous attendre à ce que les tests de votre équipe soient vraiment mauvais quand vous commencez à écrire des tests . Ne vous découragez pas. Ne jetez pas les vieux tests, chaque fois que vous remarquez qu'ils sont nuls et insoutenables.
la source
Oui, si - correctement. Le fait est que les testeurs doivent ajuster et étendre leurs scripts automatisés après que les ingénieurs ont implémenté de nouvelles fonctionnalités.
Obtenez un consultant (quelqu'un qui sait comment faire correctement). Ou investissez plus de temps. L'alternative consiste à avoir une équipe de test plus importante, qui effectue les mêmes tests manuellement (ce qui est sujet aux erreurs).
Je ne les appellerais pas "de bons développeurs expérimentés" s'ils refusaient de faire des tests unitaires. Il existe de nombreux articles sur les avantages des tests (tests unitaires et d'intégration), et à la fin, cela revient à dire combien un bogue coûte à votre entreprise . Par exemple, je travaille dans une entreprise où la qualité est importante, donc les tests unitaires et d'intégration sont inévitables. Vous pouvez facilement trouver de nombreux articles indiquant que seuls les tests unitaires réduisent le nombre de bugs de 30%! (En réalité, il se situe entre 20 et 90%, en moyenne 30%, mais c'est toujours beaucoup.)
Pour que cela fonctionne dans votre entreprise, embauchez un consultant ou confiez cette tâche à un ingénieur en chef (cela lui prendra un certain temps). Et ensuite, forcez tout le monde à respecter les règles.
la source
Il existe de nombreuses raisons pour lesquelles l'introduction de tests automatisés peut échouer. Je pense que cela revient au fait que les programmeurs ont tendance à ne pas changer leurs habitudes de codage et ne sont pas totalement capables d’accepter les tests unitaires.
De nombreuses personnes souhaitant commencer par des tests automatisés essaient de les introduire pour une base de code existante. Ils essaieront d’écrire des tests d’intégration qui testeront simultanément de nombreuses fonctionnalités d’une application existante. De tels tests d'intégration sont notoirement trop difficiles et trop coûteux à maintenir. Conseil: Introduisez des tests automatisés pour une nouvelle base de code.
Les tests unitaires sont de bons tests à automatiser. Tout ce qui précède (tests d'intégration, tests de composants, tests de système) peut également être testé automatiquement, mais le rapport coûts-avantages diminue rapidement, plus le nombre de fonctionnalités testées est simultané. Cet effet négatif est amplifié si vous construisez de tels tests sur des fonctionnalités mal testées. Conseil: Introduisez des tests automatisés au niveau des tests unitaires et construisez des tests d'intégration automatisés sur une base solide de tests unitaires .
D'après ce qui précède, le succès des tests automatisés dépend en grande partie de l'efficacité des tests unitaires. Vous avez des tests unitaires efficaces si vous vous sentez productif avec les tests unitaires. Lorsque les gens commencent avec les tests unitaires, ils ont tendance à adapter leur code et leurs habitudes de codage existants aux tests unitaires. Ironiquement, c'est le moyen le plus difficile d'apprendre les tests unitaires. De plus, le test unitaire nécessite de changer la façon dont vous codez (en appliquant par exemple les principes SOLID ). La plupart des programmeurs arrêtent bientôt d'écrire les tests unitaires car ils pensent que la courbe d'apprentissage est trop raide et trouvent qu'il est difficile de placer des tests unitaires autour d'un code conçu qui ne soit pas aussi testable. Conseil: Apprenez les tests unitaires à partir de zéro avec le nouveau code et traitez le fait que vous devez changer vos habitudes de codage.
Il y a beaucoup d'autres facteurs, mais j'ai trouvé que pour la plupart des programmeurs, il est difficile de changer de code. Le code écrit sans test est simplement différent. Si vous ne pouvez pas insérer votre code dans une conception testable, vous échouerez probablement dans l’écriture de tests unitaires efficaces. Cela détruit le terrain pour des tests automatisés efficaces.
J'en ai fait l'expérience moi-même et je suis maintenant heureux de travailler dans une entreprise qui a introduit avec succès des tests automatisés. Je pourrais écrire beaucoup plus sur les autres facteurs, mais je pense que les habitudes de codage et les tests unitaires sont les plus importants. Heureusement, il y en a d'autres qui ont plus d'expérience que moi et qui remplissent des livres avec leur savoir-faire. L’un de ces ouvrages est le développement d’applications de sites contaminés dans .NET que je peux vraiment vous recommander, car vous utilisez la pile technologique de Microsoft.
la source
Introduce automated tests on the unit test level and build automated integration tests on a solid foundation of unit tests.
+1Une chose que je n'ai pas vu clairement traitée dans les réponses ci-dessus est que le test unitaire est essentiellement un bien public et un coût privé. J'ai écrit un article de blog à ce sujet ici .
En fin de compte, si une série de tests bénéficie à l'équipe ou à un développeur individuel, la rédaction du test représente un coût pour celui qui la réalise, la plupart du temps.
En bref, à moins que l’ écriture du test ne soit imposée d’une manière ou d’une autre (et les réponses ci-dessus énumèrent un certain nombre de façons différentes de le faire), il n’ya aucune raison pour qu’un développeur en particulier le fasse.
Dans une entreprise dans laquelle j'ai travaillé, l'écriture de tests unitaires était indispensable pour fournir une fonctionnalité. Le nouveau code n'a été accepté que si un test unitaire faisait partie de la validation ou de la nouvelle fonctionnalité - de brèves révisions du code pour chaque "tâche" donnée à un développeur. Il peut être intéressant de mettre en place une politique similaire sur votre lieu de travail.
la source
Il est intéressant de noter que le business est plus pro-test que les développeurs! Il me semble que votre plus grand défi sera de surmonter la résistance de vos développeurs au changement; ils doivent redéfinir leur compréhension de leur travail pour inclure les tests unitaires.
Rien ne peut vous aider davantage que les premiers succès des tests unitaires pour aider vos développeurs à surmonter leur résistance à la rédaction de ces tests. Si vous les incitez à faire quelque chose de nouveau, assurez-vous de commencer par obtenir une récompense presque garantie.
@SkipHuffman en a parlé, mais je vais le dire tout de suite. Certaines choses sont beaucoup plus adaptées aux tests automatisés que d’autres. Pour le premier passage, je ne testerais PAS la base de données ou l'interface utilisateur. Les entrées d'une base de données peuvent être extrêmement difficiles à configurer et à démonter. Les tests de sortie d’UI ont tendance à être rapidement interrompus par des modifications d’apparence totalement étrangères à vos tests.
Ce que j'appellerais "middleware" est parfait pour les tests unitaires. Code qui a des conditions d'entrée et de sortie clairement définies. Si vous suivez le principe DRY (Ne vous répétez pas), vous aurez écrit quelques petites classes ou fonctions pour résoudre des problèmes récurrents propres à votre application.
Les tests unitaires sont un excellent outil pour limiter le risque de modification des composants internes existants. Ecrivez des tests unitaires avant de modifier un composant interne ayant fonctionné longtemps. Ces tests prouvent que la fonctionnalité qui fonctionne actuellement est préservée. Lorsque vous avez effectué votre modification et que tous les tests unitaires sont réussis, vous savez que rien n’a été cassé «en aval». Si vous trouvez un problème en aval, ajoutez un test unitaire pour celui-ci!
Ron Heifitz dirait: " Résoudre les conflits entre les valeurs que les gens attachent ou réduire l'écart entre les valeurs qu'ils défendent et la réalité à laquelle ils sont confrontés. Le travail d'adaptation nécessite un changement de valeurs, de croyances ou de comportement". Après avoir surmonté la résistance humaine au changement, vous pouvez vous lancer dans des zones de test plus difficiles, le cas échéant.
la source
Une chose à propos des tests automatisés est que cela nécessite que vous écriviez du code pour pouvoir être testé. Ce n’est pas une mauvaise chose en soi (en fait, c’est bien parce que cela décourage de nombreuses pratiques qui devraient en principe être évitées), mais si vous essayez d’appliquer des tests unitaires au code existant, il y a de fortes chances que ce ne soit pas le cas. été écrit de manière testable.
Des éléments tels que singletons, méthodes statiques, registres, localisateurs de services, etc., introduisent des dépendances très difficiles à simuler. Les violations de la loi de Demeter signifient qu'un trop grand nombre de parties de votre base de code en savent trop sur le fonctionnement d'autres parties de votre base de code, ce qui introduit d'autres dépendances cachées qu'il peut être difficile de casser. Toutes ces choses rendent difficile l'isolement d'un module du reste de la base de code, et si vous ne pouvez pas tester vos modules de manière isolée, les tests unitaires perdent beaucoup de leur valeur. Si un test échoue, cela est-il dû à une défaillance de l'unité testée, ou à une défaillance de l'une de ses dépendances, ou peut-être est-ce dû au fait que les données extraites via une source de données dépendante ne sont pas attendues par le rédacteur de test ? Si tu peux'
La plupart des bases de code que j'ai observées et qui n'ont pas été conçues avec les tests unitaires à l'esprit ont tendance à être fondamentalement impossibles à tester, car les codeurs ont tendance à se concentrer sur l'utilisation du code comme ils le devraient. . Le code qui a été écrit en pensant aux tests unitaires a l’air très différent.
Beaucoup de gens adoptent une approche naïve des tests unitaires lorsqu'ils commencent à le faire pour la première fois. Ils pensent pouvoir simplement écrire une charge de tests pour une base de code existante et tout ira bien, mais cela ne marche jamais comme ça à cause des les questions mentionnées ci-dessus. Ils commencent à découvrir qu'ils doivent exécuter des quantités excessives de configuration dans les tests unitaires pour pouvoir les exécuter. Les résultats sont souvent discutables, car le manque d'isolation dans le code signifie que vous ne pouvez pas localiser la cause d'un échec du test. Ils ont également tendance à commencer par essayer d’écrire des tests "intelligents" qui démontrent un aspect très abstrait du fonctionnement du système. Cela a tendance à échouer car un test unitaire "intelligent" est en soi une source potentielle de bugs. Le test a-t-il échoué à cause d'un bogue dans le module testé, ou à cause d'un bug dans le test? Un test devrait être tellement simple qu'il est évidemment impossible qu'un bogue s'y cache. En fait, les meilleurs tests durent rarement plus de 2 lignes, la première indiquant à l’équipe testée de faire quelque chose, la seconde affirmant que ce qu’elle a fait est conforme aux attentes.
Si votre équipe souhaite sérieusement adopter les tests unitaires, il ne serait pas judicieux de commencer par un projet existant. Les projets existants de votre équipe ne sont probablement pas testables sans refactorisation majeure. Vous feriez mieux d'utiliser un nouveau projet comme base d'apprentissage sur les tests unitaires, car vous avez une table blanche pour travailler. Vous pouvez concevoir la nouvelle base de code de manière à favoriser l’injection de dépendances par rapport aux singletons, aux registres et autres dépendances cachées, vous pouvez l’écrire en fonction des interfaces plutôt que des implémentations, etc. Vous pouvez également (et devriez) écrire les tests avec le code testé, car l'écriture ultérieure des tests aboutit à des tests unitaires garantissant que le module testé fait ce que vous pensez qu'il est censé faire plutôt que ceux qui le testent. ce que les spécifications disent qu'il devrait faire.
Une fois que vous aurez acquis une certaine confiance dans les tests unitaires, votre équipe commencera probablement à comprendre les failles de son code existant qui vont faire obstacle aux tests unitaires. C’est à ce moment-là que vous pouvez commencer à travailler à la refactorisation du code existant pour le rendre plus testable. Ne soyez pas ambitieux et essayez de faire tout cela en même temps, ou tentez de remplacer un système qui fonctionne par un tout nouveau, commencez simplement par trouver les éléments de la base de code qui peuvent facilement être testés (ceux qui ne le sont pas. dépendances ou où les dépendances sont évidentes) et écrivez des tests pour celles-ci. Je sais que j'ai dit que l'écriture d'un test avec le code était préférable à l'écriture de tests après, mais même un test écrit plus tard a toujours une valeur comme point de départ. Ecrivez les tests comme si vous ne saviez rien du fonctionnement de la classe, si ce n’était ce que ses spécifications prévoient de faire. Lorsque vous exécutez les tests et obtenez des échecs, les spécifications ou l'implémentation sont incorrectes. Vérifiez deux fois pour déterminer ce qui est faux et mettez à jour le test ou le code en conséquence.
Une fois que vous avez récolté les fruits faciles, votre vrai travail commence. Vous devez commencer à rechercher les dépendances cachées dans votre base de code et à les corriger, une à la fois. Ne soyez pas trop ambitieux à ce stade, tenez-vous en à ne faire qu'un module à la fois, ou même un seul problème dans un module, jusqu'à ce que les obstacles au test soient corrigés et que vous puissiez passer au suivant.
TL: DR: La plupart des gens pensent que les tests sont faciles et que vous pouvez facilement intégrer des tests dans du code existant. Ces deux hypothèses sont fausses. Si vous vous lancez dans un projet visant à intégrer des tests unitaires à vos projets en gardant à l'esprit ces deux faits, vous aurez plus de chances de réussir.
la source
Sinon, les initiatives de test automatisé échoueront probablement. Le test automatisé est une compétence, comme bien d’autres compétences en programmation, et si vous n’avez aucune expérience en la matière, il n’est pas facile de dire si un test automatisé est un bon test automatisé avec une valeur réelle ou mauvais. échouer de manière aléatoire / nécessiter des mises à jour fréquentes / n'exerce aucun code intéressant.
Si personne n'écoute, peu importe qu'ils disent que le test n'est pas bon. (Notez qu'il n'est pas nécessaire de formaliser le pouvoir du leadership. Avoir une équipe qui se soucie, c'est bien aussi.)
Les développeurs sont paresseux. Vous devez rendre les choses que vous voulez qu'elles soient faciles à accomplir et celles que vous ne voulez pas qu'elles fassent plus difficiles à accomplir. Vous devez vous assurer que les bibliothèques de test facilitent la réalisation des tâches associées à la configuration de test et au démontage, en particulier la configuration liée à l'environnement, telle que les bases de données de test ou similaires. (La base de données est abordée dans certains de ces commentaires mais doit être utilisée avec prudence. Une véritable base de données doit être facile à créer et vous permettre de tester l'interaction des composants et les cycles de vie des processus, souvent plus importants et plus efficaces que les tests unitaires. un accesseur de données individuel.)
Vous devez également vous assurer que vos IDE disposent d'un bon moyen de lancer la suite de tests. Vous devez exécuter la suite de tests souvent pour que les gens remarquent son échec au lieu de le laisser traîner dans la misère. Les développeurs répondent également bien aux commentaires, par exemple un système d'intégration automatisé annulant leurs modifications s'ils ont réussi un test. Ou, mieux, un retour positif: un système d’intégration automatisé qui détecte les bugs et vous évite de tout casser.
la source
Premièrement, si vos développeurs ne voient pas la valeur de vos tests, c'est probablement parce que vos tests ne sont pas utiles, et non pas parce qu'ils sont aveugles à leur valeur ou à la valeur des tests en général. Parmi ses évangélistes, il y a une tendance à croire que le développement piloté par les tests ne peut échouer, il peut simplement échouer par les développeurs paresseux et paresseux. Je pense que c'est faux et contre-productif.
Quand on m'a initié au développement piloté par les tests, cela signifiait, en effet, écrire un test pour vérifier qu'une méthode qui n'échouera jamais n'échouera jamais. Ce qui est bien, au début, parce que vous obtenez un joli chèque vert et un sentiment d'accomplissement. Plus tard, après avoir refactorisé le code, vous avez des dizaines de Xes rouges exaspérants, dont aucun ne dit plus que le code a changé, que les tests ne sont plus valides et que vous avez perdu beaucoup de temps à les écrire.
Vous voulez éviter ça.
Depuis lors, j'ai adopté une approche différente des tests. Au lieu d'une paire d'implémentation d'interface , j'ai une interface, une implémentation, un test triple . L'interface spécifie le comportement, l'implémentation effectue le comportement, le test vérifie le comportement.
Je suppose que cela semble évident, mais à mon avis, cela fait une distinction entre le code que vous devez prouver et les travaux spécifiés et le code que vous pouvez tester autant ou aussi peu que vous le jugez approprié. Le code que vous devez prouver est l'interface que vous proposez à l'extérieur. le reste ne concerne que vous.
Dans ce cas, je demanderais aux développeurs s'ils voient dans le code une division naturelle dans laquelle ce type de test serait approprié. Existe-t-il une interface implémentée par l'équipe A et utilisée par l'équipe B? Dans ce cas, il est dans l’intérêt de l’équipe B de s’assurer que l’interface se comporte comme prévu. Demandez à l’équipe B d’écrire un test, puis demandez à l’équipe A de s’assurer que leur implémentation est conforme au test; ou, si ce n'est pas le cas, et ce n'est pas intentionnel, discuter du changement imprévu avec l'autre équipe, afin qu'elle puisse s'y préparer.
Je pense que cela illustrerait la valeur du test. Ce n'est pas une fin en soi, malgré les beaux chèques verts. Il existe pour rendre explicite la promesse faite par un développeur à un autre et pour s'assurer que la promesse est tenue à la satisfaction des deux.
la source
L'ajout de nombreux tests unitaires à un grand projet préexistant est un travail difficile. Si vous avez déjà trouvé un bon framework moqueur qui fonctionne pour vous, vous devriez avoir résolu le problème le plus difficile.
Je suggère d'essayer d'ajouter des tests au fur et à mesure que vous ajoutez des fonctionnalités / corrigez des bugs. La correction des bugs étant la plus facile. Ecrivez un test qui échoue à cause de votre bogue puis corrigez-le. En même temps, vous vous retrouverez probablement en train d'écrire des tests simples qui réussissent. Bien sûr, vous voulez vraiment utiliser un petit morceau de code facilement testé pour cela.
Une fois que les gens commencent à s’habituer à écrire des tests pour les choses les plus faciles, vous devriez espérer qu’ils écrivent leur code pour être plus testables.
Je vous recommanderais également de mesurer la couverture de code de vos tests (j'ai déjà utilisé cobertura for Java). Vous souhaiterez qu'un serveur d'intégration continue exécute les tests et produise les métriques de manière régulière (chaque jour, chaque enregistrement). Si vos collègues développeurs sont enthousiastes, ils voudront voir la couverture augmenter avec le temps et ils pourront voir les lacunes béantes de la couverture dans certains de vos domaines.
la source
Je pense que vous devrez peut-être jouer au long jeu. Une des choses que vous pouvez faire pour obtenir une certaine acceptation est d’essayer de tester de manière exhaustive la prochaine fonctionnalité que vous écrivez, puis de garder une trace du nombre de bogues au fil du temps. Vous devriez espérer que les bugs majeurs seront détectés tôt (en particulier si vous associez ceci à une conception pilotée par les tests) et que le nombre de régressions devrait être très faible. Après un certain temps, disons 1 an, comparez les statistiques avec des fonctionnalités de même complexité non testées par l'unité. Si vous pouvez montrer que le nombre de nouveaux bogues et régressions est sensiblement inférieur, vous en fournissez une justification financière et il devient plus difficile à ignorer pour l'équipe produit.
J'étais dans une situation où j'ai pu utiliser TDD et les tests unitaires pour une fonctionnalité majeure. Après la fin de la phase de développement, aucun bug n'a été signalé en plus de 5 ans. Lorsqu'une nouvelle amélioration - et risquée - était demandée, j'ai pu l'implémenter et capturer toutes les régressions dans les tests unitaires.
la source
Je suis fermement convaincu que la valeur des tests unitaires est largement sous-estimée par de nombreuses équipes en raison de plusieurs facteurs, dont beaucoup ont déjà été soulignés dans les réponses.
Les développeurs subissent souvent des pressions pour «faire avancer les choses». Il est donc suffisant de prouver que le fonctionnement d'un bloc de code est une preuve suffisante pour le client. Cela s'applique presque toujours aux sociétés de conseil et aux QA axés sur l'homme: si le client ne nécessite pas de tests unitaires et considère une démonstration en direct suffisante, il échoue totalement puisqu'il doit signer une approbation pour le code susceptible de masquer des erreurs.
Les développeurs sont souvent frustrés. Être programmeur est un travail difficile: terminer une tâche et passer à la suivante est satisfaisant, alors tout le monde veut se dépêcher et finir. Jusqu'à ce qu'ils soient touchés par un bus avec un bug majeur qui se développe des mois après l'assurance qualité initiale. Dans ce scénario, le contrôle qualité automatisé et continu est un problème de gestion plutôt que de développeur (ils seront tout de même payés pour leur travail, peut-être des heures supplémentaires).
Mais il y a une exception
Je crois fermement que l'acceptation du modèle de test automatisé est fonction de "l'humain" des tests en cours. Si vous testez un module Web avec une interface utilisateur, vous êtes plus susceptible, malgré des outils tels que Selenium, de remplir le formulaire vous-même, de voir le résultat et de croire en le déterminisme. Vous oublierez de refaire les tests plus tard ou vous serez trop paresseux pour refaire les tests précédents, et c'est pourquoi les bogues sont parfois découverts plus tard. Pour tirer parti de cela, une forte modularisation du code et des règles strictes sur la "modification de l'ancien code" se sont révélées acceptables dans un environnement bancaire (dans mon expérience professionnelle personnelle).
Au lieu de cela, si le développeur est chargé de développer un module de données hautement automatisé et à volume élevé, il sera plus susceptible d'écrire des tests unitaires approfondis et de les soumettre aux lots de test. En effet, le remplissage d'une charge utile XML importante avec des données converties à partir d'une source de données externe (simulée ou non) n'est pas une tâche à prédominance humaine. Certains développeurs de tests finiront par créer un front-office minuscule et amusant pour ce type de tests spécifique. Lorsque je travaillais sur mon mémoire de maîtrise, je travaillais sur un bus de journalisation qui gérait plus de 6 000 messages Syslog par seconde et je devais mesurer la perte et la corruption des paquets: j’ai naturellement rédigé des tests unitaires et des tests de résistance pour presque tous les composants, en particulier l’analyseur Syslog.
Afin de rendre les développeurs plus sujets aux tests unitaires
Je crois qu'ils doivent être obligés de. Si vous êtes un client intelligent, vos consultants devront exécuter la suite de tests complète à chaque contrôle qualité. Si vous êtes un bon chef d'équipe, vous pouvez peut-être attribuer la tâche suivante à un développeur intelligent: créer une plate-forme de test interne. Cela n'a rien à voir avec l'antipatter interne de la plateforme d'effets, mais plutôt un ensemble de classes d'assistance, de bases de données mock, de configurations, d'analyseurs syntaxiques, de convertisseurs, de couteaux suisses pour aider les développeurs à construire des tests en un rien de temps.
Les plates-formes de test actuelles telles que NUnit sont polyvalentes et vous permettent de vérifier des assertions génériques. L'utilisation correcte d'injection de dépendance et d'usines spécifiques à un projet aide les développeurs à écrire moins de code pour les tests et à être plus heureux. Je n'ai pas encore eu la chance d'expérimenter cela sur un projet complet, je ne peux pas donner de retour d'expérience.
la source
Les tests automatisés s'apparentent au développement de logiciels. Malheureusement, les personnes que vous embauchez pour les tests sont initialement conçues pour rédiger des scénarios de test, des plans, une stratégie, suivre le processus de révision, tester et consigner manuellement les bogues.
Dès qu’ils se voient confier des responsabilités en matière de tests automatisés, cela inclut une partie du développement logiciel. Le problème ici est que les tests automatisés, quels que soient les outils que vous utilisez (et ne craignons pas, ne discutez pas de ce point), nécessitent un entretien et une mise à jour quotidiennement. Comme les développeurs changent de code,
non-functional
tests séparés, et ne vous attendez pas à courir tous les jours, il faut du temps pour garder ces UpToDate, et bon. Mais n'abandonnez pas, assurez-vous qu'ils sont maintenus.Vous échouez pour ces raisons
if
et unewhile
boucle. Parce que franchement aucun cours n'enseigne les tests automatisés, ils n'enseignent que les tests manuels.Celles-ci sont issues de mon expérience de travail pour des entreprises qui prennent les tests automatisés très au sérieux et comprennent que dev est important en tant qu'ingénieur de tests automatisés. Et d'après mon expérience de travail pour des gens qui ne savent pas, comprenez la différence, peu importe combien vous leur expliquez.
la source