J'ai une carte à jouer de classe qui représente une carte de jeu particulière. J'ai une autre classe, pont, qui contient une liste d'objets de jeu à jouer. Deck a une méthode Je voudrais écrire des tests unitaires pour la méthode Shuffle (), mais je suis à un peu de perte. Je préférerais que le test ne se soucie pas des internes de la façon dont le shuffle est fait, mais je veux qu'ils soient de bons tests. P>
Comment est-ce que c'est le meilleur test de l'unité lorsque le hasard est impliqué? p> shuffle () code> aléatoire la commande de carte. P>
7 Réponses :
ajoutez plus de tests descriptifs comme vous le souhaitez. Qualité du shuffle, aléatoire, etc ... p>
Comme Alex Martelli a souligné, vous pouvez effectuer une analyse statistique du tri pour confirmer qu'il est trié dans le degré que vous attendez. P>
Le meilleur résultat est que chaque position de la carte a changé. Signification, chacune des 52 cartes est maintenant dans une nouvelle position. Vous pouvez prendre mon approche ci-dessus, enregistrer le nombre d'éléments différents et définir un seuil pour le test. P>
Attendez-vous à au moins 20 cartes dans de nouvelles positions. Créez la liste, copiez-le, triez-le, puis comparez-le. Si le résultat est inférieur à 20, échouez, sinon passez. P>
Il y a quelques petites chances que la commande soit la même après le mélange.
Dites les chances du shuffle renvoyant la même liste qu'il a été donnée est p. Ensuite, 100% - P de l'époque, ce test fonctionnera correctement. Peu importe ce que vous faites, il y aura toujours un p. Vous pouvez le rendre plus petit en ré-exécutant sur l'échec, mais cela vous coûtera plus de temps de test. Qui est généralement considéré comme une mauvaise chose.
Une approche consiste à faire des tests statistiques; Après chaque vérification de la correction de la correction (la Set em> des cartes ne doit pas avoir été modifiée, seule la commande) et collecter des statistiques sur certaines variables aléatoires ("position des 7 diamants" "est le 5 des clubs avant ou après les 8 cœurs », etc., etc.) à tester après un nombre approprié de shuffles par T-Test et autres approches de test d'hypothèse statistique. P>
une bonne question. Premièrement, un test absolu de passage / échec: après le mélange, le multiviseur (par exemple le tri après le tri) doit être inchangé. P>
Pour tester le hasard, vous devrez faire suffisamment de mélanges que la probabilité d'une fausse défaillance «pas suffisamment aléatoire» est trop petite. Par exemple: P>
Il y a une durée de chanson .0000001% que, dans 10000, une carte particulière est dans l'une des 52 fentes données inférieures à (1-E) / 52 ou supérieures à (1 + E) / 52. (Pour certains petits E, je ne sais pas hors tension comment le calculer). P>
Un programme correct peut "échouer" un tel test, mais ne devrait pas échouer très souvent. P>
en ce qui concerne le mélange; Une échec commun est de faire ceci: p>
pour i de 1..52: qui ne vous donne aucune permutation avec une probabilité égale; cela, cependant, fait: p>
pour i de 1..52:
Choisissez un J aléatoire de
Choisissez un J aléatoire de I STRUT> .. 52 et SWAP CARD I avec une carte J ( droite em>) p>
Je n'ai pas de idées particulières sur l'unité testant cela, mais une note rapide sur l'algorithme que vous utilisez. Il est très facile à créer naïvement et inconsciemment créer un algorithme de shuffle biaisé. Pas besoin de réinventer la roue-the Fisher-Yates Shuffle garantira un mélangé impartial, s'il est mis en œuvre correctement . P>
Il y a des pièges faciles que vous pourriez frapper si vous ne faites pas correctement: p>
MOD 52 code> pour obtenir des positions de carte aléatoire. Conduit également à un léger biais. Li>
ul> Puisque je n'ai pas essayé cela, je ne peux pas dire immédiatement à quel point il est pratique, mais il devrait être possible de faire des tests d'unité avec de petits ponts et un générateur de nombres aléatoires déterministe déterministe, de manière exhaustive telle que le shuffler produire chaque permutation possible une fois. p>
Il y a eu l'objet d'un fil exhaustif (ou épuisant) sur la liste des groupes Yahoo TDD il y a quelques années. Ron Jeffries a une autre Insights utiles mais mais il est préférable de commencer à Le haut . p>
Votre objectif est de tester Shuffle (). Puisque vous savez comment vous avez construit Shuffle (), ce serait un test d'unité déterministe de votre pont initial contre la terrasse mélangée si vous avez pu connaître la série de nombres générés.
Ceci est un cas où injecter une méthode dans Votre classe de deck () pendant les tests peut rendre votre fonction de lecture mobile déterministe. p>
Construisez votre classe à utiliser la fonction aléatoire () par défaut mais pour utiliser une fonction de génération de nombres prédéterminée lorsqu'il est injecté. Par exemple, dans Python, vous pouvez faire: P>
class Deck():
def __init__(self, rand_func = random.random):
self._rand = rand_func
def rand(self):
return self._rand()
Une idée serait de courir le shuffler sur une terrasse triée et de lancer un algorithme de distance pour voir comment "loin" le shuffle sort; et courir continuellement et comparer aux permutations antérieures à un certain point (disons 10-12 mélanges avec des exigences dégradantes de la distance) et comparez ensuite ces valeurs à la différence optimale - vous devrez tester et obtenir ces chiffres vous-même.