新增测试用例后Django创建特定模型的单元测试突发报错求助
核心问题是Django TestCase的原子事务机制与MySQL连接/事务状态冲突:TestCase默认会将每个测试方法包裹在atomic块中,测试结束后回滚事务以隔离测试环境,但当事务内出现未妥善处理的错误(或MySQL连接因超时/负载断开)时,后续的数据库操作会触发事务状态异常,最终导致OperationalError (2006, '')(MySQL连接断开)。
具体排查与修复步骤
检查测试中的事务干扰代码:
排查所有测试用例及关联代码(如信号、模型方法),确认是否存在手动调用transaction.commit()/transaction.rollback()、在atomic块外执行写操作,或捕获数据库异常后未重置事务状态的情况。这类操作会破坏TestCase的事务隔离机制,导致后续测试的事务上下文异常。调整MySQL连接超时参数:
测试套件规模较大时,闲置的数据库连接可能被MySQL提前断开。修改MySQL配置文件(my.cnf/my.ini):wait_timeout = 3600 interactive_timeout = 3600重启MySQL服务后再运行测试,避免连接超时断开。
升级MySQL驱动版本:
当前使用的MySQLdb可能存在事务处理兼容性问题,换成Django官方推荐的最新版mysqlclient:pip uninstall MySQLdb pip install mysqlclient>=2.1.0若仍有问题,可尝试
PyMySQL(需在Django设置中配置:import pymysql; pymysql.install_as_MySQLdb())。调整Django测试数据库配置:
在settings.py的DATABASES配置中,禁用连接复用,避免复用异常连接:DATABASES = { 'default': { # ... 原有配置 'TEST': { 'NAME': 'test_db', }, 'CONN_MAX_AGE': 0, # 每次请求新建连接,禁用连接复用 } }排查信号与异步操作:
检查模型的post_save/pre_save等信号处理器,确认是否在信号中执行了数据库操作且未正确处理事务上下文。若信号中的操作抛出异常,会导致当前事务进入错误状态,后续测试无法正常执行。临时优化事务隔离方案(不推荐长期使用):
若上述方法均无效,可尝试用--keepdb参数避免每次重建数据库,或使用pytest-xdist等工具并行运行测试,缓解TransactionTestCase带来的速度问题。
内容的提问来源于stack exchange,提问作者Romero Cartaxo

