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

Pytest Django中AssertionError: Lists differ问题求助

API测试断言失败问题分析

问题描述

编写了一个测试API端点的测试用例,持续返回以下断言错误:

AssertionError: Lists differ: [] != [{'field_value': {'id': 1, 'panel_name': '[420 chars]: 2}]

以及

Second list contains 4 additional elements. First extra element 0: {'field_value': {'id': 1, 'panel_name': 'Clinic A', 'panel_type': 1}, 'field_type': 'clinic', 'count': 3}

疑问:出现该问题的原因是什么?这是否意味着预期内容不在返回列表中?

测试代码如下:

def test_api(self, query, expected):
        username = "jeff"
        password = "test"
        client = Client()

        response = client.post('/admin/login/', {'username': username, 'password': password})
        self.assertEqual(response.status_code, 302)

        balance_type_collection = [
            'medical',
            'dental'
        ]

        for balance_type in balance_type_collection:
            if query == '':
                query += '?'
            else:
                query += '&'

            query += 'balance_type=' + balance_type
            response = client.get('/api/v1/medical/clinicvisit/stats/'+ query)
            self.assertEqual(response.status_code, 200)
            content = json.loads(response.content)
            self.assertEqual(content, expected[balance_type])

问题原因及解答

1. 断言错误的含义

这个错误明确说明你预期返回的是空数组[],但API实际返回了包含4个元素的列表——和你想的刚好相反,不是预期内容不在返回列表里,是返回列表有内容,而你预期它是空的。

2. 代码里的核心bug

你的测试逻辑有个严重问题:循环中一直在原query变量上拼接参数,导致第二次请求的参数被污染:

  • 第一次循环(balance_type=medical):query变成?balance_type=medical,请求正常;
  • 第二次循环(balance_type=dental):query已经不是空字符串,会被拼接成?balance_type=medical&balance_type=dental,此时API处理的是两个balance_type参数(后端通常会取最后一个或合并处理),但你的expected[dental]对应的是单独传balance_type=dental的结果,自然和实际返回不匹配。

3. 修复方案

每次循环都基于原始query创建新的请求参数,别污染原变量,修改循环部分代码:

for balance_type in balance_type_collection:
    # 用原始query生成当前请求的参数,避免累加污染
    current_query = query
    if current_query == '':
        current_query += '?'
    else:
        current_query += '&'
    current_query += 'balance_type=' + balance_type
    response = client.get('/api/v1/medical/clinicvisit/stats/'+ current_query)
    self.assertEqual(response.status_code, 200)
    content = json.loads(response.content)
    self.assertEqual(content, expected[balance_type])

4. 额外检查点

  • 确认expected字典里medical和dental对应的预期值是否正确,是否和API单独返回的结果一致;
  • 测试时可以打印current_query和content,对比实际请求参数和返回值,排查是否和预期匹配。

内容的提问来源于stack exchange,提问作者Gavin Teo Juen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 13:06:17