2015-05-26 81 views
0

給出一個測試套件,文本文件:解析單元測試斷言使用抽象語法樹

class MyTestSuite(unittest.TestCase): 

    def test_foo(self): 
     self.assertLessEqual(temperature, boiling, "boiling will burn the cake") 
     self.assertEqual(colour, 'golden brown', "the cake should be cooked until golden brown") 

    def test_bar(self): 
     self.assertIn('flour', ['flour', 'eggs'], "the flour should be mixed in with the eggs") 

我想產生描述所有的斷言和測試的文本文件。例如:

My Test Suite 

Test foo: 

* temperature <= boiling because boiling will burn the cake 
* colour == 'golden brown' because the cake should be cooked until golden brown 

Test bar: 

* 'flour' in ['flour', 'eggs'] because the flour should be mixed in with the eggs 

更新

使用inspect我設法得到一個模塊中的所有測試方法可迭代列表:

def __init__(self, module='__main__'): 
    if isinstance(module, basestring): 
     self.module = __import__(module) 
     for part in module.split('.')[1:]: 
      self.module = getattr(self.module, part) 
    else: 
     self.module = module 

    self.tests = {} 

    for name, obj in inspect.getmembers(self.module): 
     if inspect.isclass(obj): 
      for method_name in dir(obj): 
       method = callable(getattr(obj, method_name)) 
       if method and re.match('test.*', method_name): 
        spec = ' '.join(re.findall('[A-Za-z][^A-Z_]*(?=_[A-Z])?|[A-Z][^A-Z_]*', obj.__name__)).title() 
        test = ' '.join(re.findall('[A-Za-z][^A-Z_]*(?=_[A-Z])?|[A-Z][^A-Z_]*', method_name)).capitalize() 

        assertions = # a list of strings describing the assertions 

        try: 
         self.tests[spec][test] = assertions 
        except KeyError: 
         self.tests[spec] = {test: assertions} 

的最後一步是提取描述測試方法斷言的字符串列表。我的第一個解決方案是使用與inspect.getsourcelines(method)結合使用正則表達式的負載,但必須有更少的依賴於語法的解決方案。感謝凱文建議ast作爲一個可行的選擇,但這帶來了一個更具體的問題。

如何使用ast將測試方法中的斷言解析爲人類可讀的格式?

失敗這可能有更好的選擇嗎?

+2

你有試過在你的單元測試中揮動[ast魔杖](https://docs.python.org/3/library/ast.html#ast.parse)嗎? – Kevin

回答

0

爲TestSuite的基類的文檔字符串說:

在使用時,創建一個TestSuite實例,再加入測試用例 實例。當所有測試都添加完畢後,該套件可以傳遞給 測試運行者,如TextTestRunner。它將按照添加它們的順序運行個別測試 ,並彙總結果。 子類化時,不要忘記調用基類構造函數。

如果您選擇使用TextTestRunner,那麼你可以提供一個流爲它寫:

tester = unittest.TextTestRunner(stream=mystream, verbosity=2) 
test = unittest.makeSuite(MyTestSuite) 
tester.run(test) 

編輯補充冗長= 2;這將在每個測試執行時打印您的文檔字符串。這是否足夠的信息?