【Python测试】unittest源码解析一----测试用例是如何被执行的

【Python测试】unittest源码解析⼀----测试⽤例是如何被执⾏
在Python的单元测试中,有各种不同⽅式来执⾏⽤户的测试⽤例,在接下来的篇幅中,我们会详细叙述每种⽅式的具体执⾏流程。
先来看下unittest中的__init__.py中提供的⼀个测试⽤例案例:
import unittest
class IntegerArithmeticTestCase(unittest.TestCase):
def testAdd(self):  ## test method names begin 'test*'
self.assertEqual((1 + 2), 3)
self.assertEqual(0 + 1, 1)
def testMultiply(self):
self.assertEqual((0 * 10), 0)
self.assertEqual((5 * 8), 40)
if __name__ == '__main__':
unittest.main()
可以把上⾯的⽤例放到⼀个arithmetic.py中,然后执⾏命令python arithmetic.py,测试⽤例会被依次运⾏。
那么,unittest是怎么提取相应的测试⽤例进⾏的运⾏的呢?
先来看⼀下unittest下⾯有哪些⽂件,分别是:
__init__.py,__main__.py,case.py,loader.py,main.py,result.py,runner.py,signals.py,suite.py,utils.py。
这⾥先不描述这些⽂件都有什么⽤,因为在执⾏流程的叙述中⾃然会说明⽩它们的作⽤。
1.
unittest.main()开始了整个单元测试,这⾥实际上是调⽤了main.py中的TestProgram类的构造函数,因
为在该⽂件中有这样⼀条语句:main = TestProgram。
def __init__(self, module='__main__', defaultTest=None, argv=None,
testRunner=None, testLoader=loader.defaultTestLoader,
exit=True, verbosity=1, failfast=None, catchbreak=None,
buffer=None):
print str(self.__class__) + " " + str(sys._getframe().f_lineno)
if isinstance(module, basestring):
print str(self.__class__) + " " + str(sys._getframe().f_lineno)
for part in module.split('.')[1:]:
else:
if argv is None:
argv = sys.argv
self.failfast = failfast
self.catchbreak = catchbreak
self.verbosity = verbosity
self.buffer = buffer
self.defaultTest = defaultTest
self.progName = os.path.basename(argv[0])
self.parseArgs(argv)
self.runTests()
上⾯是TestProgram的构造函数,这⾥的module默认是__main__,然后会去动态加载当前的module,即dule =
__import__(module)。
这⾥是为了执⾏测试⽤例所在的module。再来看下另外个参数testLoader=loader.defaultTestLoader,在loader.py中设置了defaultTestLoader = TestLoader()。
构造函数中进⾏了⼀系列的初始化操作,最后分别执⾏self.parseArgs(argv)和runTests()去提取和执⾏测试⽤例。
self.parseArgs(argv)会执⾏ateTests(),如下
def createTests(self):
stNames is None:
else:
这⾥testNames是None,所以会执⾏:
进⼊loader.py的loadTestsFromModule:
def loadTestsFromModule(self, module, use_load_tests=True):
"""Return a suite of all tests cases contained in the given module"""
tests = []
print module
for name in dir(module):
油水冷却器obj = getattr(module, name)
if isinstance(obj, type) and issubclass(obj, case.TestCase):
tests.append(self.loadTestsFromTestCase(obj))
load_tests = getattr(module, 'load_tests', None)
tests = self.suiteClass(tests)
if use_load_tests and load_tests is not None:
try:
return load_tests(self, tests, None)
except Exception, e:
return _make_failed_load_tests(module.__name__, e,
self.suiteClass)
雨水边沟return tests
这⾥是把self.loadTestsFromTestCase(obj)得到suite追加到tests列表中,然后把tests也转化为suite,并且返回。(这⾥⾯包含了所有的TestCase)
2.
下⾯来看看self.runTests()怎么执⾏
def runTests(self):
if self.catchbreak:
installHandler()
stRunner is None:
if stRunner, (type, types.ClassType)):
try:
testRunner = stRunner(verbosity=self.verbosity,
failfast=self.failfast,
buffer=self.buffer)屋顶融雪装置
except TypeError:
# didn't accept the verbosity, buffer or failfast arguments
testRunner = stRunner()
else:
# it is assumed to be a TestRunner instance插卡式摄像机
testRunner = stRunner
it:
在runTests()中会执⾏testRunner.st),也就是说会去执⾏TextTestRunner中的run⽅法,并把原先获取的TestSuite对想传⼊。
runner.py
try:
test(result)
finally:
stopTestRun = getattr(result, 'stopTestRun', None)
自动钎焊设备if stopTestRun is not None:
stopTestRun()
这⾥会回调TestSuite中的run⽅法。
def __call__(self, *args, **kwds):
return self.run(*args, **kwds)
def run(self, result, debug=False):
print str(self.__class__) + " " + str(sys._getframe().f_lineno) + "\n"
topLevel = False
if getattr(result, '_testRunEntered', False) is False:
result._testRunEntered = topLevel = True
for test in self:
if result.shouldStop:
break
if _isnotsuite(test):
self._tearDownPreviousClass(test, result)
self._handleModuleFixture(test, result)
self._handleClassSetUp(test, result)
result._previousTestClass = test.__class__
if (getattr(test.__class__, '_classSetupFailed', False) or
getattr(result, '_moduleSetUpFailed', False)):
continue
if not debug:
test(result)
黄金木枣else:
test.debug()
if topLevel:
self._tearDownPreviousClass(None, result)
self._handleModuleTearDown(result)
result._testRunEntered = False
return result
在run中,通过⼀个for循环依次调⽤TestCase的run⽅法去执⾏具体的测试⽤例(这⾥要注意的是,如果test还是TestSuite类型,会继续递归调⽤)。
case.py
def __call__(self, *args, **kwds):
return self.run(*args, **kwds)
进⼊TestCase的run⽅法:
获取测试⽅法
testMethod = getattr(self, self._testMethodName)执⾏获取到的测试⽅法
else:
try:
testMethod()
except KeyboardInterrupt:
raise

本文发布于:2024-09-20 12:00:34,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/1/105402.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:测试   追加   获取
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议