Comment dois-je tester mon code TEST?

22

La plupart des développeurs de logiciels sont d'accord sur le fait que vous ne devez pas vous fier au code pour fonctionner correctement, sauf si vous le testez. Si vous ne le testez pas, il peut y avoir des bogues cachés qui ne feront que vous obliger à travailler plus sur la route.

Je comprends comment tester mon code normal, mais comment dois-je tester mon code de test pour m'assurer qu'il peut effectivement détecter et signaler des erreurs lorsqu'elles sont présentes? Personnellement, j'ai été assez stupide pour écrire des cas de test erronés qui passeraient alors qu'ils n'auraient pas dû, ce qui a déjoué le but de mes tests de rédaction. Heureusement, j'ai trouvé et corrigé les erreurs dans le temps, mais selon le mantra des tests, il semble qu'aucune suite de tests ne serait complète sans avoir son propre ensemble de tests pour s'assurer que cela fonctionne.

Il me semble que la meilleure façon de le faire serait de m'assurer que le test échoue pour le code bogué. * Si je passe alternativement 2 minutes à ajouter des bogues au code et à m'assurer qu'il échoue, je devrais avoir un degré de confiance acceptable que les tests «fonctionnent». Cela m'amène à ma deuxième question: quels sont les bons moyens d'introduire des bogues pour s'assurer qu'ils sont détectés par les cas de test? Si je commente simplement des instructions au hasard, assurez-vous que la mauvaise branche d'un if-elseest exécutée en annulant sa condition et modifiez l'ordre d'exécution du code avec des effets secondaires, etc., jusqu'à ce que je sois convaincu que mes tests attraperont le plusbugs communs? Comment les développeurs professionnels valident-ils que leurs tests font réellement ce qu'ils sont censés faire? Supposent-ils simplement que les tests fonctionnent, ou prennent-ils aussi le temps de les tester? Si oui, comment testent-ils les tests?

Je ne suggère pas aux gens de passer autant de temps à tester leurs tests, puis à tester les tests pour leurs tests qu'ils n'écrivent jamais réellement le vrai code, mais j'ai fait suffisamment de choses stupides pour que je pense pouvoir en bénéficier un peu. de «méta-tests», et était curieux de savoir la meilleure façon de procéder. :RÉ

* Je pourrais vérifier si le test réussit lors du test de code `` sans bogue '', mais utiliser le code comme spécification pour le test semble assez à l'envers ...

Gordon Gustafson
la source
On dirait que vous n'avez pas confiance en vos tests unitaires - probablement parce que vous manquez beaucoup d'expérience dans la rédaction de tests? Dans ce cas, il serait déraisonnable d'écrire plus de tests et de s'attendre à un résultat différent. Continuez simplement à faire ce que vous faites, soyez aussi minutieux que possible (testez l'échec aussi bien que le succès) et bientôt vos tests unitaires commenceront à payer pour eux-mêmes - et votre confiance en eux augmentera.
MattDavey
Copie possible de Comment tester les tests?
gnat
Avant d'utiliser plus d'outils, utilisez mieux vos outils réels . Écrivez moins de tests, mais des tests écrits plus efficaces et meilleurs. Vous ne pouvez pas faire confiance à quelque chose que vous ne comprenez pas.
Steve Chamaillard

Réponses:

16

Le flux standard pour TDD est:

  1. Écrivez un test qui échoue. (Rouge)
  2. Faites le plus petit changement de code qui le fasse passer (vert)
  3. Refactor (en le gardant vert)

Le test de vos tests dans ce cas est l'étape 1 - assurez-vous que le test échoue avant d'apporter des modifications au code.

Un autre test que j'aime est de savoir si vous pouvez supprimer du code et le réimplémenter d'une manière différente, et vos tests échouent après la suppression mais fonctionnent avec un algorithme différent en place.

Comme pour tout, il n'y a pas de solution miracle. Oublier d'écrire un test requis est tout aussi facile pour un développeur que d'oublier d'écrire le code. Au moins, si vous faites les deux, vous avez deux fois plus d'occasions de découvrir votre omission.

Bringer128
la source
4
Double comptabilité: Les tests unitaires testent le code de production et vice versa. Ce sont deux façons différentes d'énoncer le même problème. Comme dans la double comptabilité, où vous enregistrez vos transactions de deux manières différentes et les deux doivent obtenir les mêmes totaux.
EricSchaefer
La question concerne le problème lorsque l'étape 2 rend le test vert même si le code est toujours bogué. Exemple simple: vous avez une fonction qui doit renvoyer un pointeur sur un objet liste non vide. Votre test teste si le pointeur est nullet échoue à l'étape 1. Vous apportez la plus petite modification de code qui le fait passer en renvoyant une liste vide. Le test est désormais "vert" car vous avez deux bugs.
Christian Hackl
@ChristianHackl à ce stade de développement, c'est une mise en œuvre parfaite! Vous devez ajouter un (ou plusieurs) tests qui échouent au début pour préciser davantage le comportement attendu. Par la suite, vous l'implémentez, ce qui rend ces tests verts.
Andy
@Andy: Vous voulez savoir comment il s'agit d'une implémentation parfaite lorsque j'ai un bug à la fois dans le code et dans le test, et que l'un m'empêche de remarquer l'autre? (Le bogue dans le code est qu'une liste vide est retournée, et le bogue dans le test est que je vérifie nullet non pas vide.)
Christian Hackl
@ChristianHackl vous avez raison selon le chèque vide. Cela, en effet, devrait également être fait dans un test. Lorsque vous traduisez vos exigences en tests, étape par étape, il y a peu de place pour les bugs. Sauf ceux où vous ne respectez pas les spécifications (comme oublier un chèque non vide).
Andy
9

Une approche est le test de mutation , utilisant un outil comme Jester :

Jester modifie votre code, exécute vos tests et si les tests réussissent, Jester affiche un message indiquant ce qu'il a changé

parsifal
la source
4

Des tests pour des tests? Ne prenez pas cette route. Ensuite, vous aurez probablement besoin de tests pour tests pour tests, puis de tests pour tests pour tests pour tests ... où vous arrêtez-vous?

Le flux de test habituel va comme ceci, et en tant que développeur, vous passerez la majorité de votre temps sur les points 1-3:

  1. Code
  2. Tests unitaires
  3. Tests d'intégration
  4. Système / autre automatisé
  5. QA / testeurs humains

Si je passe alternativement 2 minutes à ajouter des bugs au code (...)

Votre code finira par "grossir" ses propres bugs, ne perdez pas de temps à les introduire à la main. Sans oublier, est-ce qu'une chose que vous saviez à l'avance est vraiment un bug? Des bugs viendront, je ne m'en inquiéterais pas.

Si je commente simplement des déclarations au hasard, assurez-vous que la mauvaise branche d'un if-else est exécutée en annulant sa condition (...)

Il s'agit en fait d'une approche viable pour vérifier si vous testez réellement ce que vous pensez faire. Je ne pense pas que ce soit toujours aussi bon car il souffre du même problème que la chose "test pour test pour test ...": quand arrêtez-vous de modifier le code sachant que le code que vous testez fonctionne à 100%?

Il est également bon de se souvenir des conseils classiques du programmeur pragmatique - vous n'en aurez pas besoin . Soyez agile, écrivez des tests et du code pour les bogues réels, au lieu de ceux hypothétiques qui pourraient ou non apparaître.

km
la source
3
Je ne m'inquiète pas de voir mon code augmenter ses propres bogues, je m'inquiète que mes tests les détectent lorsqu'ils se produisent. Si mes tests sont défectueux, ils ne feront pas leur travail et je penserai que je me suis débarrassé d'une certaine classe de bogues alors qu'ils existent encore, rendant mon travail plus difficile car je regarde des résultats de test inexacts (passer quand ils devraient échouer).
Gordon Gustafson
@CrazyJugglerDrummer: vos tests n'attraperont pas tous les bugs c'est sûr. Ils ne servent pas cet objectif - c'est là qu'intervient l'AQ. S'ils le faisaient, cela signifierait que le logiciel est exempt de bogues, à moins que le code source ne change, ce que je n'ai jamais vu.
km
3

Par construction, le code fonctionnel et le code de test sont testés l'un contre l'autre. Un problème subsiste: le cas des bogues en mode commun, lorsqu'un bogue dans le code fonctionnel est masqué par un bogue dans le code de test. TDD n'est pas à l'abri de cet effet. C'est pourquoi les tests sont généralement effectués à plusieurs niveaux par différentes personnes afin de diminuer cette probabilité.

mouviciel
la source
0

Vous testez votre test unitaire une fois que vous l'écrivez, dans le débogueur. Ensuite, vous le laissez tranquille et vous l'oubliez. Il n'y a pas de problème ici.

Considère ceci. À quoi sert un test unitaire? Il vous avertit lorsque l'une des nombreuses modifications que vous apporterez à votre programme principal modifie accidentellement la logique de ce programme. Vous voulez avoir cela parce que vous savez que tout changement peut potentiellement casser quelque chose. C'est exactement pourquoi il n'y a pas de problème si vous ne testez pas votre test: vous ne dérangez pas votre test jusqu'à ce que vous changiez délibérément la logique de votre programme (ce qui vous obligerait à revoir le test et à le tester à nouveau), donc votre le test ne risque pas de se casser accidentellement.

Martin Maat
la source
-2

Il existe un test de mutation qui évalue et mesure la pertinence et la qualité du test.

Nous pouvons l'utiliser pour évaluer "le test" lui-même.

En bref, nous pouvons évaluer notre test (par exemple TestA) en testant TestA peut trouver la différence entre le code et ses codes de mutation (code très similaire mais légèrement différent du code original).

Si TestA ne peut pas trouver la différence entre le code et ses codes de mutation, cela signifie que le TestA a des réglementations trop approximatives pour tester le code d'origine.

Chasseur de poulet
la source