在Python中使用随机变量进行单元测试

0 投票
5 回答
520 浏览
提问于 2025-04-17 20:59

我正在测试我为一个游戏写的模块。这个模块的功能是掷骰子,并把结果加起来。之后会用这些结果来检查一些事情,比如技能检查等等,所以我想确保它能正常工作。

import random

def roll3d6():
  return random.choice(1, 6) + random.choice(1, 6) + random.choice(1, 6)

def rolld100():
  return random.choice(1, 100)

这是我的测试代码

import Roll

from unittest import TestCase

class test_Roll(TestCase):
  def test_simple(self):
    roll = Roll.roll3d6(), Roll.rolld100()
    self.assertEqual(roll)

这是我测试的结果,我哪里做错了呢?

    PS C:\Users\Ray\Desktop\GitHub\pickett\pickett> python -m unittest discover
    .E.
    ======================================================================
    ERROR: test_simple (test.test_Roll.test_Roll)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "C:\Users\Ray\Desktop\GitHub\pickett\pickett\test\test_Roll.py", line 7, in test_simple
        roll = Roll.roll3d6(), Roll.rolld100()
      File "C:\Users\Ray\Desktop\GitHub\pickett\pickett\Roll.py", line 4, in roll3d6
        return random.choice(1, 6) + random.choice(1, 6) + random.choice(1, 6)
    TypeError: choice() takes exactly 2 arguments (3 given)

    ----------------------------------------------------------------------
    Ran 3 tests in 0.001s

    FAILED (errors=1)
    PS C:\Users\Ray\Desktop\GitHub\pickett\pickett> 

补充:我改用了randint,现在出现了这个类型错误,这也是我之前担心的,不太确定该怎么写代码。

PS C:\Users\Ray\Desktop\GitHub\pickett\pickett> python -m unittest discover
.E.
======================================================================
ERROR: test_simple (test.test_Roll.test_Roll)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\Ray\Desktop\GitHub\pickett\pickett\test\test_Roll.py", line 8, in test_simple
    self.assertEqual(roll)
TypeError: assertEqual() takes at least 3 arguments (2 given)

----------------------------------------------------------------------
Ran 3 tests in 0.000s

FAILED (errors=1)
PS C:\Users\Ray\Desktop\GitHub\pickett\pickett>

5 个回答

0

random.choice() 这个函数需要你传入一个集合,所以下面这个写法是可以用的:

random.choice([1,2,3,4,5,6]);

如果选择的选项有100个,这样做就会很麻烦,所以我建议你用下面这个方法:

random.randint(a, b)

返回一个随机整数N,使得 a <= N <= b。

0

根据错误提示,choice() 这个函数需要两个参数(这里的 (3 given) 意思是实际上传入了三个参数,其中一个可能是 self,这是隐式传入的)。

实际上,choice() 只需要一个参数,这个参数必须是一个序列(比如列表、元组等)。

你真正想用的是 random.randint,而不是 random.choice

0

使用 random.randint(1, 6) 可以生成一个随机数,这个随机数的范围是从1到6,包括1和6本身。

0

恭喜你,你的测试成功了,并且发现了一个错误!

这个错误是你在使用 random.choice 时给了两个参数,但它其实只需要一个参数,也就是一个序列(通常是一个列表)。

你可能是想用 random.randint(1, 6) 来代替它。

1

你在使用 random.choice() 的时候搞错了;它需要一个 序列 来选择。你可以用 random.choice(range(1, 7)),不过这样效率不是很好。

如果你想要一个1到6之间的随机数(包括1和6),可以使用 `random.randint()`:

random.randint(1, 6)

测试 random 模块的功能一方面不在你单元测试的范围内,另一方面也比较困难,因为这个模块总是产生随机结果。

你应该模拟(mock) random 模块提供的函数,然后测试这些模拟函数是否按照你理解的方式被正确调用。可以参考一下这个链接:如何为掷骰子的用例编写好的单元测试?

撰写回答