unittest库如何确定是否运行一个装饰方法?

时间:2016-12-26 00:23:31

标签: python

在Linux上使用Python 2.7.12进行测试。

我正在尝试编写一个简单的函数来装饰test_*中的unittest.TestCase方法。我知道不以test_开头的方法不被视为实际测试,并且在运行测试时不会直接调用。然后我想知道如果你采用test_方法并将一个天真的装饰器应用于它而没有尝试保留名称,你会发生什么。我希望我的测试被忽略,并且必须修改我的装饰器以确保该函数的名称以test_开头。无论如何,当测试运行时,我非常非常惊讶。

这里是示例

的目录布局
.
|-- add.py
|-- print_args.py
|-- test_add.py
`-- test_add_decorated.py

0 directories, 4 files

add.py是我们正在测试的库。它增加了两件事。

def add(x, y):
    return x + y

print_args.py是一个包含装饰器的库,它打印函数的args和kwargs作为副作用。它尽可能天真地编写,并且不会尝试保留函数的名称。

def print_args(wrapped):
    def wrapper(*args, **kwargs):
        print [args, kwargs]
        return apply(wrapped, args, kwargs)

    return wrapper

以下test_add.py导入add.py并测试4 + 5 = 9__repr__的{​​{1}}方法与此示例没有直接关系,但会在下一个方法中。

TestAdd

当我们运行import unittest import add class TestAdd(unittest.TestCase): def __repr__(self): return "I am a unittest.TestCase! Fear me!" def test_add(self): self.assertEqual(add.add(4, 5), 9) if __name__ == "__main__": unittest.main() 时,我们可以看到一个测试已经运行并且已经通过了。

test_add.py

现在我们将装饰器应用于---------------------------------------------------------------------- Ran 1 test in 0.000s OK 中的test_add方法。

test_add_decorated.py

在我运行之前,我希望看到没有错误,但是表明零测试已经运行,因为import unittest import print_args import add class TestAdd(unittest.TestCase): def __repr__(self): return "I am a unittest.TestCase! Fear me!" @print_args.print_args def test_add(self): self.assertEqual(add.add(4, 5), 9) if __name__ == "__main__": unittest.main() 方法的名称现在应该是test_add

这不是发生的事情。 wrapper装饰器工作正常,我们可以在数组中看到args和kwargs,并指示一个测试成功运行。

print_args

所以,我的问题是...... . ---------------------------------------------------------------------- Ran 1 test in 0.000s OK [(I am a unittest.TestCase! Fear me!,), {}] 图书馆怎么弄清楚它应该运行我的装饰方法?

1 个答案:

答案 0 :(得分:3)

包装函数的__name__可能是wrapper,但它仍然是TestAdd.test_add。如同,如果你查看TestAdd类的__dict__,你会发现包装函数绑定到键'test_add',如果你想调用该方法,你会使用这个名字test_add,而非wrapper

unittest使用方法名称来确定方法是否为测试时,它不会查看__name__。它查看与方法关联的属性名称,而装饰器不会影响该属性。