如何在Django测试前创建可被所有测试用例共享的用户实例
解决Django测试中共享用户实例的问题
方法一:使用setUpClass创建全局共享用户(仅创建一次)
如果希望用户实例在整个测试类的所有测试方法中只初始化一次,需要用@classmethod装饰setUpClass方法,将用户赋值给类属性(而非实例属性)——因为setUpClass是类方法,操作的是测试类本身而非单个测试实例。
注意:Django的TestCase会为每个测试方法开启独立事务,对用户的修改不会影响其他测试方法,但用户的初始状态会保持一致。
示例代码:
from django.test import TestCase from django.contrib.auth.models import User class DoSomeTests(TestCase): @classmethod def setUpClass(cls): super().setUpClass() # 创建共享用户,赋值给类属性 cls.usr1 = User.objects.create_user(username='user1', password='test123') cls.usr2 = User.objects.create_user(username='user2', password='test123') cls.usr3 = User.objects.create_user(username='user3', password='test123') @classmethod def tearDownClass(cls): # 可选:手动清理类级资源,Django测试框架也会自动清理数据库数据 cls.usr1.delete() cls.usr2.delete() cls.usr3.delete() super().tearDownClass() def test_number_one(self): # 可通过实例或类访问共享用户 self.assertEqual(self.usr1.username, 'user1') # 编写测试逻辑 def test_number_two(self): self.assertEqual(self.usr2.username, 'user2') # 编写测试逻辑 def test_number_three(self): self.assertEqual(self.usr3.username, 'user3') # 编写测试逻辑
方法二:使用setUp为每个测试方法创建独立用户(实例级复用)
如果希望每个测试方法执行前都生成全新的用户实例,避免测试间的状态污染,可使用setUp方法——它会在每个测试方法运行前自动执行,赋值给实例属性self:
示例代码:
from django.test import TestCase from django.contrib.auth.models import User class DoSomeTests(TestCase): def setUp(self): super().setUp() # 每个测试方法都会重新创建这些用户 self.usr1 = User.objects.create_user(username='user1', password='test123') self.usr2 = User.objects.create_user(username='user2', password='test123') self.usr3 = User.objects.create_user(username='user3', password='test123') def test_number_one(self): self.assertEqual(self.usr1.username, 'user1') # 编写测试逻辑 def test_number_two(self): self.assertEqual(self.usr2.username, 'user2') # 编写测试逻辑 def test_number_three(self): self.assertEqual(self.usr3.username, 'user3') # 编写测试逻辑
常见问题排查
- 自定义的
setup_createusers方法不会被Django测试框架自动调用,必须使用框架规定的setUp或setUpClass方法。 - 使用
setUpClass时必须添加@classmethod装饰器,方法参数为cls而非self,只有赋值给cls的属性才能被所有测试实例共享。 - 如果用
TestCase时setUpClass创建的对象在测试方法中无法访问,可改用TransactionTestCase(它不会自动管理事务,需手动清理数据)。
内容的提问来源于stack exchange,提问作者Lin
相关产品推荐
相关产品推荐

