8
votes

Tester un pont de carte shuffler

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 shuffle () aléatoire la commande de carte.

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.

Comment est-ce que c'est le meilleur test de l'unité lorsque le hasard est impliqué?


1 commentaires

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.


7 Réponses :


0
votes
  1. Créer une liste.
  2. Créez une copie profonde de cette liste.
  3. Mélangez la première liste.
  4. Assert List1! = List2

    ajoutez plus de tests descriptifs comme vous le souhaitez. Qualité du shuffle, aléatoire, etc ...

    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.

    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.

    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.


2 commentaires

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.



10
votes

Une approche consiste à faire des tests statistiques; Après chaque vérification de la correction de la correction (la Set 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.


0 commentaires

1
votes

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é.

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:

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).

Un programme correct peut "échouer" un tel test, mais ne devrait pas échouer très souvent.

en ce qui concerne le mélange; Une échec commun est de faire ceci:

pour i de 1..52:
Choisissez un J aléatoire de 1 .. 52 et carte d'échange I avec une carte J ( mauvais )

qui ne vous donne aucune permutation avec une probabilité égale; cela, cependant, fait:

pour i de 1..52:
Choisissez un J aléatoire de I .. 52 et SWAP CARD I avec une carte J ( droite )


0 commentaires

5
votes

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 .

Il y a des pièges faciles que vous pourriez frapper si vous ne faites pas correctement:

  • Prenez chaque carte i et échangez-la avec une autre carte aléatoire j dans le pont où j peut être n'importe quelle carte, même une partie d'un position déjà visitée. Ceci est un shuffle biaisé.
  • Prendre la sortie d'un MOD 52 pour obtenir des positions de carte aléatoire. Conduit également à un léger biais.

0 commentaires

-2
votes

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.


0 commentaires

1
votes

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 .


0 commentaires

5
votes

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()


0 commentaires