Pytest批量执行数据库查询用例第二条失败单独执行正常问题排查
问题根因
- 核心原因是Oracle客户端重复初始化触发异常:
cx_Oracle.init_oracle_client()方法全局仅允许执行一次,第一个测试用例调用conexion()方法时已完成客户端初始化,第二个测试用例再次调用该方法时,重复执行初始化逻辑会直接抛出异常。代码的异常捕获分支仅打印报错信息,没有定义返回值,因此调用方会拿到默认返回的None,最终触发assert None == 20的报错。单独执行第二个测试用例时仅会初始化一次Oracle客户端,不会触发该异常,因此运行正常。 - 数据库连接方法本身也存在多处缺陷:
- 没有显式关闭游标、数据库连接,多次调用会造成连接泄露,极端情况会耗尽数据库连接数导致新建连接失败
- 异常处理逻辑不完善,仅打印报错没有抛出异常或返回明确的错误标识,调用方无法区分是查询结果为空还是数据库连接出错
- SQL语句使用字符串拼接编写,存在SQL注入风险
- 未对
cursor.fetchone()的返回值做判空处理,如果查询结果为空,调用datos[0]会直接抛出索引越界异常
修复方案
- 将Oracle客户端初始化逻辑从
conexion()方法中移出,放到类构造方法、全局初始化函数或Pytest的session级fixture中,保证全局仅执行一次 - 完善异常处理逻辑:出现数据库连接错误时主动抛出异常,或返回可识别的错误值,避免调用方拿到无意义的
None - 增加资源释放逻辑:查询完成后按顺序关闭游标、数据库连接,或使用上下文管理器自动管理连接生命周期
- 改写SQL为参数化查询格式,规避SQL注入风险
- 对
fetchone()的返回值增加判空逻辑,查询无结果时返回约定值或抛出明确的查询为空异常
内容的提问来源于stack exchange,提问作者Fedex
相关产品推荐
相关产品推荐

