Django 2.0 TestCase:如何为所有测试创建pk=1的唯一Board对象
解决Django测试中创建唯一pk=1的Board对象的问题
在Django 2.0.3中,要让所有测试用例共享同一个pk=1的Board对象,避免每次测试都创建新对象导致pk递增,你可以按照以下方法操作:
1. 使用TestCase的setUpTestData类方法
Django的TestCase提供了setUpTestData类方法,它会在整个测试类的所有测试方法运行前只执行一次,创建的测试数据会被所有测试用例共享,并且每个测试方法结束后,对数据的修改会自动回滚,保证原始的pk=1对象始终存在。
示例代码:
from django.test import TestCase from your_app.models import Board class BoardTests(TestCase): @classmethod def setUpTestData(cls): # 仅执行一次,创建pk=1的Board对象 # 替换为你的Board模型需要的字段 Board.objects.create( pk=1, name="测试看板", description="用于测试的看板" # 其他必填字段... ) def test_board_pk(self): # 获取共享的pk=1对象 board = Board.objects.get(pk=1) self.assertEqual(board.pk, 1) def test_board_name(self): # 即使上一个测试修改了对象,这里依然会拿到原始数据(因为事务回滚) board = Board.objects.get(pk=1) self.assertEqual(board.name, "测试看板")
2. 避免在setUp中重复创建对象
如果你之前是在setUp方法中创建Board对象,那么每个测试用例都会执行一次setUp,导致每次都生成新的对象,pk自然会递增。所以一定要把创建逻辑移到setUpTestData中,而不是setUp。
3. 特殊场景:使用pytest的fixture(如果用pytest测试)
如果你用pytest代替Django自带的测试框架,可以定义一个作用域为类/模块的fixture,确保对象只创建一次:
import pytest from your_app.models import Board @pytest.fixture(scope="class") def fixed_board(): # 创建pk=1的对象,所有测试类内的方法共享 return Board.objects.create(pk=1, name="测试看板") class TestBoardOperations: def test_modify_board(self, fixed_board): fixed_board.name = "修改后的看板" fixed_board.save() assert fixed_board.name == "修改后的看板" def test_original_board(self, fixed_board): # 上一个测试的修改会被回滚,这里拿到原始对象 assert fixed_board.name == "测试看板"
关键注意点
- 确保你的测试类继承自
django.test.TestCase(而非SimpleTestCase),这样才能享受到事务隔离和setUpTestData的特性。 - 不要在测试方法中重复创建
pk=1的Board对象,否则会抛出主键冲突的异常;如果需要使用看板,直接通过Board.objects.get(pk=1)获取即可。
内容的提问来源于stack exchange,提问作者MK87
相关产品推荐
相关产品推荐

