2010-09-19 7 views
1

J'ai un test unitaire qui peut spontanément échouer 1 1000000 (supputation) fois même quand il n'y a pas de défaut dans le code. Est-ce une tolérance acceptable ou le manifeste TDD exige-t-il une absolue volonté de fer?Tests unitaires: est "assez bon" assez bon?

Juste pour ceux qui sont intéressés, il va quelque chose comme ça

 
stuff = randomCrap.get() 
stuff2 = randomCrap.get() 
assert(stuff != stuff2) 
+1

Vous ne devriez jamais faire de tests avec des données aléatoires. – halfdan

+5

Lien obligatoire http://stackoverflow.com/questions/462219/xkcd-random-number/620835#620835 –

+0

Selon cette loi et la loi de Murphy, si vous exécutez l'application une seule fois, elle échouera :) – takeshin

Répondre

3

Eh bien, cela dépend vraiment de la source de l'échec. Savez-vous pourquoi échoue? Si oui, avez-vous essayé d'isoler ce défaut afin qu'il ne déclenche pas le test unitaire?

Personnellement, je dirais que si c'est vraiment 1 sur un million et vous savez pourquoi cela se produit, puis ajouter un commentaire à cet effet et ne vous inquiétez pas à ce sujet. Il n'est pas susceptible de déranger les gens de manière significative dans une construction continue, après tout. Bien sûr, si c'est vraiment un sur dix, ou quelque chose comme ça, c'est une question très différente.

Je voudrais au moins essayer pour supprimer la source de l'inexactitude si. D'une part, cela suggère que votre test n'est pas répétable. Parfois c'est correct - il y a des sources de hasard qui sont très difficiles à extraire - mais je ne pas essayer de le faire. Si vous avez essayé et atteint un bloc, alors la chose pragmatique à faire est de le documenter et de passer à autre chose, OMI.

+0

Probablement une journée lente en enfer avant que je crois que ce test sera exécuté un million de fois. Commentez et ignorez, gotcha. – mglmnc

1

Quelle est votre exigence pour combien de fois avant que cette erreur se produise?

Êtes-vous à l'aise, et vos utilisateurs fonctionnels, avec ce qui se passe?

Vous pouvez vous assurer qu'il est écrit que votre génération aléatoire se répète, parfois dans des demandes en double. Pour moi, c'est la partie la plus troublante, cela peut arriver comme vous l'avez montré ci-dessus, et je pense que c'est quelque chose à examiner.

1

Avez-vous absolument utiliser des données aléatoires? Testez-vous un système conçu pour renvoyer deux valeurs aléatoires distinctes? Sinon créez un bout. Les tests unitaires doivent être répétables à 100%, ce qui est difficile à faire lorsque vous utilisez par exemple des threads d'un système de fichiers, mais c'est pour cela que les stubs sont utilisés.

1

Un test unitaire ne peut échouer s'il n'y a pas de défaut dans le code. Il y a un défaut, que ce soit lié au timing, au réseau, etc ... vous ne l'avez pas encore compris. Une fois que vous l'avez compris, vous venez d'apprendre quelque chose que vous ne saviez pas. +1 à vous.

Le vrai problème si elle n'est pas fixe est d'ordre psychologique. Cette méthode aura tendance à être blâmée chaque fois qu'il y a quelque chose d'étrange/aléatoire/inexpliqué qui se passe dans le système. Mieux vaut réparer le hareng rouge maintenant quand vous y pensez.

Et FYI, aléatoire n'implique pas unique.

3

La question n'est pas "Est-ce que TDD me permet d'autoriser un test qui échoue occasionnellement?" mais plutôt: «les exigences de mon système permettent-elles des échecs occasionnels? Et c'est une question que vous seul pouvez répondre.Du point de vue de TDD, il est maladroit d'avoir des tests qui échouent de temps en temps - vous ne savez pas, quand ils échouent, si c'est un de ces rares échecs permis, ou si c'est parce que votre code est cassé dans un manière inacceptable. Ainsi, un test qui échoue occasionnellement vous est beaucoup moins utile que celui qui passe toujours.

Si votre exigence est d'avoir un comportement différent une fois sur un million, vous devez tester cette exigence. Tester le cas général, pas avec un nombre aléatoire, mais avec un sous-ensemble significatif d'entrées valides. Testez le cas particulier avec la valeur qui doit entraîner le comportement spécial.

+0

vous m'avez eu à * vous ne savez pas, quand ils échouent ... * –

0

Votre test affirme que stuff1 est jamais égal à stuff2, mais voyant le test échouer occasionnellement signifie que ce n'est pas vrai.

Vous pourriez être en mesure d'affirmer que stuff1 est parfois égale à stuff2 en prenant un million d'échantillons et d'affirmer que la fréquence d'être égale est inférieure à 10, mais cela ne fonctionne pas de temps en temps - mais peut-être beaucoup moins souvent que pourrait être acceptable.

Vous pourriez être mieux avec:

stuff = 4 
stuff2 = 5 
assert(stuff != stuff2) 

Vous pouvez être certain que le code ci-dessus effectuera le même que votre code d'origine une fois dans un million de millions de fois - mais vous êtes certain que ce code passer à chaque fois!

Questions connexes