You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用@pytest.mark.django_db时如何避免pytest自动将测试包裹在事务中

pytest-django测试transaction.on_commit()不触发的解决方案

方案1:手动执行on_commit回调(优先推荐)

不需要修改默认事务回滚逻辑,测试速度无损失,直接调用Django内置的回调捕获工具即可:

  • 导入django.test.TestCase,使用captureOnCommitCallbacks上下文管理器,将execute参数设为True,上下文退出时会自动执行所有注册的on_commit回调
    示例代码:
import pytest
from django.test import TestCase
from your_app.module import your_function_with_on_commit

@pytest.mark.django_db
def test_on_commit_logic():
    with TestCase.captureOnCommitCallbacks(using="default", execute=True):
        # 执行包含on_commit的业务代码
        your_function_with_on_commit()
    # 此处on_commit逻辑已执行,可直接断言结果
    # assert 你的断言逻辑

方案2:修改django_db标记开启真实事务提交

给@pytest.mark.django_db添加transaction=True参数,pytest不会再将测试包裹在自动回滚的事务中,会真实提交事务,自然触发on_commit逻辑:
示例代码:

import pytest
from your_app.module import your_function_with_on_commit

@pytest.mark.django_db(transaction=True)
def test_on_commit_logic():
    your_function_with_on_commit()
    # 此处on_commit逻辑已随事务提交触发
    # assert 你的断言逻辑

方案3:使用transactional_db fixture

和方案2效果完全一致,直接在测试函数参数中引入transactional_db fixture即可,不需要额外修改标记:
示例代码:

import pytest
from your_app.module import your_function_with_on_commit

def test_on_commit_logic(transactional_db):
    your_function_with_on_commit()
    # 此处on_commit逻辑已随事务提交触发
    # assert 你的断言逻辑

注意事项

  • 方案2、3会真实提交事务,测试结束后pytest-django会自动执行flush命令清理测试数据,测试速度比默认模式慢,适合无法用方案1覆盖的场景
  • 如果你的on_commit逻辑依赖其他数据库事务特性,优先选择方案2、3

内容的提问来源于stack exchange,提问作者Yituo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 11:36:09