Écrire du code "testable par unité"?

Quel genre de pratiques utilisez-vous pour rendre votre code plus convivial pour les tests unitaires?

37
demandé sur Dana Holt 2009-06-17 18:38:44

19 réponses

  • TDD -- Ecrire les tests en premier, forces vous de penser à la testabilité et aide à écrire le code qui est réellement besoin, pas ce que vous pensez que vous pouvez besoin

  • Refactoring aux interfaces -- rend se moquer plus facilement

  • Méthodes Publiques virtuel si vous n'utilisez pas interfaces -- facilite la moquerie

  • Injection de dépendance-rend moqueur plus facile

  • Méthodes plus petites et plus ciblées -- les tests sont plus ciblés, plus faciles de écrire

  • Éviter les classes statiques

  • Évitez les singletons, sauf si nécessaire

  • Éviter les classes scellées

53
répondu tvanfosson 2009-06-17 14:47:54

L'injection de dépendance semble aider.

13
répondu dss539 2009-06-17 14:40:47

Écrivez d'abord les tests - de cette façon, les tests pilotent votre conception.

10
répondu Shane Fulmer 2009-06-17 14:40:02
  1. utiliser TDD
  2. Lorsque vous écrivez du code, utilisez l'injection de dépendance dans la mesure du possible
  3. Programme aux interfaces, pas aux classes concrètes, de sorte que vous pouvez substituer des implémentations fictives.
7
répondu PaulJWilliams 2009-06-17 14:44:00

Assurez-vous que toutes vos classes suivent le principe de Responsabilité Unique . Une seule responsabilité signifie que chaque classe devrait avoir une et une seule responsabilité. Cela rend les tests unitaires beaucoup plus faciles.

7
répondu Robert Cartaino 2009-06-17 14:45:22

Lors de l'écriture de tests (comme pour toute autre tâche logicielle), ne vous répétez pas (Principe sec). Si vous avez des données de test utiles pour plus d'un test, placez-les quelque part où les deux tests peuvent l'utiliser. Ne copiez pas le code dans les deux tests. Je sais que cela semble évident mais je le vois arriver tout le temps.

5
répondu ssteidl 2009-06-17 16:02:59

Le plus simple est de ne pas vérifier votre code à moins de vérifier les tests avec.

Je ne suis pas un grand fan d'écrire les tests en premier. Mais une chose que je crois très fortement est que le code doit être vérifié dans avec tests. Même pas une heure avant, togther. Je pense que l'ordre dans lequel ils sont écrits est moins important tant qu'ils entrent ensemble.

4
répondu JaredPar 2009-06-17 14:43:08

Petites méthodes très cohésives. J'ai appris à la dure. Imaginez que vous avez une méthode publique qui gère l'authentification. Peut-être que vous avez fait TDD, mais si la méthode est grande, il sera difficile de déboguer. Au lieu de cela, si cette méthode # authenticate fait des choses d'une manière plus pseudo-codish, en appelant d'autres petites méthodes (peut-être protégées), quand un bug apparaît, il est facile d'écrire de nouveaux tests pour ces petites méthodes et de trouver le défectueux.

4
répondu Maximiliano Guzman 2009-06-17 14:47:39

Et quelque chose que vous apprenez la première chose en POO, mais tant semble oublier: Code contre les Interfaces, pas les implémentations .

4
répondu alexn 2009-06-17 14:50:25

Passez du temps à refactorer le code untable pour le rendre testable. Écrivez les tests et obtenez une couverture de 95%. Faire cela m'a appris tout ce que j'ai besoin de savoir sur l'écriture de code testable. Je ne suis pas opposé à TDD, mais apprendre les spécificités de ce qui rend le code testable ou untestable vous aide à penser à la testabilité au moment de la conception.

4
répondu Robert 2009-06-17 14:53:39
4
répondu cwash 2009-06-17 15:55:05

Je suis sûr que je serai en baisse voté pour cela, mais je vais exprimer l'opinion de toute façon:)

Bien que beaucoup de suggestions ici aient été bonnes, je pense qu'il faut les tempérer un peu. L'objectif est d'écrire des logiciels plus robustes, modifiables et maintenables.

Le but n'est pas d'avoir du code qui est testable par unité. Il y a beaucoup d'efforts pour rendre le code plus "testable" malgré le fait que le code testable n'est pas le but. Ça sonne vraiment bien et je suis sûr que ça donne les gens les fuzzies chauds, mais la vérité est que toutes ces techniques, cadres, tests, etc., ont un coût.

Ils coûtent du temps en formation, maintenance,frais généraux de productivité, etc. Parfois, ça vaut le coup, parfois ce n'est pas le cas, mais vous ne devriez jamais mettre les oeillères et charger à l'avance pour rendre votre code plus "testable".

4
répondu Fred 2009-06-17 16:04:28

J'utilise le développement piloté par les tests autant que possible, donc je n'ai pas de code qui ne peut pas être testé à l'unité. Il n'existerait pas à moins que le test unitaire n'existe en premier.

3
répondu John Saunders 2009-06-17 14:40:20
1.Using a framework/pattern like MVC to separate your UI from you
business logic will help a lot. 
2. Use dependency injection so you can create mock test objects.
3. Use interfaces.
3
répondu Jeffrey Hines 2009-06-17 14:52:09

Vérifiez cette présentation Modèles de test automatisés et odeurs . L'un des principaux points à retenir pour moi, était de s'assurer que le code UnitTest est de haute qualité. Si le code est bien documenté et bien écrit, tout le monde sera motivé pour continuer.

2
répondu Nir Ofry 2009-06-17 20:06:26

Pas de statique - vous ne pouvez pas vous moquer de la statique.

Google dispose également d'un outil qui permettra de mesurer la testabilité de votre code...

1
répondu Michael Wiles 2009-06-17 16:49:56

J'essaie continuellement de trouver un processus où les tests unitaires sont moins une corvée et quelque chose que je veux réellement faire. Dans mon expérience, un facteur assez important est vos outils. Je fais beaucoup de travail ActionScript et malheureusement, les outils sont quelque peu limités, tels que l'absence d'intégration IDE et le manque de frameworks moqueurs plus avancés (mais les bonnes choses sont à venir, donc pas de plaintes ici!). J'ai déjà fait du développement piloté par les tests avec des frameworks de test plus matures et c'était certainement un plus expérience agréable, mais encore ressenti comme un peu d'une corvée.

Récemment, j'ai commencé à écrire du code d'une manière différente. J'avais l'habitude de commencer par écrire le test, les regarder échouer, écrire du code pour réussir le test, rincer et répéter et tout cela.

Maintenant, cependant, je commence par écrire des interfaces, presque peu importe ce que je vais faire. Au début, j'essaie bien sûr d'identifier le problème et de penser à une solution. Ensuite, je commence à écrire les interfaces pour obtenir une sorte de sensation abstraite pour le code et la communication. À ce moment-là, je me rends compte généralement que je n'ai pas vraiment trouvé une solution appropriée au problème du tout en raison de ma compréhension incomplète du problème. Je reviens donc, révise la solution et révise mes interfaces. Quand je sens que les interfaces reflètent ma solution, je commence par écrire l'implémentation, pas les tests. Quand j'ai quelque chose mis en œuvre (projet d'implémentation, généralement des étapes de bébé), je commence à le tester. Je garde revenir en arrière entre les tests et la mise en œuvre, quelques pas en avant à la fois. Puisque j'ai des interfaces pour tout, il est incroyablement facile d'injecter des mocks.

Je trouve que travailler comme ça, avec des classes ayant très peu de connaissances sur les autres implémentations et ne parlant qu'aux interfaces, est extrêmement libérateur. Cela me libère de penser à la mise en œuvre d'une autre classe et je peux me concentrer sur l'unité actuelle. Tout ce que j'ai besoin de savoir est le contrat que l'interface fournit.

Mais ouais, j'essaie toujours d'élaborer un processus qui fonctionne super-fantastiquement-awesomely-bien à chaque fois.

Oh, je voulais aussi ajouter que je n'écris pas de tests pour tout. Les propriétés de vanille qui ne font pas grand-chose mais get/set variables sont inutiles à tester. Ils sont garantis par le contrat de travail linguistique. Si ce n'est pas le cas, j'ai des problèmes bien pires que ceux de mes unités qui ne sont pas testables.

1
répondu Marcus Stade 2009-06-17 17:12:54

Pour préparer votre code testable:

  • documentez vos hypothèses et exclusions.
  • évitez les grandes classes complexes qui font plus d'une chose - gardez à l'esprit le principe de Responsabilité Unique .
  • lorsque cela est possible, utilisez des interfaces pour découpler les interactions et permettre l'injection d'objets fictifs.
  • lorsque cela est possible, rendez la méthode pubienne virtuelle pour permettre aux objets fictifs de les émuler.
  • si possible, utilisez la composition plutôt que héritage dans vos conceptions-cela encourage également (et prend en charge) l'encapsulation des comportements dans les interfaces.
  • lorsque cela est possible, utilisez les bibliothèquesdependency injection (ou les pratiques DI) pour fournir aux instances leurs dépendances externes.

Pour tirer le meilleur parti de vos tests unitaires, considérez ce qui suit:

  • Renseignez-vous, ainsi que votre équipe de développement, sur les capacités du framework de test unitaire, des bibliothèques moqueuses et des outils de test vous avez l'intention d'utiliser. Comprendre ce qu'ils peuvent et ne peuvent pas faire sera essentiel lorsque vous commencez réellement à écrire vos tests.
  • planifiez vos tests avant de commencer à les écrire. Identifiez les cas périphériques, les contraintes, les conditions préalables, les postconditions et les exclusions que vous souhaitez inclure dans vos tests.
  • corrigez les tests brisés aussi près que possible lorsque vous les Découvrez. Les Tests vous aident à découvrir les défauts et les problèmes potentiels dans votre code. Si vos tests sont brisés, vous ouvrez la porte à avoir à réparer plus de choses plus tard.
  • Si vous suivez un processus de révision de code dans votre équipe, passez également en revue vos tests unitaires. Les tests unitaires font autant partie de votre système que n'importe quel autre code - les examens aident à identifier les faiblesses dans les tests comme ils le feraient pour le code système.
1
répondu LBushkin 2016-04-14 20:37:05

Vous n'avez pas nécessairement besoin de "rendre votre code plus convivial pour les tests unitaires".

Au Lieu de cela, une boîte à outils moqueuse peut être utilisée pour faire disparaître les problèmes de testabilité. Une telle boîte à outils est JMockit .

0
répondu Rogério 2009-06-21 03:12:18