unittest 源代码分析(二)--main.py代码分析
2017-04-04 19:39
645 查看
1 介绍
main.py是unittest主文件。
2 main.py调用过程
TestProgram.__init__() ==> TestProgram.parseArgs() ==> TestProgram.createTests() ==> TestProgram.runTests()
__init__() 初始化调用parseArgs()和runTests()
parseArgs()解析输入参数
createTests()创建测试用例集合
runTests()执行测试用例
3 代码和注释
main.py是unittest主文件。
2 main.py调用过程
TestProgram.__init__() ==> TestProgram.parseArgs() ==> TestProgram.createTests() ==> TestProgram.runTests()
__init__() 初始化调用parseArgs()和runTests()
parseArgs()解析输入参数
createTests()创建测试用例集合
runTests()执行测试用例
3 代码和注释
"""Unittest main program""" import sys import os import types from . import loader, runner from .signals import installHandler __unittest = True #-h 输出帮助信息 FAILFAST = " -f, --failfast Stop on first failure\n" CATCHBREAK = " -c, --catch Catch control-C and display results\n" BUFFEROUTPUT = " -b, --buffer Buffer stdout and stderr during test runs\n" # -f 用例遇到失败后停止,不在执行后面的用例 # -c ctrl-c 中断后执行完输出测试结果 USAGE_AS_MAIN = """\ Usage: %(progName)s [options] [tests] Options: -h, --help Show this message -v, --verbose Verbose output -q, --quiet Minimal output %(failfast)s%(catchbreak)s%(buffer)s Examples: %(progName)s test_module - run tests from test_module %(progName)s module.TestClass - run tests from module.TestClass %(progName)s module.Class.test_method - run specified test method [tests] can be a list of any number of test modules, classes and test methods. Alternative Usage: %(progName)s discover [options] Options: -v, --verbose Verbose output %(failfast)s%(catchbreak)s%(buffer)s -s directory Directory to start discovery ('.' default) -p pattern Pattern to match test files ('test*.py' default) -t directory Top level directory of project (default to start directory) For test discovery all test modules must be importable from the top level directory of the project. """ USAGE_FROM_MODULE = """\ Usage: %(progName)s [options] [test] [...] Options: -h, --help Show this message -v, --verbose Verbose output -q, --quiet Minimal output %(failfast)s%(catchbreak)s%(buffer)s Examples: %(progName)s - run default set of tests %(progName)s MyTestSuite - run suite 'MyTestSuite' %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething %(progName)s MyTestCase - run all 'test*' test methods in MyTestCase """ #TestProgram是unittest主类调用其他类完成测试 class TestProgram(object): USAGE = USAGE_FROM_MODULE #帮助信息 # defaults for testing failfast = catchbreak = buffer = progName = None def __init__(self, module='__main__', defaultTest=None, argv=None, testRunner=None, testLoader=loader.defaultTestLoader, exit=True, verbosity=1, failfast=None, catchbreak=None, buffer=None): if isinstance(module, basestring): #basestring是str和unicode的超类(父类),也是抽象类,因此不能被调用和实例化,但可以被用来判断一个对象是否为str或者unicode的实例 self.module = __import__(module) #动态加载测试用例文件 for part in module.split('.')[1:]: self.module = getattr(self.module, part) else: self.module = module if argv is None: argv = sys.argv #获取运行case的参数 self.exit = exit self.failfast = failfast self.catchbreak = catchbreak self.verbosity = verbosity self.buffer = buffer self.defaultTest = defaultTest self.testRunner = testRunner #参数初始化 self.testLoader = testLoader #初始化创建测试用例集的类 self.progName = os.path.basename(argv[0]) #调用测试用例文件赋值到self.progName self.parseArgs(argv) #参数解析函数 self.runTests() #测试用例运行函数 #输出帮助信息函数 def usageExit(self, msg=None): if msg: print msg usage = {'progName': self.progName, 'catchbreak': '', 'failfast': '', 'buffer': ''} if self.failfast != False: usage['failfast'] = FAILFAST if self.catchbreak != False: usage['catchbreak'] = CATCHBREAK if self.buffer != False: usage['buffer'] = BUFFEROUTPUT print self.USAGE % usage sys.exit(2) #解析输入参数并生成测试用例 def parseArgs(self, argv): #调用discover参数加载目录里文件,并生成测试用例集 if len(argv) > 1 and argv[1].lower() == 'discover': self._do_discovery(argv[2:]) return import getopt long_opts = ['help', 'verbose', 'quiet', 'failfast', 'catch', 'buffer'] try: options, args = getopt.getopt(argv[1:], 'hHvqfcb', long_opts) for opt, value in options: if opt in ('-h','-H','--help'): self.usageExit() if opt in ('-q','--quiet'): self.verbosity = 0 if opt in ('-v','--verbose'): self.verbosity = 2 if opt in ('-f','--failfast'): if self.failfast is None: self.failfast = True # Should this raise an exception if -f is not valid? if opt in ('-c','--catch'): if self.catchbreak is None: self.catchbreak = True # Should this raise an exception if -c is not valid? if opt in ('-b','--buffer'): if self.buffer is None: self.buffer = True # Should this raise an exception if -b is not valid? if len(args) == 0 and self.defaultTest is None: # 没有指定测试用例 self.testNames = None elif len(args) > 0: # 指定测试用例 self.testNames = args if __name__ == '__main__': # to support python -m unittest ... self.module = None else: self.testNames = (self.defaultTest,) self.createTests() #创建测试用例集合 except getopt.error, msg: self.usageExit(msg) #创建测试用例集合函数 def createTests(self): if self.testNames is None: # 没有指定测试用例加载整个文件做测试集合 self.test = self.testLoader.loadTestsFromModule(self.module) else: # 指定使用的测试用例,加载当个测试用例 self.test = self.testLoader.loadTestsFromNames(self.testNames, self.module) #将指定目录的文件加载成测试用例集 def _do_discovery(self, argv, Loader=None): if Loader is None: Loader = lambda: self.testLoader # handle command line args for test discovery self.progName = '%s discover' % self.progName import optparse parser = optparse.OptionParser() parser.prog = self.progName parser.add_option('-v', '--verbose', dest='verbose', default=False, help='Verbose output', action='store_true') if self.failfast != False: parser.add_option('-f', '--failfast', dest='failfast', default=False, help='Stop on first fail or error', action='store_true') if self.catchbreak != False: parser.add_option('-c', '--catch', dest='catchbreak', default=False, help='Catch ctrl-C and display results so far', action='store_true') if self.buffer != False: parser.add_option('-b', '--buffer', dest='buffer', default=False, help='Buffer stdout and stderr during tests', action='store_true') parser.add_option('-s', '--start-directory', dest='start', default='.', help="Directory to start discovery ('.' default)") parser.add_option('-p', '--pattern', dest='pattern', default='test*.py', help="Pattern to match tests ('test*.py' default)") parser.add_option('-t', '--top-level-directory' 4000 , dest='top', default=None, help='Top level directory of project (defaults to start directory)') options, args = parser.parse_args(argv) if len(args) > 3: self.usageExit() for name, value in zip(('start', 'pattern', 'top'), args): setattr(options, name, value) # only set options from the parsing here # if they weren't set explicitly in the constructor if self.failfast is None: self.failfast = options.failfast if self.catchbreak is None: self.catchbreak = options.catchbreak if self.buffer is None: self.buffer = options.buffer if options.verbose: self.verbosity = 2 start_dir = options.start pattern = options.pattern top_level_dir = options.top loader = Loader() #根据开始目录,匹配格式,顶层目录生成测试用例 self.test = loader.discover(start_dir, pattern, top_level_dir) #执行测试用例 def runTests(self): if self.catchbreak: #注册捕捉信号函数 installHandler() if self.testRunner is None: self.testRunner = runner.TextTestRunner if isinstance(self.testRunner, (type, types.ClassType)): try: testRunner = self.testRunner(verbosity=self.verbosity, failfast=self.failfast, buffer=self.buffer) except TypeError: # didn't accept the verbosity, buffer or failfast arguments testRunner = self.testRunner() else: # it is assumed to be a TestRunner instance testRunner = self.testRunner #根据输入的参数初始化runner类 #调用runner.run运行测试用例 self.result = testRunner.run(self.test) if self.exit: sys.exit(not self.result.wasSuccessful()) #主函数 main = TestProgram
相关文章推荐
- unittest 源代码分析(一)--unittest代码结构分析
- (1)写一个程序,用于分析一个字符串中各个单词出现的频率,并将单词和它出现的频率输出显示。(单词之间用空格隔开,如“Hello World My First Unit Test”); (2)编写单元测试进行测试; (3)用ElcEmma查看代码覆盖率,要求覆盖率达到100%。
- Selenium-Webdriver(python) (六) --- Unittest框架分析
- 使用 Visual Studio 2005 Team System 进行单元测试并生成用于 Unit Test Framework 的源代码 (实例)
- __main代码分析
- 语法分析表产生器的代码之一:主函数main.cpp
- Python 的单元测试框架Unittest之一(TestResult类分析)
- python调用HTMLTestRunner+unittest实现一次执行多个测试类,并生成与每个测试类对应的测试报告,并不像某些人写的每次只执行一个测试类,具体看代码,附上整个project代码
- BT源代码学习心得(六):跟踪服务器(Tracker)的代码分析(初始化) -- 转贴自 wolfenstein (NeverSayNever)
- cocos2d-x 3.0 示例代码分析3:BaseTest
- 21.番外篇:Tornado的多进程管理分析---process.py代码解读
- Essential C++ 第一章,猜数代码分析ch1_main.cpp + 知识点总结
- unittest+coverage单元测试代码覆盖操作实例详解
- spice server qxl red_worker_main()代码分析
- 使用 py.test 对 python 代码进行测试
- RTMPdump 源代码分析 1: main()函数
- FFmpeg源代码结构图 - 雷神经典代码分析
- 【QEMU-KVM代码分析之三】IO thread源码浅析之main loop
- python unittest源码解析三----loader.py之_get_name_from_path(self, path)
- BT源代码学习心得(八):跟踪服务器(Tracker)的代码分析(用户请求的实际处理)