フレームワークのテストを作成すると、次のパターンに気付き始めます。
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
test_feat_*
そのため、メタクラスを使用して、これらのタイプのテストクラスのメソッドをプログラムで作成したいと思います。つまり、署名付きのプライベートメソッドごとに、署名付き_test_{featname}(self, arg)
の2つのトップレベルの検出可能なメソッドとtest_{featname}_true(self)
をtest_{featname}_false(self)
作成する必要があります。
私は次のようなものを思いついた:
#!/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()
私は次のような出力を期待しています:
this: False
this: True
that: False
that: True
しかし、私が得たのは:
$ ./test_meta.py
that: True
.that: True
.that: True
.that: True
.
----------------------------------------------------------------------
Ran 4 tests in 0.000s
OK
私が見逃しているいくつかの閉鎖規則があるようです。これを回避するにはどうすればよいですか?より良いアプローチはありますか?
ありがとう、
編集:修正されました。スニペットを参照してください。