Nosetests test generators – make your bool values more explicit

I had to write a test generator in Python + nostests to drive the same test in two different conditions.

The way I initially wrote the generator initially resembled something like this:

def testChildIsPopulatedCorrectly(self):
    for case in [True, False]:
        yield self.checkChildIsPopulatedCorrectly, case

Although concise, the test as it’s written is not really easy to follow: there is no way to know what the test does without delving into the checkChildIsPopulatedCorrectly method and see which paths case triggers.

A second problem happens when the test runs. The output will be:

testChildIsPopulatedCorrectly(True,) ... ok
testChildIsPopulatedCorrectly(False,) ... ok

Again, it is not very clear what True and False mean in that context.

A solution is to create two simple classes, within the generator[1]:

def testChildIsPopulatedCorrectly(self):
    class WaitForChildren(object):
        def __bool__(self): return True  # [2]
        def __repr__(self): return 'Wait until all the children in the tree are populated'
    class DontWaitForChildren(object):
        def __bool__(self): return False
        def __repr__(self): return 'Do not wait until all the children in the tree are populated'
    for case in [WaitForChildren(), DontWaitForChildren()]:
        yield self.checkChildIsPopulatedCorrectly, case

The next time you run the tests, you’ll get:

testChildIsPopulatedCorrectly(Wait until all the children in the tree are populated,) ... ok
testChildIsPopulatedCorrectly(Do not wait until all the children in the tree are populated,) ... ok

Now both the test generator and the output are clearer.

[1] This is a proof of concept. The complete solution I implemented involves the definition of a more generic class in a different module.

[2] just a heads-up that you should include __nonzero__ = __bool__ if you are using Python 2.x.