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

如何使用pytest-snapshot处理不可排序的List[Dict]快照测试

解决pytest-snapshot中无序List[Dict]的快照断言问题

方法一:自定义序列化逻辑(推荐)

pytest-snapshot支持自定义数据序列化规则,能让无序的List[Dict]在生成/对比快照前自动转为有序结构,彻底规避顺序影响。

先写一个归一化函数,把List[Dict]转成有序的可序列化格式:

def normalize_unordered_list(data):
    # 仅处理List[Dict]类型的数据
    if isinstance(data, list) and all(isinstance(item, dict) for item in data):
        # 把每个字典按键排序转为元组,再对整个列表排序
        return sorted(tuple(sorted(item.items())) for item in data)
    # 其他类型保持原样
    return data

然后在测试中指定这个序列化函数:

def test_some_function(snapshot):
    my_unsortable_list = my_function()
    # 用自定义序列化器生成/对比快照,快照会保存归一化后的有序数据
    snapshot.assert_match(
        my_unsortable_list,
        "my_snapshot",  # 快照文件名前缀,可自定义
        serializer=normalize_unordered_list
    )

如果想让所有测试的List[Dict]都自动归一化,可在项目根目录的pytest.ini中配置全局序列化器:

[pytest]
snapshot_serializer = 你的模块名.normalize_unordered_list

方法二:提前归一化数据再存快照

不想修改全局配置或序列化逻辑的话,可以在测试里先把数据转换成不依赖顺序的结构:

  • 若元素唯一,可转成集合(自动忽略顺序):
import json

def test_some_function(snapshot):
    my_unsortable_list = my_function()
    # 把每个字典转为排序键的JSON字符串,再转成集合
    normalized_set = {
        json.dumps(item, sort_keys=True, indent=2) for item in my_unsortable_list
    }
    snapshot.assert_match(normalized_set, "my_snapshot")
  • 若存在重复元素,改成排序后的列表:
normalized_list = sorted(
    json.dumps(item, sort_keys=True, indent=2) for item in my_unsortable_list
)
snapshot.assert_match(normalized_list, "my_snapshot")

方法三:自定义对比器

部分版本的pytest-snapshot支持comparator参数,直接自定义数据对比逻辑:

def compare_unordered_lists(a, b):
    if len(a) != len(b):
        return False
    # 归一化两个列表后再对比
    sorted_a = sorted(tuple(sorted(item.items())) for item in a)
    sorted_b = sorted(tuple(sorted(item.items())) for item in b)
    return sorted_a == sorted_b

def test_some_function(snapshot):
    my_unsortable_list = my_function()
    snapshot.assert_match(
        my_unsortable_list,
        "my_snapshot",
        comparator=compare_unordered_lists
    )

另外你之前的代码失效,大概率是因为列表存在重复元素——比如快照里有两个相同的字典,但结果里只有一个,此时len相等但重复次数不一致,而归一化排序的方式能解决这类问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 23:05:24