问题描述
在测试用例中使用参数化,在@pytest.mark.parametrize()
上方加入装饰器来抓取运行报错信息,但是加入装饰器后参数化失效了。如图:
出现原因
装饰器改变了函数的签名或行为,导致 pytest
无法正确识别和处理参数化的测试用例。
-
装饰器没有正确保留被装饰函数的元信息
pytest
使用函数的元信息(例如__name__
和__doc__
)来识别测试用例。未经特殊处理的装饰器会改变这些元信息,从而导致pytest
无法识别测试用例。示例:def my_decorator(func): def wrapper(*args, **kwargs): print("Before the test") result = func(*args, **kwargs) print("After the test") return result return wrapper
装饰后,函数
func
的元信息就被替换成了wrapper
的元信息。 -
装饰器改变了函数签名
pytest.mark.parametrize
需要知道测试函数的参数列表。如果装饰器改变了函数签名,pytest
将无法为测试函数提供正确的参数。
解决办法
为了避免这些问题,可以使用 Python 内置的 functools.wraps
来修饰装饰器,保留原函数的元信息和签名。
import pytest
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print("Before the test")
result = func(*args, **kwargs)
print("After the test")
return result
return wrapper
@pytest.mark.parametrize("x, y, expected", [(1, 1, 2), (2, 2, 4)])
@my_decorator
def test_add(x, y, expected):
assert x + y == expected