0

Hi I am new to unit tests and was wondering how I would test a function that has a random component in it?

I have the following python code:

class Questions(object):

def __init__(self):

    self.questions = {}

place_value = {
    0: "Thousands",
    1: "Hundreads",
    2: "Tens",
    3: "Units/ones",
}

def place_value(self, question, number):

    selection = randint(0, 3)

    number = ''.join(map(str, number))
    value = number[selection]

    question_text = question.format(value, number)

    li = generate_a_list(question_text)

    self.questions['question1'] = li

test code

def test_place_value():

    obj = math_q.Questions()
    obj.place_value("value of {0} in {1}", [1,2,3,4])

    assert_equal(obj.questions["question1"], ["value of {0} in 1234"])

The problem being I don't know which value 1-4 is selected from the 'value = number[selection]' code above.

What can be done about this? Thanks.

user1831677
  • 201
  • 1
  • 4
  • 13

1 Answers1

0

Assuming your code is in path/my_file.py you can use mock module like this:

@mock.patch('path.my_file.randint', return_value=0)
def test_place_value(m_randint):
    obj = math_q.Questions()
    obj.place_value("value of {0} in {1}", [1,2,3,4])

    m_randint.assert_called_once_with(0, 3)
    assert obj.questions["question1"] == ...

Then just write 4 tests to handle all cases.

Side note: I strongly suggest switching to pytest.

freakish
  • 54,167
  • 9
  • 132
  • 169
  • Thanks for the reply. What do you mean by four test to handle all cases? What would the code look like for these tests? – user1831677 Jul 21 '15 at 11:14
  • Just 4 test functions where you change `return_value` of the mock to `0, 1, 2, 3`. – freakish Jul 21 '15 at 11:15
  • Great got it to work, but a quick question. What if I had to select from a range of 100. Would I have to write 100 separate functions just to test that one function? Surely there must be an easier way. – user1831677 Jul 22 '15 at 09:13
  • @user1831677 Sure, you have to dynamically generate test functions. Have a look at this: http://stackoverflow.com/questions/32899/how-to-generate-dynamic-parametrized-unit-tests-in-python Also note that this is super easy with pytest, you only decorate your test with `@pytest.mark.parametrize`. Nosetest seems to support something similar via `test_generator` (have a look at responds in the mentioned thread). – freakish Jul 22 '15 at 10:00
  • Thanks for the help, I will look at the post. – user1831677 Jul 22 '15 at 10:11