Test generators are an amazing tool when you are testing small variations in the same code path. It uses generators[fn:0] which yield callables[fn:1] that are called as the test suite runs. For example, imagine you’re testing a rounding library.

class TestRound(object):
  def _check_rounding(self, test, expected):
    assert round(test) == expected

  def test_rounding(self):
    for x, y in [(1, 1),
                 (1.9, 2)]:
      yield self._check_rounding, x, y

# VERSUS

class TestRound(unittest.TestCase):
  def test_rounding_same(self):
    self.assertEquals(round(1), 1)

  def test_rounding_one_dot_nine_to_two(self):
    self.assertEquals(round(1.9), 2)

While these two examples look mostly similar for 2 cases, imagine what ten cases would look like, or 50. For a much more real-world example, imagine a test generator which will crawl your webapp’s url routing setup and assert that each of them return a 200 status code.

There is support for test generators in both nose and unittest2. I’ve outlined examples of both in a small git repository on github.

[fn:0] Generators are iterables (aka pseudo-lists) that are generated on the fly instead of all up front. wiki

[fn:1] Callables are things that you can call. In Python, this is functions and classes which define a “call” method. stack overflow