【读源码】unittest -- __init__.py 和 __main__.py
目录
__init__.py
__all__ = ['TestResult', 'TestCase', 'TestSuite',
'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main',
'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless',
'expectedFailure', 'TextTestResult', 'installHandler',
'registerResult', 'removeResult', 'removeHandler']
# Expose obsolete functions for backwards compatibility
__all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])
__unittest = True
from .result import TestResult
from .case import (TestCase, FunctionTestCase, SkipTest, skip, skipIf,
skipUnless, expectedFailure)
from .suite import BaseTestSuite, TestSuite
from .loader import (TestLoader, defaultTestLoader, makeSuite, getTestCaseNames,
findTestCases)
from .main import TestProgram, main
from .runner import TextTestRunner, TextTestResult
from .signals import installHandler, registerResult, removeResult, removeHandler
# deprecated
_TextTestResult = TextTestResult
# There are no tests here, so don't try to run anything discovered from
# introspecting the symbols (e.g. FunctionTestCase). Instead, all our
# tests come from within unittest.test.
def load_tests(loader, tests, pattern):
import os.path
# top level directory cached on loader instance
this_dir = os.path.dirname(__file__)
return loader.discover(start_dir=this_dir, pattern=pattern)
__init__.py 特殊文件的作用
__init__.py 文件的存在使得 unittest 的目录被 Python 解释器当做一个包 (Package)。
__all__ 特殊变量的作用
__all__ 变量定义适用导入语句 from unittest import *
时,会导入到当前命名空间里的东西。
相对导入
from .xxx import xxx
使用相对导入从子模块中变量、类或函数等
其他
load_tests
定义一个函数,从 __init__.py 所在的目录适用 loader 模块的 discover 函数发现用例
__main__.py
"""Main entry point"""
import sys
if sys.argv[0].endswith("__main__.py"):
import os.path
# We change sys.argv[0] to make help message more useful
# use executable without path, unquoted
# (it's just a hint anyway)
# (if you have spaces in your executable you get what you deserve!)
executable = os.path.basename(sys.executable)
sys.argv[0] = executable + " -m unittest"
del os
print(sys.argv[0])
__unittest = True
from .main import main, TestProgram
main(module=None)
__main__.py 特殊文件的作用
python -m unittest xxx
运行 unittest 时,__main__.py 会被执行
其他
python -m unittest xxx
运行 unittest 时,sys.argv 变量是个列表,内容是类似 ['/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/__main__.py', 'main.py']
。sys.executable 是 Python 解释器的可执行文件的名字也就是 python
。
if 逻辑修改了 sys.argv[0] 的内容变成了 python -m unittest
。目的是简化了信息。
然后使用相对导入,导入了 main、TestProgram,从 main.py 中看到 main=TestProgram
,即 main 变量等同于 TestProgram 类。然后调用 main(module=None) 即执行 TestProgram 的实例初始化 __init__() 方法,因此, TestProram.__init__ 方法定义了主要的执行流程。