14.4 将测试输出用日志记录到文件ä¸Â¶
问题¶
ä½ å¸Œæœ›å°†å�•元测试的输出写到到æŸ�个文件ä¸åŽ»ï¼Œè€Œä¸�是打å�°åˆ°æ ‡å‡†è¾“出。
解决方案¶
è¿�行å�•元测试一个常è§�æŠ€æœ¯å°±æ˜¯åœ¨æµ‹è¯•æ–‡ä»¶åº•éƒ¨åŠ å…¥ä¸‹é�¢è¿™æ®µä»£ç �片段:
import unittest
class MyTest(unittest.TestCase):
pass
if __name__ == '__main__':
unittest.main()
è¿™æ ·çš„è¯�测试文件就是å�¯æ‰§è¡Œçš„,并且会将è¿�行测试的结果打å�°åˆ°æ ‡å‡†è¾“出上。
å¦‚æžœä½ æƒ³é‡�定å�‘输出,就需è¦�åƒ�下é�¢è¿™æ ·ä¿®æ”¹ main() 函数:
import sys
def main(out=sys.stderr, verbosity=2):
loader = unittest.TestLoader()
suite = loader.loadTestsFromModule(sys.modules[__name__])
unittest.TextTestRunner(out,verbosity=verbosity).run(suite)
if __name__ == '__main__':
with open('testing.out', 'w') as f:
main(f)
讨论¶
本节感兴趣的部分并ä¸�是将测试结果é‡�定å�‘到一个文件ä¸ï¼Œ
è€Œæ˜¯é€šè¿‡è¿™æ ·å�šå�‘ä½ å±•ç¤ºäº† unittest 模å�—ä¸ä¸€äº›å€¼å¾—关注的内部工作原ç�†ã€‚
unittest 模�首先会组装一个测试套件。
这个测试套件包å�«äº†ä½ 定义的å�„ç§�方法。一旦套件组装完æˆ�,它所包å�«çš„æµ‹è¯•å°±å�¯ä»¥è¢«æ‰§è¡Œäº†ã€‚
è¿™ä¸¤æ¥æ˜¯åˆ†å¼€çš„,unittest.TestLoader 实例被用æ�¥ç»„装测试套件。
loadTestsFromModule() 是它定义的方法之一,用�收集测试用例。
它会为 TestCase 类扫æ��æŸ�个模å�—并将其ä¸çš„æµ‹è¯•方法æ��å�–出æ�¥ã€‚
å¦‚æžœä½ æƒ³è¿›è¡Œç»†ç²’åº¦çš„æŽ§åˆ¶ï¼Œ
å�¯ä»¥ä½¿ç”¨ loadTestsFromTestCase() 方法æ�¥ä»ŽæŸ�个继承TestCaseçš„ç±»ä¸æ��å�–测试方法。
TextTestRunner 类是一个测试è¿�行类的例å�,
这个类的主è¦�用途是执行æŸ�个测试套件ä¸åŒ…å�«çš„æµ‹è¯•方法。
这个类跟执行 unittest.main() 函数所使用的测试è¿�è¡Œå™¨æ˜¯ä¸€æ ·çš„ã€‚
�过,我们在这里对它进行了一些列底层�置,包括输出文件和��级别。
尽管本节例å�代ç �å¾ˆå°‘ï¼Œä½†æ˜¯èƒ½æŒ‡å¯¼ä½ å¦‚ä½•å¯¹ unittest 框架进行更进一æ¥çš„自定义。
è¦�想自定义测试套件的装é…�æ–¹å¼�ï¼Œä½ å�¯ä»¥å¯¹ TestLoader 类执行更多的æ“�作。
为了自定义测试è¿�è¡Œï¼Œä½ å�¯ä»¥æž„é€ ä¸€ä¸ªè‡ªå·±çš„æµ‹è¯•è¿�行类æ�¥æ¨¡æ‹Ÿ TextTestRunner 的功能。
而这些已�超出了本节的范围。unittest 模�的文档对底层实现原�有更深入的讲解,�以去看看。