使用Pytest与pytest-django时出现断言错误求助
Django序列化器Pytest测试断言错误排查
我花了30分钟处理这个问题,现在求助。用Pytest和pytest-django测试Django序列化器时,出现断言错误:
E AssertionError: assert {} == {'rant': 'Kulugo', 'slug': 'apostrophe'} E Right contains 2 more items: E {'rant': 'Kulugo', 'slug': 'apostrophe'} E Full diff: E - {'rant': 'Kulugo', 'slug': 'apostrophe'} E + {} tests/rants/test_serializers.py:26: AssertionError
错误来自第26行的assert serializer.data == invalid_serializer_data。另外test_valid_rant_serializer也断言失败,提示title和categories是必填字段。代码基于testdriven.io教程编写,预期所有测试通过。
完整测试代码如下:
from main.serializers import RantSerializer, CategorySerializer def test_valid_rant_serializer(): valid_serializer_data = { 'id': 1, 'title': "First Rant", 'slug': "first-rant", } serializer = RantSerializer(data=valid_serializer_data) assert serializer.is_valid() assert serializer.validated_data == valid_serializer_data assert serializer.data == valid_serializer_data assert serializer.errors == {} def test_invalid_rant_serializer(): invalid_serializer_data = { 'rant': 'Kulugo', 'slug': 'apostrophe' } serializer = RantSerializer(data=invalid_serializer_data) assert not serializer.is_valid() assert serializer.validated_data == {} assert serializer.data == invalid_serializer_data assert serializer.errors == {"id": ["This field is required"]}
问题原因及修复方案
1. test_valid_rant_serializer失败修复
测试用例存在两个问题:
id是Django模型的只读主键字段,序列化器不会将其作为可输入字段,传入data参数无效- 缺少
title和categories必填字段(错误提示已明确说明)
修改后的测试代码:
def test_valid_rant_serializer(): valid_serializer_data = { 'title': "First Rant", 'slug': "first-rant", 'categories': [1] # 需确保测试环境存在ID为1的分类,或用工厂类生成测试数据 } serializer = RantSerializer(data=valid_serializer_data) assert serializer.is_valid() # 避免直接断言完整字典,针对性检查核心字段即可(序列化器可能处理字段格式) assert serializer.validated_data['title'] == valid_serializer_data['title'] assert serializer.validated_data['slug'] == valid_serializer_data['slug'] assert serializer.errors == {}
2. test_invalid_rant_serializer失败修复
- 序列化器验证失败时,
serializer.data不会返回原始传入数据,而是返回经过验证后的合法字段(此处验证全失败,所以返回空字典),因此assert serializer.data == invalid_serializer_data不成立 - 实际错误字段是
title和categories,不是id,原断言错误
修改后的测试代码:
def test_invalid_rant_serializer(): invalid_serializer_data = { 'rant': 'Kulugo', 'slug': 'apostrophe' } serializer = RantSerializer(data=invalid_serializer_data) assert not serializer.is_valid() assert serializer.validated_data == {} # 移除错误的data断言,改为检查实际错误字段 assert 'title' in serializer.errors assert 'categories' in serializer.errors
额外建议
- 测试序列化器时,不要直接断言
serializer.data或validated_data与传入字典完全相等,序列化器可能会自动处理字段格式(如日期、外键)或忽略只读字段 - 对于关联字段(如
categories),建议用factory_boy等工厂类生成测试数据,避免硬编码ID导致测试不稳定
内容的提问来源于stack exchange,提问作者Vicente Antonio G. Reyes
相关产品推荐
相关产品推荐

