Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have Django unit tests that are pretty much the following format:

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))

A function that returns a lambda that is bound as a method via setattr, which is an eyesore and as unreadable as you can get in Python without really trying to obfuscate.

How can I achieve the same functionality in a more readable way, preferably without lambda?

For reference, see the original SO question about the subject.

share|improve this question

2 Answers 2

Don't bother with generating tests:

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

    def test_thingies(self):
        for i in xrange(1, 4):
            for j in xrange(2, 6):
                self.check(i,j)

It would be nicer to generate individual tests, but do you really get that much benefit out of it?

Or write a reusable function:

data = [(i,j) for i in xrange(1,4) for j in xrange(2,6)]
add_data_tests(TestClass, data, 'check')
share|improve this answer
    
Generating tests is pretty much a must - as there will be a few things that will be checked for hundreds of items so a single "ok" / "failed" for the 1k+ individual asserts does not give enough resolution. –  Kimvais Apr 27 '12 at 20:08
    
So even though I'm using unittest I'm actually doing this to do regression testing :) –  Kimvais Apr 27 '12 at 20:11
2  
@Kimvais, you don't need separate tests to get that resolution. (Albeit, that's the nicest way. Some unit testing frameworks like nose make it easy.) Just catch the exception when it fails, and add some information on the parameters being tested. –  Winston Ewert Apr 27 '12 at 20:55

Both nose and py.test support mechanisms to run parameterized tests. Either of these options will likely produce a better result than trying to spin your own implementation.

The issue with the big nested loop to call check method, is that it stops on the first failure. That single failure might tell you want is broken. But knowing the 5 of the 20 input sets cause the failure will give you a much better idea of what the core issue is.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.