2012-12-26 89 views
0

我試圖創建一個單元測試,它檢查mymodule中的每個函數都有它自己的TestCase實例。
爲了減少樣板代碼和人工操作,我想用introspection/reflection動態地將lambda函數作爲類方法添加到初始空類Test_TestCases
以下代碼類型的作品 - 確實將lambda作爲類方法添加,並且unittest.main()找到並正確調用它們。Python內省:在運行時定義動態類方法

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 

似乎懶洋洋地初始化了lambda。
任何人都可以請解釋這種行爲或給我一個關於如何正確完成我的目標的提示?

預先感謝

+0

可能重複http://stackoverflow.com/questions/2731111/python-lambdas和變量綁定) – interjay

+1

[Python嵌套函數中的局部變量]的可能的重複(http://stackoverflow.com/questions/12423614/local-variables-in-python-nested-functions) –

+0

這在相同方向和解決我的再現,但我最初的問題是別的。 提供一個默認值不會也不能解決我的問題,因爲它不是傳遞給lambda函數的參數總是保持不變,但它是'testname',一個不作爲參數傳遞的簡單變量 – Chris

回答

1

暗影testname與另一包裝函數:

def assertion(testname=testname): 
    def function(self): 
     return self.assertTrue(testname in globals()) and issubclass(getattr(globals(), testname), TestCase)) 

    return function 

setattr(Test_TestCases, "test_%s_is_tested" % item, assertion()) 
[Python的lambdas和變量綁定(的
+0

作品,非常感謝! – Chris