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

Django分页测试移类后异常:分页数量不符问题排查

问题:Django分页测试用例迁移后数量异常

将Django分页测试用例从独立的PaginatorViewsTest类移至PostPagesTests类后,出现分页数量异常:

  • 创建13篇测试Post时,第二页显示4篇(预期3篇)
  • 创建12篇测试Post时,第二页显示2篇
  • 测试用例保留在独立类中则一切正常

相关代码如下:

测试代码

def test_correct_page_context_guest_client(self):
    posts = [Post(text=f'Тестовый текст {i}',
                  group=self.group0,
                  author=self.user0) for i in range(13)]
    Post.objects.bulk_create(posts)
    pages = (reverse('posts:posts_list'),
             reverse('posts:group_list',
                     kwargs={'slug': f'{self.group0.slug}'}),
             reverse('posts:profile',
                     kwargs={'username': f'{self.user0.username}'}))
    for page in pages:
        for page_number in range(2):
            with self.subTest(page=page):
                response = self.guest_client0.get(
                    page, {'page': page_number+1})
                self.assertEqual(len(response.context['page_obj']),
                                 POSTS_COUNT[page_number])

PostPagesTests类及SetUpClass代码

class PostPagesTests(TestCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.user = User.objects.create_user(username='test')
        cls.user2 = User.objects.create_user(username='test2')
        cls.user_unfollow = User.objects.create_user(username='test3')
        cls.guest_client = Client()
        cls.authorized_client = Client()
        cls.authorized_client.force_login(cls.user)
        cls.authorized_client_no_follow = Client()
        cls.authorized_client_no_follow.force_login(cls.user_unfollow)
        cls.guest_client0 = Client()
        cls.user0 = User.objects.create_user(username='auth')
        cls.group0 = Group.objects.create(title='Тестовая группа',
                                          slug='test_group')
        cls.group = Group.objects.create(
            title='test',
            slug='test',
            description='test'
        )
        cls.group2 = Group.objects.create(
            title='test2',
            slug='test2',
            description='test2'
        )
        cls.post = Post.objects.create(
            author=cls.user,
            group=cls.group,
            text='test'
        )

原因排查与解决方案

核心问题:SetUpClass中存在额外Post

PostPagesTests.setUpClass最后一行创建了一个额外的cls.post,这个Post会被计入全局的posts_list页面总数中,导致分页计算出错:

  • 测试用例创建13篇Post时,全局Post总数为13+1=14,若每页显示10篇,第二页自然会显示4篇
  • 测试用例创建12篇Post时,全局总数为12+1=13,第二页显示3篇,但你的测试用例统一用POSTS_COUNT断言,导致结果不符合预期
  • 而独立测试类中没有这个额外Post,所以分页逻辑正常

解决方案

方案1:清理测试前置数据

在测试用例开始前删除所有Post,避免前置数据干扰:

def test_correct_page_context_guest_client(self):
    # 清空所有Post,保证测试环境纯净
    Post.objects.all().delete()
    posts = [Post(text=f'Тестовый текст {i}',
                  group=self.group0,
                  author=self.user0) for i in range(13)]
    Post.objects.bulk_create(posts)
    # 后续测试代码不变

方案2:移除SetUpClass中的非必要Post

如果cls.post不是该类其他测试用例的必需数据,直接删除setUpClass中创建cls.post的代码即可。

方案3:改用setUp方法初始化数据

若cls.post是其他测试用例需要的,将setUpClass改为setUp方法,让每个测试用例执行前都重新初始化数据,避免测试间的污染:

class PostPagesTests(TestCase):
    def setUp(self):
        super().setUp()
        # 原setUpClass中的初始化代码移到这里
        self.user = User.objects.create_user(username='test')
        # ... 其余初始化代码 ...
        self.post = Post.objects.create(
            author=self.user,
            group=self.group,
            text='test'
        )

内容的提问来源于stack exchange,提问作者Fabler

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 00:30:44