我最终编写了两个新类,它们继承自unittest.TextTestResult和unittest.TextTestRunner。这样一来,我可以运行主要那样:
unittest.main(testRunner=xmlrunner.XMLTestRunner(...))
我重载unittest.TextTestRunner的__init__和来自unittest.TextTestResult:
addSuccess()
addError()
addFailure()
addSubTest()
例如:
def addSuccess(self, test):
super().addSuccess(test)
[... store the test into list, dictionary, whatever... ]
由于这些add*()函数被调用的实际测试中,我可以将它们存储在一个全局列表,并在我的XMLTestRunner.run()结束它们解析:
def run(self, test):
result = super().run(test)
self.save_xml_report(result)
return result
请注意,这些功能通常在/usr/lib/python3.4/unittest/runner.py中定义。
警告注意:通过使用一个实际的对象传递unittest.main()的testRunner参数如图所示,推出蟒蛇时给出的命令行参数被忽略。例如,使用-v参数增加详细级别将被忽略。这是因为在/usr/lib/python3.4/unittest/main.py中定义的TestProgram类会检测unittest.main()是否以testRunner作为类或对象运行(请参阅文件末尾附近的runTests())。如果你只给出这样一个类:
unittest.main(testRunner=xmlrunner.XMLTestRunner)
然后命令行参数被解析。但是你传递一个实例化的对象(就像我需要的那样),runTests()就会按原样使用它。因此我不得不在自己的解析参数XMLTestRunner.__init__():
# 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')