pytest fixture清理数据未打印预期信息及变量引用问题
问题分析与解决方案
问题1:清理代码未执行的原因
你在yield之后定义了_cleanup_data函数,但从来没调用过它,所以里面的打印和数据库操作根本不会执行,只会触发print("teardown")。另外这个函数里还递归调用了自己,就算调用了也会直接栈溢出,这是个致命bug。
问题2:直接打印cab_user_id报错的原因
cab_user_id是_setup_data函数的局部参数,只在调用_setup_data时存在,而yield之后的teardown阶段脱离了这个上下文,自然找不到该变量,所以报“未解析的引用”错误。
修正后的代码
要解决这两个问题,你需要在fixture外层记录所有被修改过的用户ID,让teardown阶段能逐个清理:
import random import pytest @pytest.fixture def setup_data_register_new_user(db_connection): # 记录所有被修改过的cab_user_id,用于teardown阶段统一清理 modified_user_ids = [] def _setup_data(cab_user_id): cursor = db_connection.cursor() random_mobile = f"+9{random.randint(1000000000, 9999999999)}" random_cab_user_id = str(random.randint(1000000000, 9999999999)) cursor.execute(""" UPDATE tbl_user SET mobile = %s, cab_user_id = %s WHERE cab_user_id = %s """, (random_mobile, random_cab_user_id, cab_user_id)) db_connection.commit() # 将原cab_user_id加入记录列表(若需清理新生成的ID,可替换为random_cab_user_id) modified_user_ids.append(cab_user_id) # 返回新生成的cab_user_id,方便测试用例调用 return random_cab_user_id yield _setup_data # teardown阶段:遍历所有记录的用户ID执行清理 print("teardown: 开始清理测试数据") cursor = db_connection.cursor() for user_id in modified_user_ids: print(f"Cleaning up for cab_user_id: {user_id}") # 按需求编写清理逻辑,示例为查询当前记录,可扩展为恢复/删除数据 cursor.execute(""" select * FROM tbl_user WHERE cab_user_id = %s """, (user_id,)) result = cursor.fetchall() print("************************", result) # 示例:若需恢复原数据,可在此处执行反向UPDATE操作 # cursor.execute(""" # UPDATE tbl_user SET cab_user_id = %s WHERE ... # """, (user_id,)) # db_connection.commit() cursor.close()
关键修改点
- 新增
modified_user_ids列表,在_setup_data中记录所有被操作的用户ID,让teardown阶段能获取到需要清理的对象 - teardown阶段直接遍历列表执行清理逻辑,避免了未调用函数和递归溢出的问题
- 在
_setup_data中返回新生成的cab_user_id,方便测试用例直接使用修改后的参数
内容的提问来源于stack exchange,提问作者Safa
相关产品推荐
相关产品推荐

