在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!,), {}]
图书馆怎么弄清楚它应该运行我的装饰方法?
答案 0 :(得分:3)
包装函数的__name__
可能是wrapper
,但它仍然是TestAdd.test_add
。如同,如果你查看TestAdd
类的__dict__
,你会发现包装函数绑定到键'test_add'
,如果你想调用该方法,你会使用这个名字test_add
,而非wrapper
。
当unittest
使用方法名称来确定方法是否为测试时,它不会查看__name__
。它查看与方法关联的属性名称,而装饰器不会影响该属性。