How to test random.choice in Python?

Question:

How would you test a function which could lead to a random choice?

For instance:

from random import shuffle

def getMaxIndices(lst):
    '''
    :lst: list of int

    Return indices of max value. If max value appears more than once,
    we chose one of its indices randomly.
    '''
    index_lst = [(i, j) for i, j in enumerate(lst)]
    shuffle(index_lst)
    index_lst.sort(key=lambda x: x[1])
    max_index = index_lst.pop()[0]
    return max_index

How would you test it?

Asked By: Gaut

||

Answers:

If you want to test it, you can write something like:

lst = [1,2,3,4,5,5]
assert getMaxIndices(lst) in (4,5)

testing that the result is either 4 or 5.

If you want to test that it can be both and is random, run it 1000 times and test that you get 4 and 5 about the same amount of times:

result = 0
for i in range(1000):
    result += getMaxIndices(lst)
assert 4.3 <= result/1000 <= 4.7
Answered By: Jesse Bakker

Since you are not testing the shuffling itself, you should patch shuffle to return an output set by you in order to have a deterministic test.

In this case it could be something along the lines of:

@patch('random.shuffle', lambda x: x)
def test_get_max_Indices():
    max_index = getMaxIndices([4,5,6,7,8])
    assert max_index == 4

From the test, you can realise that the return value will simply be dependent on the length of the input list.

You can read more about patch in the docs: https://docs.python.org/dev/library/unittest.mock.html#unittest.mock.patch

Answered By: Enrique Saez

Answering this many years later, but I would have some tests for edges cases like an empty list

import pytest
def test_get_max_empty_list():
    with pytest.raises(Exception):
        getMaxIndices([])

I would also test I got the largest, regardless of what the shuffle does:

def test_get_max_is_largest_for_two_identical_items():
    L = [2,2]
    max_index = getMaxIndices(L)
    assert L[max_index] == max(L)

def test_get_max_is_largest():
    L = [2,3,4,5,6]
    max_index = getMaxIndices(L)
    assert L[max_index] == max(L)

Mocking out the shuffle is fine, and does let you test specifics too, but doesn’t cover the empty edge case.

Answered By: doctorlove
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.