测试卡牌洗牌机

Bra*_*ugh 8 unit-testing

我有一个类PlayCard代表一个特定的扑克牌.我有另一个类Deck,它包含一个PlayingCard对象列表.Deck有一种shuffle()随机化卡片顺序的方法.

我想为shuffle()方法编写一些单元测试,但我有点不知所措.我更喜欢测试不关心洗牌是如何完成的内部,但我希望它们是好的测试.

当涉及随机性时,我如何进行最佳单元测试?

Ale*_*lli 10

一种方法是进行统计检验; 在每次洗牌之后检查是否正确(一卡片不得更改,只有订单),并收集有关一些随机变量的统计数据("7颗钻石的位置","是8号俱乐部之前或之后的5条)通过学生t检验和其他统计假设检验方法在适当数量的改组之后测试心脏"等" .


Joh*_*ica 5

我对单元测试没有特别的想法,但是关于你使用的算法的快速说明.很容易天真地在不知不觉中创建一个有偏差的混洗算法.无需重新发明轮子 - 如果正确实施,Fisher-Yates shuffle将保证无偏见的随机播放.

如果您没有正确执行FY,可能会遇到一些容易陷入的陷阱:

  • 每次取卡和另一个随机卡掉它Ĵ在甲板上,其中Ĵ可以是任何卡,甚至是一个从已经访问过的位置.这一个有偏见的洗牌.
  • mod 52获取RNG的输出以获得随机卡位置.也导致轻微的偏见.


小智 5

你的目标是测试shuffle().既然你知道如何构造shuffle(),那么如果你能够知道生成的一系列数字,它将是你的初始套牌与洗牌套牌的确定性单位测试.

这种情况是在测试期间将方法注入Deck()类可以使您的shuffle函数具有确定性.

构建类以默认使用random()函数,但在注入时使用预定的数字生成函数.例如,在Python中,您可以:

class Deck():
   def __init__(self, rand_func = random.random):
      self._rand = rand_func
   def rand(self):
      return self._rand()
Run Code Online (Sandbox Code Playgroud)

当简单地使用没有参数的Deck时,您将得到预期的随机数.但是,如果您制作自己的随机数函数,则可以生成预定的数字序列.

通过这种结构,您现在可以构建一个初始牌组(无论您想要的大小)和随机数列表(同样,您需要的任何大小),您将知道输出的内容.因为shuffle()在注入版本和真正随机版本之间不会发生变化,所以您可以确定性地对shuffle()进行单元测试,并且在运行时具有随机行为.如果有要测试的边角情况,您甚至可以生成多个不同的数字序列.

关于涉及统计建模的其他答案:我认为这些是接受程度测试以证明"shuffle"算法的正确性,但它没有确定性地对函数shuffle()的实现进行单元测试.