Django中LiveServerTestCase无法加载fixtures问题咨询
为什么LiveServerTestCase的fixtures在setUpClass中不加载?
这是因为 LiveServerTestCase 和 TestCase 处理fixtures的时机完全不同:
核心原因
TestCase基于数据库事务实现测试隔离:它会在测试类初始化的setUpClass阶段一次性加载fixtures到测试数据库,之后每个测试方法运行在独立的事务中,结束后回滚到初始状态。所以你在setUpClass中调用super().setUpClass()后,fixtures已经被加载,能查询到数据。LiveServerTestCase要支持外部HTTP客户端(比如你用的Selenium),而事务内的数据库变更对外部客户端不可见,因此它不会使用事务。取而代之的是,它会在每个测试方法的setUp()阶段重新加载fixtures,确保每个测试都有干净的初始数据。这就导致在类级别的setUpClass()方法中,fixtures还未被加载,查询结果自然为空。
解决方案
根据你的需求,有两种可行的处理方式:
方式一:将依赖fixtures的代码移到测试方法或实例级setUp中
这是最符合Django设计意图的方式,因为LiveServerTestCase的fixtures就是为每个测试方法准备的:
from django.contrib.staticfiles.testing import LiveServerTestCase from selenium.webdriver.chrome.webdriver import WebDriver from myapp.models import Event class FrontTest(LiveServerTestCase): fixtures = ['event.json'] @classmethod def setUpClass(cls): super().setUpClass() # 这里不要查询fixtures数据,此时还没加载 cls.driver = WebDriver() @classmethod def tearDownClass(cls): cls.driver.quit() super().tearDownClass() def setUp(self): super().setUp() # 在这里可以查询到fixtures数据 print(Event.objects.all()) # 输出 [<Event: event search>] def test_event_search(self): # 测试方法中可以正常使用fixtures数据 self.driver.get(f"{self.live_server_url}/events/") # 后续Selenium操作...
方式二:在setUpClass中手动加载fixtures
如果你确实需要在类级别就加载fixtures(比如启动服务器前需要初始化某些数据),可以手动调用loaddata命令:
from django.contrib.staticfiles.testing import LiveServerTestCase from django.core.management import call_command from myapp.models import Event class FrontTest(LiveServerTestCase): @classmethod def setUpClass(cls): super().setUpClass() # 手动加载fixtures到测试数据库 call_command('loaddata', 'event.json') print(Event.objects.all()) # 现在能正常输出数据了 # 后续初始化Selenium等操作...
额外提示
注意你提供的event.json最后有个多余的逗号("expiry_date": null, } },),这会导致JSON格式错误。虽然你的TestCase能正常加载,可能是实际文件中已经修正,但建议检查一下fixtures文件的格式,避免后续出现加载失败的问题。
内容的提问来源于stack exchange,提问作者AntoineLB
相关产品推荐
相关产品推荐

