【问题标题】:How to use a random seed value in order to unittest a PRNG in Python?如何使用随机种子值在 Python 中对 PRNG 进行单元测试?
【发布时间】:2017-11-07 17:48:57
【问题描述】:

我对编程还是很陌生,只是学习如何进行单元测试。我需要测试一个返回随机值的函数。到目前为止,我已经找到了建议使用特定种子值的答案,以便“随机”序列是恒定的并且可以进行比较。这是我到目前为止所得到的:

这是我要测试的功能:

import random

def roll():
    '''Returns a random number in the range 1 to 6, inclusive.'''
    return random.randint(1, 6)

这是我的单元测试:

class Tests(unittest.TestCase):

    def test_random_roll(self):
        random.seed(900)
        seq = random.randint(1, 6)
        self.assertEqual(roll(), seq)

如何在函数中为PRNG设置对应的种子值,以便在不写入函数本身的情况下进行测试?或者这是测试随机数生成器的完全错误的方法?

谢谢

【问题讨论】:

  • 可能想看看this question
  • @JaredGoguen 谢谢,我看过但不能完全理解他们的建议。似乎有 'seq = random.randint' 是我的问题,我不明白函数调用会使用测试中指定的种子。

标签: python random


【解决方案1】:

其他答案是正确的。在这里,我正在回答如何测试随机数生成器的更深层次的问题:

您提供的函数并不是真正的随机数生成器,因为它的整个实现依赖于提供的随机数生成器。换句话说,您相信 Python 为您提供了一个合理的随机生成器。对于大多数目的,这是一件好事。如果您正在编写加密原语,您可能想要做其他事情,此时您会想要一些真正强大的测试策略(但它们永远不够)。

测试一个函数返回一个特定的数字序列几乎不会告诉你你的函数在“产生随机数”方面的正确性。预定义的数字序列与随机序列相反。

那么,您真正想要测试什么?对于'滚动'功能,我想你想测试一下:

  1. 如果掷出“足够”,它会产生 1 到 6 之间的所有数字,最好是“大约”相等的比例。
  2. 它不会产生任何其他东西。

1. 的问题在于您的函数被定义为一个随机序列,因此您为定义“足够”或“大约等于”而设置的任何硬限制偶尔会失败的可能性总是非零。您可以进行一些计算来选择一些限制,以确保您的测试不太可能失败,例如十亿分之一,或者你可以打一个 random.seed() 调用,这意味着如果它通过一次就永远不会失败(除非 Python 的底层实现发生变化)。

项目 2. 可以更容易地“测试” - 生成大量“N”个项目,检查所有项目是否都在预期结果范围内。

然而,对于所有这些,我会问单元测试的实际价值是什么。您实际上无法编写测试来检查某事是否“随机”。要查看该函数是否具有合理的随机性来源并正确使用它,测试是无用的——您必须检查代码。一旦你这样做了,很明显你的函数是正确的(假设 Python 提供了一个不错的随机数生成器)。

简而言之,这是单元测试提供极少价值的情况之一。我可能只写一个测试(上面的第 2 项),然后就这样了。

【讨论】:

    【解决方案2】:

    通过使用已知种子播种 prng,您知道它将产生哪个序列,因此您可以测试该序列:

    class Tests(unittest.TestCase):
        def test_random_roll(self):
            random.seed(900)
            self.assertEqual(roll(), 6)
            self.assertEqual(roll(), 2)
            self.assertEqual(roll(), 5)
    

    【讨论】:

    • 谢谢!似乎我不太明白函数调用会自动使用测试中的种子,而我可以手动检查该种子的值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-18
    • 1970-01-01
    • 2017-07-01
    • 2014-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多