Django中跨应用导入用户测试模块的登录功能失败问题
问题
为避免代码重复,尝试将users/tests模块中的登录功能导入到ordering/tests中,用于测试带@login_required装饰器的视图。
users/tests.py代码如下:
User = get_user_model() class UserBaseTest(TestCase): def setUp(self): self.user = User.objects.create_user( username='testuser', password='testpass', email='test@gmail.com', phone_number='3401234567' ) def test_login(self): logged_in = self.client.login(username='testuser', password='testpass') self.assertTrue(logged_in, "Login failed in UserBaseTest")
ordering/tests.py代码如下:
class OrderTest(UserBaseTest): def test_view(self): self.test_login() response = self.client.get(reverse('homepage'), follow=True) self.assertRedirects(response, self.order_url) self.assertTemplateUsed(response, 'ordering/ordering.html')
执行py manage.py test users无错误,但执行py manage.py test ordering时出现错误:
self.assertTrue(logged_in, "Login failed in UserBaseTest") AssertionError: False is not true : Login failed in UserBaseTest
请问该如何解决这个跨应用测试导入后登录失败的问题?
解决方案
核心原因
跨应用继承测试类时,父类UserBaseTest的setUp方法未被正确执行,导致测试用户未创建,登录自然失败。另外直接调用以test_开头的测试方法,也可能触发Django测试框架的额外逻辑,引发异常。
修复步骤
确保父类初始化逻辑执行
如果OrderTest有自定义setUp方法,必须先调用父类的setUp来创建测试用户;如果没有自定义setUp,也要确认导入路径正确:# ordering/tests.py from django.test import TestCase from django.urls import reverse from users.tests import UserBaseTest class OrderTest(UserBaseTest): def setUp(self): super().setUp() # 强制执行父类setUp,创建测试用户 self.order_url = reverse('order-page') # 补充订单页URL定义 def test_view(self): self.test_login() response = self.client.get(reverse('homepage'), follow=True) self.assertRedirects(response, self.order_url) self.assertTemplateUsed(response, 'ordering/ordering.html')重构登录逻辑为非测试方法
不要直接调用test_前缀的测试方法,将登录逻辑封装成普通方法:# users/tests.py User = get_user_model() class UserBaseTest(TestCase): def setUp(self): self.user = User.objects.create_user( username='testuser', password='testpass', email='test@gmail.com', phone_number='3401234567' ) # 用非test_前缀的方法封装登录逻辑 def login_test_user(self): logged_in = self.client.login(username='testuser', password='testpass') self.assertTrue(logged_in, "Login failed in UserBaseTest")然后在
OrderTest中调用这个封装方法:def test_view(self): self.login_test_user() response = self.client.get(reverse('homepage'), follow=True) self.assertRedirects(response, self.order_url) self.assertTemplateUsed(response, 'ordering/ordering.html')可选:直接在父类setUp中完成登录
如果所有继承UserBaseTest的测试都需要登录,可以直接在父类setUp中完成登录,省去子类调用步骤:# users/tests.py class UserBaseTest(TestCase): def setUp(self): self.user = User.objects.create_user(...) # 直接在初始化时完成登录 self.client.login(username='testuser', password='testpass')
内容的提问来源于stack exchange,提问作者M4rc0txt
相关产品推荐
相关产品推荐

