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

如何让pytest多个测试共用同一数据库与module级fixture?

解决Django+pytest中Module级Fixture对象在多测试间不可见的问题

这问题我刚上手pytest+Django的时候也踩过一模一样的坑!你遇到的核心原因是Django测试框架的事务隔离机制:

默认情况下,pytest-django的django_db fixture会为每个测试函数单独开启一个数据库事务,测试执行完成后自动回滚,目的是保证测试之间的独立性。但你的forwarding_bot fixture是module级别的——它在所有测试的事务之外创建,第一个测试结束后回滚了自己的事务,第二个测试开启新事务时,自然看不到之前创建的Bot对象了。

解决方案:使用transactional_db共享事务

最简单的修复方式是让整个测试模块共享同一个数据库事务,这可以通过依赖pytest-django提供的transactional_db fixture实现:

import pytest
from django.contrib.auth import get_user_model
from bots.models import Bot

@pytest.fixture(scope='module')
def forwarding_bot(transactional_db):
    # 先创建用户,再创建Bot
    test_user = get_user_model().objects.create_user(username='test_user')
    bot, created = Bot.objects.get_or_create(
        name="test_bot",
        user=test_user,
        forward_http_requests_to='https://httpbin.org/post'
    )
    return bot

def test_get_bot_by_pk(forwarding_bot):
    print(f'test_get_bot_by_pk: bot count: {Bot.objects.count()}')  # 输出1

def test_get_bot_by_uuid(forwarding_bot):
    print(f'test_get_bot_by_uuid: bot count: {Bot.objects.count()}')  # 现在也会输出1

原理说明

transactional_db fixture会在模块级别开启一个数据库事务,所有该模块下的测试函数都在这个事务里执行。测试模块结束后,才会统一回滚事务,这样你在module级fixture里创建的Bot对象,在所有测试中都能访问到。

注意事项

  • 因为所有测试共享同一个事务,如果某个测试修改了forwarding_bot的状态(比如修改name字段),后续测试会看到修改后的状态,所以要确保测试之间没有状态依赖,或者在fixture中做必要的状态重置。
  • 如果你需要更细粒度的控制,也可以考虑使用function级别的fixture,结合@pytest.mark.django_db(transaction=True)标记,但这样就失去了module级别fixture只创建一次的优势。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:59:08