Python 如何测试使用随机变量的函数?

Python 如何测试使用随机变量的函数?,python,unit-testing,Python,Unit Testing,它试图为具有线性seqarch数组体系结构的词典编写popitem函数。你能给我举个例子吗,我应该如何用unittests测试这个函数 def popitem(self): number = self.keys_list[random.randint(0, len(self.keys_list))] i = 0 while i < len(self.values_list): if i == number: needed_k

它试图为具有线性seqarch数组体系结构的词典编写
popitem
函数。你能给我举个例子吗,我应该如何用unittests测试这个函数

def popitem(self):
    number = self.keys_list[random.randint(0, len(self.keys_list))] 
    i = 0
    while i < len(self.values_list):
        if i == number:
            needed_key = self.keys_list[i]
            needed_value = self.values_list[i]
            self.keys_list.remove(needed_key)
            self.values_list.remove(needed_value)
            return (needed_key, needed_value)
def popitem(自身):
number=self.keys\u list[random.randint(0,len(self.keys\u list))]
i=0
而i
将函数一分为二:

def popitem(self):
    number = self.keys_list[random.randint(0, len(self.keys_list))]
    return self._popitem(number)

def _popitem(self, number):
    i = 0
    ...
现在使用硬编码值测试
\u popitem
。这也将使您的测试更易于阅读和控制

顺便说一句,如果我了解您在函数中试图做什么,下面是我将如何实现它:

def _popitem(self, number):
    i = self.keys_list.index(number)
    return (
        self.keys_list.pop(i),
        self.values_list.pop(i),
    )

将功能一分为二:

def popitem(self):
    number = self.keys_list[random.randint(0, len(self.keys_list))]
    return self._popitem(number)

def _popitem(self, number):
    i = 0
    ...
现在使用硬编码值测试
\u popitem
。这也将使您的测试更易于阅读和控制

顺便说一句,如果我了解您在函数中试图做什么,下面是我将如何实现它:

def _popitem(self, number):
    i = self.keys_list.index(number)
    return (
        self.keys_list.pop(i),
        self.values_list.pop(i),
    )

如果要测试随机数生成器的行为,请修复种子。对于random,可以使用
random.seed(seed)
,或者如果使用
numpy
可以使用
np.random.seed(seed)

然而,我将提供一个替代方案,一个非常重要的概念,叫做模仿

您可以使用模拟将所有函数调用重定向到
random.randint()

from unittest import mock
import random
mocked_random_choice = lambda : 1000
with mock.patch('random.randint', mocked_random_choice):
    popitem(...) # any call to random.int will now output 1000.
如果要编写适当的测试,您很可能会遇到
unittest
pytest
。它们具有广泛的功能,其中之一是允许您从接口的任何输入注入预期的行为。这就是所谓的“嘲弄”


很明显,您可以在这里使用不同的补丁来放置不同的函数。您可以测试边界、返回顺序值等。它为您测试程序中各种可能的漏洞提供了更大的灵活性。

如果要测试随机数生成器的行为,请修复种子。对于random,可以使用
random.seed(seed)
,或者如果使用
numpy
可以使用
np.random.seed(seed)

然而,我将提供一个替代方案,一个非常重要的概念,叫做模仿

您可以使用模拟将所有函数调用重定向到
random.randint()

from unittest import mock
import random
mocked_random_choice = lambda : 1000
with mock.patch('random.randint', mocked_random_choice):
    popitem(...) # any call to random.int will now output 1000.
如果要编写适当的测试,您很可能会遇到
unittest
pytest
。它们具有广泛的功能,其中之一是允许您从接口的任何输入注入预期的行为。这就是所谓的“嘲弄”


很明显,您可以在这里使用不同的补丁来放置不同的函数。您可以测试边界、返回顺序值等。它为您测试程序中各种可能的漏洞提供了更大的灵活性。

如果您修复seed()并使用相同的操作,randint()的“随机性”是可预测的,就像可重复的一样。至少在同一台机器上,使用相同的pyton版本应该是这样的——但不能保证使用相同种子的不同python版本会为相同的种子提供相同的序列。这就是你想要的吗?只要给随机数生成器添加一个硬编码种子值,它就会从那一点返回相同的序列。调用是随机的。seed(某些值),此函数是…中断重复性是必要的,但还不够。此函数可能至少应该有3个测试用例,分别是“随机”值0、
len(self.keys\u list)
,以及介于两者之间的某个测试用例,并且可能需要一段时间才能确定哪些种子将在第一次调用时为您提供所需的值。如果修复seed()并使用相同的操作,则randint()的“随机性”会降低是可预测的,就像可重复的一样。至少在同一台机器上,使用相同的pyton版本应该是这样的——但不能保证使用相同种子的不同python版本会为相同的种子提供相同的序列。这就是你想要的吗?只要给随机数生成器添加一个硬编码种子值,它就会从那一点返回相同的序列。调用是随机的。seed(某些值),此函数是…中断重复性是必要的,但还不够。这个函数应该至少有3个测试用例,对于“随机”值0、
len(self.keys\u list)
,以及介于两者之间的一些测试用例,并且可能需要一些时间来确定哪些种子会在第一次调用时为您提供所需的值。您忘记了它是无限的情况loop@hop我不明白?我是在讽刺。当<代码>编号!=0(和
值\u列表
恰好不是空的)函数将永远不会返回。您忘记了它是无限的情况loop@hop我不明白?我是在讽刺。当<代码>编号!=0(和
值\u列表
恰好不是空的)该函数将永远不会返回。