2015-05-26 51 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;这将在每个测试执行时打印您的文档字符串。这是否足够的信息?