Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I unit test random shuffle operations in Python?

I have written code to create a Secret Santa list from a .csv file with groups of names and corresponding emails.

import random
import pandas as pd

def compare(list_of_names, list_of_emails):
    zipped_lists = list(zip(list_of_emails, list_of_names))
    random.shuffle(zipped_lists)  # shuffle list of emails and names
    result = []
    shuffled_emails = [i[0] for i in zipped_lists]
    for i, _ in enumerate(shuffled_emails):
        result.append(zipped_lists[i-1][1])  # shift email relatively one position to the right
    return list(zip(result, shuffled_emails))

def main():
    names  = ["John", "Bob", "Alice"]
    emails = ["[email protected]", "[email protected]", "[email protected]"]

    print(compare(names,emails))

if __name__ == '__main__':
    main()

How can I unit test this code, since I am using random shuffle operations? I am not sure how I could write a test case for the same.

like image 775
nerdyGuy Avatar asked Nov 07 '22 02:11

nerdyGuy


1 Answers

A common approach would be to seed the random number generator in the test, generate a dataset and verify it by hand. The test will then serve as a regression test to ensure that the implementation did not change. If the implementation does change, you will be forced to regenerate the dataset and manually re-verify.

For example:

def test_compare():
    seed = 0xBEEF
    names = ['Alice', 'Bob', 'Cuthbert', 'Daisy', 'Ethelred']
    emails = [f'{n}@company.com' for n in names]

    expected = [('Alice', '[email protected]'), ('Cuthbert', '[email protected]'), ('Bob', '[email protected]'), ('Daisy', '[email protected]'), ('Ethelred', '[email protected]')]

    random.seed(seed)

    #k = list(zip(emails, names))
    #random.shuffle(k)
    #print(k)

    assert compare(names, emails) == expected

test_compare()

The first time I ran the test, I ran the commented out lines instead of the assertion, and manually constructed the list expected. After that, the assertion should pass until you change the seed or the implementation of compare.

In a broader sense, you are trying to assert something deterministic about the function you are testing. Random seeds exist exactly to make this possible. Since you are not testing the properties of random.shuffle, using a bunch of hard-coded quantities is perfectly fine.

like image 83
Mad Physicist Avatar answered Nov 15 '22 09:11

Mad Physicist