0

mymoduleすべての関数に独自のTestCaseインスタンスがあることを確認する単体テストを作成しようとしています。
定型コードと手作業を減らすために、イントロスペクション/リフレクションを使用して、lambda関数をクラス メソッドとして最初は空の classに動的に追加したいと考えましたTest_TestCases
次のコードの種類は機能します-実際にラムダをクラスメソッドとして追加し、それらをunittest.main()見つけて正しく呼び出します。

import unittest
from unittest import TestCase

import mymodule

class Test_TestCases(TestCase):
"""Class whose test_* methods will be created during runtime."""
    pass

################################################################################

if __name__ == "__main__":
    for item in dir(mymodule):
        attr = getattr(pws, item)
        if callable(attr):
            testname = "Test_%s" % item
            setattr(Test_TestCases, "test_%s_is_tested" % item,
                    lambda self: self.assertTrue(testname in globals()) and
                    issubclass(getattr(globals(), testname), TestCase))
    unittest.main()

問題は、単体テスト モジュールにテストされていない関数があるにもかかわらず、すべてのテストが成功することです。
少し試してみたところ、変数が呼び出されるtestnameたびに同じ値を持つことがわかりました。 再現性を確保するために、このコードの一部に問題を最小限に抑えることができました。lambda

lambdas = []
for i in range(5):
    lambdas.append(lambda: str(i))
print ", ".join(f() for f in lambdas)

私はこの出力を期待します:

0, 1, 2, 3, 4

しかし、代わりに私は得る:

4, 4, 4, 4, 4

ラムダが遅延して初期化されているようです。
誰かがこの動作を説明したり、目標を適切に達成する方法についてヒントを教えてくれませんか?

前もって感謝します

4

1 に答える 1