本文介绍了Python 的 unittest 模块如何检测测试用例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道当我们运行 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.testLoaderunittest.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 模块如何检测测试用例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-23 17:38