私は定期的に、Pythonで許可されているダイナミシティの一部を少し悪用しようとしていることに気付きます(ここではpython3を使用していますが、多くの違いはないはずです)。
unittest.TestCase
この場合、実行時に作成されたいくつかのメソッドに、私の1つのtest_メソッドを分割したいと思いました。
(これはローマ数字についてのカタでしたが、実際にはTDDではありませんでした。後でテストを作成しました)
これはテストです:
class TestNumbers(TestCase):
def test_number(self):
for i in range(3000):
self.assertEqual(i, roman_to_int(int_to_roman(i)))
これは私がそれを書き込もうとした方法です:
from functools import partial
from types import MethodType
class TestNumbers(TestCase):
pass
def test_number(self, n):
self.assertEqual(n, roman_to_int(int_to_roman(n)))
for i in range(3000):
name = str(i)
test_method = MethodType(partial(test_number, n=i), TestNumbers)
setattr(TestNumbers, "test" + name, test_method)
(あるいは、私は多くのTestCaseサブクラスとsetattr(globals(), ...)
それらを動的に作成しようとしました)
私は知っています:これは実際にはあまり目的がなく、おそらく遅いなどです。しかし、これは単なるPOCであり、どのように機能させることができるかを理解しようとしています。
MethodTypeを使用すると、テストはバインドされたメソッドになりますが、内部では、assertEqualは明らかに関数になり、それを呼び出そうとすると失敗します。TypeError: assertEqual() takes at least 3 arguments (2 given)
test_numberをに変更しようとしました
def test_number(self, n):
self.assertEqual(self, n, roman_to_int(int_to_roman(n)))
しかし、これは隠されたTestCaseメソッドで同じ問題をより深く発掘するだけです:TypeError: _getAssertEqualityFunc() takes exactly 3 arguments (2 given)
ここでstackoverflowを調べて、同様の質問(Python:バインドされていないメソッドをバインドしますか?)を見つけましたが、それらのいずれも、その内部でターゲットクラスの他のバインドされたメソッドを呼び出すメソッドのバインドを扱っていません
メタクラス(http://docs.python.org/py3k/reference/datamodel.html#customizing-class-creation)も調べようとしましたが、私がやろうとしていることと一致していないようです。