Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python's unittest and dynamic creation of test cases [duplicate]

Possible Duplicate:
How do you generate dynamic (parameterized) unit tests in Python?

Is there a way to dynamically create unittest test cases? I have tried the following...

class test_filenames(unittest.TestCase):

    def setUp(self):
        for category, testcases in files.items():
            for testindex, curtest in enumerate(testcases):
                def thetest():
                    parser = FileParser(curtest['input'])
                    theep = parser.parse()
                    self.assertEquals(theep.episodenumber, curtest['episodenumber'])

                setattr(self, 'test_%s_%02d' % (category, testindex), thetest)

..which creates all the methods correctly (they show up in dir() and are callable), but unittest's test detector, nor nosetest executes them ("Ran 0 tests in ...")

Since I may be asking the wrong question - what I am trying to achieve:

I have a file containing test data, a list of input filenames, and expected data (simplified to episodenumber in the above code), stored in a Python dictionary. The key is the category, the value is a list of test cases, for example...

test_cases = {}
test_cases['example_1'] = [
    {'input': 'test.01',
    'episodenumber': 1},
    {'input': 'test.02',
    'episodenumber': 2}
]

test_cases['example_2'] = [
    {'input': 'another.123',
    'episodenumber': 123},
    {'input': 'test.e42',
    'episodenumber': 32}
]

Currently I just loop over all the data, call self.assertEquals on each test. The problem is, if one fails, I don't see the rest of the failures as they are also grouped into one test, which aborts when an assertion fails.

The way around this, I thought, would be to (dynamically) create a function for each test case, perhaps there is a better way?

like image 456
dbr Avatar asked Jul 28 '09 12:07

dbr


People also ask

How do you run multiple test cases in Python?

If they have not provided their environment to run test cases in a loop. And locally if You are running code for python compiler It would be useful. you can simply use a while loop or range function of python.

Which is better Pytest or unittest?

Which is better – pytest or unittest? Although both the frameworks are great for performing testing in python, pytest is easier to work with. The code in pytest is simple, compact, and efficient. For unittest, we will have to import modules, create a class and define the testing functions within that class.


2 Answers

In the following solution, the class Tests contains the helper method check and no test cases statically defined. Then, to dynamically add a test cases, I use setattr to define functions in the class. In the following example, I generate test cases test_<i>_<j> with i and j spanning [1,3] and [2,5] respectively, which use the helper method check with different values of i and j.

class Tests(unittest.TestCase):
    def check(self, i, j):
        self.assertNotEquals(0, i-j)



for i in xrange(1, 4):
    for j in xrange(2, 6):
        def ch(i, j):
            return lambda self: self.check(i, j)
        setattr(Tests, "test_%r_%r" % (i, j), ch(i, j))
like image 65
Adrian Panasiuk Avatar answered Oct 12 '22 09:10

Adrian Panasiuk


For this you should use test generators in nose. All you need to do is yield a tuple, with the first being a function and the rest being the args. From the docs here is the example.

def test_evens():
    for i in range(0, 5):
        yield check_even, i, i*3

def check_even(n, nn):
    assert n % 2 == 0 or nn % 2 == 0
like image 25
David Raznick Avatar answered Oct 12 '22 09:10

David Raznick