user2998754
user2998754

Reputation: 89

Passing arguments to python unittests tests functions

C#'s NUnit has an ability to run the same test several times with different arguments:

[TestCase(12,2,6)]
[TestCase(12,4,3)]
public void DivideTest(int n, int d, int q) {
  Assert.AreEqual( q, n / d ); 
} 

Is it possible to do the same in Python's unittest module?

I can sorta do like

def test_divide(self):
   for n, d, q in [(12, 2, 6), (12, 4, 3)]:
     self.assertEqual(q, n / d)

but it

Upvotes: 0

Views: 144

Answers (1)

Kara
Kara

Reputation: 6226

Python does not have a shortcut syntax for adding tests like this but it is possible to add tests dynamically to the unittest class.

Based on the example you provided you could do this as follows:

import os
import unittest


class TestMath(unittest.TestCase):
    pass


def add_method(cls, method_name, test_method):
    """
    Add a method to a class.
    """
    # pylint warns about re-defining the method name, I do want to re-define
    # the name in this case.
    # pylint: disable=W0622
    test_method.__name__ = method_name
    if not hasattr(cls, test_method.__name__):
        setattr(cls, test_method.__name__, test_method)


def add_divide_test(n, d, q):
    """
    Adds a test method called test_divide_n_by_d to the TestMath class that
    checks the result of the division operation.
    """

    def test_method(self):
        self.assertEqual(q, n / d)

    add_method(
        TestMath, "test_divide_%d_by_%d" % (n, d), test_method
    )

# Adding an entry to this list will generate a new unittest in the TestMath
# class
value_list = [
    [12, 2, 6],
    [12, 4, 3],
]

for values in value_list:
    add_divide_test(values[0], values[1], values[2])

This becomes considerably more useful if you want to generate unit tests based on a list of files in a directory. For example you could have a collection of data files in the test_resources and implement something like this.

for file_name in os.listdir("test_resources"):
    add_test_for_file(file_name)

Once this is setup to add a new unittest you would only need to add a new file in the test_resources directory to add a new test

Upvotes: 1

Related Questions