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

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测试框架的额外逻辑,引发异常。

修复步骤

  1. 确保父类初始化逻辑执行
    如果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')
    
  2. 重构登录逻辑为非测试方法
    不要直接调用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')
    
  3. 可选:直接在父类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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 06:03:16