问题描述
我想知道当我们运行 unittest.main()
时,Python 如何知道 unittest.Testcase
有哪些子类?
I was wondering when we run unittest.main()
, how does Python know what subclasses unittest.Testcase
has?
例如,如果我添加一个类 FromRomanBadInput(unittest.TestCase)
,unittest
怎么知道要运行它?
For example, if I add a class FromRomanBadInput(unittest.TestCase)
, how does unittest
know to run this?
推荐答案
所以我在我的 Python27/Lib
目录中四处看了看...
So I looked around in my Python27/Lib
directory...
unittest.main
实际上是一个类的别名,unittest.TestProgram
.所以发生的事情是你构造了一个它的实例,它的 __init__
运行,它做一堆健全性检查和配置,包括你调用它的模块的动态导入(它使用 __init__
code>__import__ 函数,使用 __main__
作为要导入的模块的名称,默认情况下).所以现在它有一个 self.module
属性,它包含一个代表你的源的模块对象.
unittest.main
is actually an alias for a class, unittest.TestProgram
. So what happens is you construct an instance of this, and its __init__
runs, which does a bunch of sanity checks and configuration, including a dynamic import of the module that you called it from (it uses the __import__
function, with __main__
as the name of the module to import, by default). So now it has a self.module
attribute that contains a module object that represents your source.
最终,它得到了这个代码:
Eventually, it gets to this code:
self.test = self.testLoader.loadTestsFromModule(self.module)
其中 self.testLoader
是 unittest.TestLoader
的一个实例.该方法包括:
where self.testLoader
is an instance of unittest.TestLoader
. That method contains, among other stuff:
for name in dir(module):
obj = getattr(module, name)
if isinstance(obj, type) and issubclass(obj, case.TestCase):
tests.append(self.loadTestsFromTestCase(obj))
因此它使用模块对象的 dir
来获取您定义的所有全局变量(包括类)的名称,将其过滤为仅从 unittest.TestCase 派生的类
(在本地,case.TestCase
是它的别名),然后在这些类中查找测试方法以添加到 tests
列表中.该搜索的行为类似:
So it uses the dir
of your module object to get the names of all the global variables you defined (including classes), filters that to just the classes that derive from unittest.TestCase
(locally, case.TestCase
is an alias for that), and then looks for test methods inside those classes to add to the tests
list. That search behaves similarly:
def isTestMethod(attrname, testCaseClass=testCaseClass,
prefix=self.testMethodPrefix):
return attrname.startswith(prefix) and \
hasattr(getattr(testCaseClass, attrname), '__call__')
testFnNames = filter(isTestMethod, dir(testCaseClass))
因此它使用类的 dir
来获取要尝试的名称列表,查找具有这些名称的属性,并选择以 self.testMethodPrefix
(默认为 'test'
)并且是可调用的(依次具有 __call__
属性).(我真的很惊讶他们在这里没有使用内置的 callable
函数.我想这是为了避免选择嵌套类.)
so it uses the dir
of the class to get a list of names to try, looks for attributes with those names, and selects those that start with the self.testMethodPrefix
('test'
by default) and that are callable (have, in turn, a __call__
attribute). (I'm actually surprised they don't use the built-in callable
function here. I guess this is to avoid picking up nested classes.)
这篇关于Python 的 unittest 模块如何检测测试用例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!