如何在pytest中以编程方式将函数注册为测试函数?
在pytest中编程式添加/标记测试用例
方法一:自定义@testcase装饰器
通过自定义装饰器标记函数,再让pytest识别这些标记过的函数为测试用例。
实现装饰器
给目标函数添加一个标识属性,用来标记这是一个测试用例:
def testcase(func): func.is_pytest_testcase = True return func
配置pytest钩子识别测试用例
在项目根目录创建conftest.py,添加pytest_collection_modifyitems钩子函数,遍历模块中的函数,把标记过的函数转为测试用例:
def pytest_collection_modifyitems(session, config, items): # 遍历所有已加载的模块 for module in session.items_by_module.values(): # 遍历模块内的对象 for name, obj in vars(module).items(): # 筛选出被testcase装饰的可调用对象 if callable(obj) and getattr(obj, "is_pytest_testcase", False): # 将函数转为pytest测试项并加入测试列表 test_item = session.getitem(obj) items.append(test_item)
使用示例
@testcase def a_function_specification(): assert 1 + 1 == 2
方法二:手动注册测试用例(类似pytest.add_test)
通过手动调用注册函数,把普通函数加入测试用例列表。
实现测试注册器
在测试模块中定义一个列表和注册函数,用来存储要添加的测试函数:
registered_tests = [] def add_test(func): registered_tests.append(func) return func
配置pytest处理注册的测试用例
同样在conftest.py中添加钩子,遍历模块的注册列表,把函数转为测试用例:
def pytest_collection_modifyitems(session, config, items): for module in session.items_by_module.values(): # 检查模块是否有注册的测试列表 if hasattr(module, "registered_tests"): for func in module.registered_tests: test_item = session.getitem(func) items.append(test_item)
使用示例
def a_function_specification(): assert 3 * 4 == 12 add_test(a_function_specification)
自定义测试项(进阶)
如果需要完全自定义测试用例的执行逻辑,可以继承pytest.Item实现自定义测试项,替代默认的测试项类型:
class CustomTestItem(pytest.Item): def __init__(self, name, parent, func): super().__init__(name, parent) self.test_func = func def runtest(self): # 自定义测试执行逻辑 self.test_func() def pytest_collection_modifyitems(session, config, items): for module in session.items_by_module.values(): for name, obj in vars(module).items(): if callable(obj) and getattr(obj, "is_pytest_testcase", False): # 创建自定义测试项并加入列表 custom_item = CustomTestItem(name, session, obj) items.append(custom_item)
这种方式可以实现和pytest.mark、参数化完全不同的测试生成逻辑,满足个性化需求。
内容的提问来源于stack exchange,提问作者wirrbel
相关产品推荐
相关产品推荐

