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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 03:22:56