lerugray
lerugray

Reputation: 369

unittesting with random variables in python

I am trying to test this Module I wrote for a game. The module is supposed to roll dice, and add the result. later they are checked for things like skill check and such, so I wanted to make sure that it is working correctly.

import random

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

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

Here is my test

import Roll

from unittest import TestCase

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

And here was my testing results, what am I doing wrong?

    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> 

Edit: So I changed to randint, and now I get this type error, which i was worried about originally, not sure how to syntax this out.

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>

Upvotes: 0

Views: 532

Answers (5)

Brian English
Brian English

Reputation: 466

random.choice() expects a SET to be passed in, so the following would work instead:

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

This would be prohibitive with 100 choices, so I recommend using the following instead:

random.randint(a, b)

Return a random integer N such that a <= N <= b.

Upvotes: 0

heavenslife
heavenslife

Reputation: 71

Use random.randint(1, 6) to get random numbers between 1 and 6 inclusive.

Upvotes: 0

Martijn Pieters
Martijn Pieters

Reputation: 1122122

You are using random.choice() wrong; it expects a sequence to pick from. You could use random.choice(range(1, 7)), albeit that that's not very efficient.

To get a random number between 1 and 6 (inclusive), use `random.randint():

random.randint(1, 6)

Testing the functionality of the random module is a) outside of the scope of your unittest, and b) rather hard, as the module always produces random results.

You'd instead stub out (mock) the functions the random module provides and test if those stubs were called correctly, according to your understanding of how they should be called. See What are good unit tests to cover the use case of rolling a die?.

Upvotes: 1

Valentin Lorentz
Valentin Lorentz

Reputation: 9753

As the error says, choice() takes exactly 2 arguments (the (3 given) means that there is a third argument passed implicitely to choice (probably self)).

Indeed, choice() only takes one argument, which has to be aa sequence (list, tuple, …).

What you want is actually random.randint and not random.choice.

Upvotes: 0

RemcoGerlich
RemcoGerlich

Reputation: 31260

Congratulations, your tests worked, and they have found a bug!

The bug is that you're calling random.choice with 2 arguments, while it takes only one, a sequence (usually a list).

You probably meant to use random.randint(1, 6) instead.

Upvotes: 0

Related Questions