title: unittest and metaclass: automatic test_* method generation
body: <p>As I create tests for a framework, I start noticing the following pattern:</p>
  
  <pre><code>class SomeTestCase(unittest.TestCase):
  
      def test_feat_true(self):
          _test_feat(self, True)
  
      def test_feat_false(self):
          _test_feat(self, False)
  
      def _test_feat(self, arg):
          pass    # test logic goes here
  </code></pre>
  
  <p>So I want to programmatically create <code>test_feat_*</code> methods for these type of test classes with a metaclass. In other words, for each private method with signature <code>_test_{featname}(self, arg)</code>, I want two top-level, discoverable methods with the signatures <code>test_{featname}_true(self)</code> and <code>test_{featname}_false(self)</code> to be created.</p>
  
  <p>I came up with something like:</p>
  
  <pre><code>#!/usr/bin/env python
  
  import unittest
  
  
  class TestMaker(type):
  
      def __new__(cls, name, bases, attrs):
          callables = dict([
              (meth_name, meth) for (meth_name, meth) in attrs.items() if
              meth_name.startswith('_test')
          ])
  
          for meth_name, meth in callables.items():
              assert callable(meth)
              _, _, testname = meth_name.partition('_test')
  
              # inject methods: test{testname}_{[false,true]}(self)
              for suffix, arg in (('false', False), ('true', True)):
                  testable_name = 'test{0}{1}'.format(testname, suffix)
                  attrs[testable_name] = lambda self: meth(self, arg)
  
          return type.__new__(cls, name, bases, attrs)
  
  
  class TestCase(unittest.TestCase):
  
      __metaclass__ = TestMaker
  
      def _test_this(self, arg):
          print 'this: ' + str(arg)
  
      def _test_that(self, arg):
          print 'that: ' + str(arg)
  
  
  if __name__ == '__main__':
      unittest.main()
  </code></pre>
  
  <p>I expect some output like:</p>
  
  <pre><code>this: False
  this: True
  that: False
  that: True
  </code></pre>
  
  <p>But what I got is:</p>
  
  <pre><code>$ ./test_meta.py
  that: True
  .that: True
  .that: True
  .that: True
  .
  ----------------------------------------------------------------------
  Ran 4 tests in 0.000s
  
  OK
  </code></pre>
  
  <p>It looks like there are some closure rules that I am missing. How do I get around this? Is there a better approach?</p>
  
  <p>Thanks,</p>
  
  <p><em>edit</em>: Fixed. See: <a href="https://gist.github.com/852268/e8430a8322c25c39fbd5cd18b84d21d2b26b9be8" rel="nofollow">the snippet</a>.</p>