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

理解不稳定的Django测试:实例创建顺序影响序列化返回数组顺序

顺序异常的原因
  • Django 多对多关联关系默认不保证返回数据的顺序:你在创建Client时传入agents=[agent1, agent2],仅代表插入关联记录的顺序,但是默认查询多对多关联数据时,数据库没有固定的排序规则,返回顺序会受数据库查询执行计划、数据存储分布、环境负载等因素影响。本地环境刚好返回顺序符合预期,CI 环境出现差异是正常现象,和--parallel并行参数没有直接关系。
  • 如果你的序列化器没有显式指定agents的排序逻辑,序列化输出的数组顺序完全依赖数据库返回的 QuerySet 顺序,自然会出现偶发乱序的问题。
更健壮的实现方案

方案1:序列化层固定排序(适合业务要求返回顺序固定的场景)

直接在序列化器中给关联的agents字段指定排序规则,保证无论数据库返回顺序如何,序列化输出的顺序都是固定的,示例如下:

# 在WebhookClientSerializer中定义agents字段时指定排序
agents = AgentSerializer(
    many=True, 
    # 可根据业务需求选择排序字段,比如id、创建时间、邮箱等
    queryset=AgentUser.objects.order_by("email")
)

方案2:测试层调整断言逻辑(适合业务不要求返回顺序的场景)

测试时不要依赖数组的索引顺序,改用集合校验元素完整性,或者先排序再断言,修改后的测试代码示例:

class WebhookClientSerializerTestCase(TestCase):
    def test_serializes_agent_from_client(self):
        agent1 = factories.AgentUserFactory(email='dave@agently.com')
        agent2 = factories.AgentUserFactory(email='jim@agently.com')
        client = factories.ClientFactory(agents=[agent1, agent2])
        schema = serializers.WebhookClientSerializer()
        data = schema.dump(client).data
        
        # 方式1:用集合校验返回的邮箱完整,不关心顺序
        returned_emails = {item['email'] for item in data['agents']}
        self.assertEqual(returned_emails, {'dave@agently.com', 'jim@agently.com'})
        
        # 方式2:先排序再断言,避免依赖原始返回顺序
        sorted_emails = sorted(item['email'] for item in data['agents'])
        self.assertEqual(sorted_emails, ['dave@agently.com', 'jim@agently.com'])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 01:45:03