Python 3 unittest: How to extract results of tests?
我正在使用python的(3.4.1)
我使用导入加载所有测试模块文件,然后运行unittest.main():
1 2 3 4 5 6 | import unittest import testing_module1 import testing_module2 # [...] if __name__ == '__main__': unittest.main() |
这对我来说非常有效,因为它很简单,并且尊重我用来控制冗长性或运行哪个测试的命令行参数。
我想继续输出相同的信息,但我想从结果生成一个XML文件。我尝试了xmlrunner(https://github.com/xmlrunner/unittest-xml-reporting/)但是:
- 它不像标准运行程序那样向stdout输出太多信息;
- 它使用的XML的特定格式不适合我。
我希望以我需要的格式生成XML(我不介意手动执行),但对测试运行方式的更改很小。
我有什么选择?
有什么建议吗?
谢谢!
最后我写了两个新的类,继承了
1 | unittest.main(testRunner=xmlrunner.XMLTestRunner(...)) |
我超载了
addSuccess() addError() addFailure() addSubTest()
例如:
1 2 3 | def addSuccess(self, test): super().addSuccess(test) [... store the test into list, dictionary, whatever... ] |
由于这些
1 2 3 4 | def run(self, test): result = super().run(test) self.save_xml_report(result) return result |
注意,这些函数通常在
警告说明:通过使用实际对象传递的
1 | unittest.main(testRunner=xmlrunner.XMLTestRunner) |
然后分析命令行参数。但是您传递一个实例化的对象(如我需要的那样),
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # Similar to what /usr/lib/python3.4/unittest/main.py's TestProgram._getParentArgParser() does. import argparse parser = argparse.ArgumentParser(add_help=False) parser.add_argument('-v', '--verbose', dest='verbosity', action='store_const', const=2, default=1, # Add default=1, not present in _getParentArgParser() help='Verbose output') parser.add_argument('-q', '--quiet', dest='verbosity', action='store_const', const=0, help='Quiet output') parser.add_argument('-f', '--failfast', dest='failfast', action='store_true', help='Stop on first fail or error') parser.add_argument('-c', '--catch', dest='catchbreak', action='store_true', help='Catch ctrl-C and display results so far') parser.add_argument('-b', '--buffer', dest='buffer', action='store_true', help='Buffer stdout and stderr during tests') |
这对你有什么作用?在Stringio中捕获UnitTest的输出,该输出将转到sys.stderr。在unittest.main之后继续,方法是添加"exit=false"。根据需要读取捕获的输出和进程。概念证明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import contextlib import io import sys import unittest class Mytest(unittest.TestCase): def test_true(self): self.assertTrue(True) @contextlib.contextmanager def err_to(file): old_err = sys.stderr sys.stderr = file yield sys.stderr = old_err if __name__ == '__main__': result = io.StringIO() with err_to(result): unittest.main(exit=False) result.seek(0) print(result.read()) |
此打印(到sys.stdout)
1 2 3 4 | ---------------------------------------------------------------------- Ran 1 test in 0.000s OK |
注意:contextlib具有重定向u stdout,但没有重定向u stderr。上面的代码比ContextLib代码简单。上面假设没有UnitTest未捕获的异常。有关添加try:except:finally的信息,请参见contextlib.contextmanager文档。我把这个留给你。