比较Python中get请求的预期json响应与实际json响应

比较Python中get请求的预期json响应与实际json响应,python,json,Python,Json,当您访问此站点时,会收到一个小的json响应 我把回答保存在一个变量中。我还将响应放在另一个变量expected中。两个响应都是相同的。我正在更改值以测试失败的案例。最终目标是比较2并确保它们匹配 我有两个函数,一个比较两个字典的键和值,另一个函数对字典进行排序。代码如下: import json import requests response = requests.get('https://reqres.in/api/users/2') #actual_response saves th

当您访问此站点时,会收到一个小的json响应

我把回答保存在一个变量中。我还将响应放在另一个变量expected中。两个响应都是相同的。我正在更改值以测试失败的案例。最终目标是比较2并确保它们匹配

我有两个函数,一个比较两个字典的键和值,另一个函数对字典进行排序。代码如下:

import json
import requests


response = requests.get('https://reqres.in/api/users/2')
#actual_response saves the json as we get it from url above
actual_response= json.loads(response.text)

#expected response is saved after using pretty json that will be used to testing/comparing actual vs expected
expected_response={
    "data": {
        "id": 2,
        "first_name": "Janet",
        "last_name": "Weaver",
        "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"
    }
}

# sort the key values before comparing
def dict_sort(dictA,dictB):
    dictA, dictB = json.dumps(dictA, sort_keys=True), json.dumps(dictB, sort_keys=True)
    dictA == dictB

#if there are any failure due to mismatch in key value the function below will show that
def key_diff(dictA,dictB):
    for key,value in dictA.items():
        for keyB,valueB in dictB.items():
            for k,v in value.items():
                for k2,v2 in valueB.items():
                    if(key!= keyB):
                        print('Expected',key,' but got',keyB)
                    if(k!=k2):
                        print('Expected', k, ' but got', k2)
                    if(v!=v2):
                        print('Expected', v, ' but got', v2)
                    else:
                        print()

dict_sort(actual_response,expected_response)

if(actual_response==expected_response):
    print('Passed')
else:
    print('Failed')
    key_diff(actual_response,expected_response)
问题:测试在没有差异的情况下通过。但是,如果有任何差异,顺序就会变得疯狂。下面是一个示例,我在预期响应中将数据更改为dat: 预期数据,但得到数据

预期id,但得到姓氏

预计2,但得到了韦弗

排序函数是否应该更具体,而不是使用sort_keys=True?顺便说一下,我考虑了**args,但我认为在这种情况下,这不是一个好的选择


感谢您的专家意见和时间。

在3.7下的Python版本中不保证密钥顺序;需要创建记住键顺序的对象时,应使用


在Python 3.7中,插入顺序是保留的,因此您的密钥将始终匹配。

在3.7下的Python版本中,密钥顺序不受保证;需要创建记住键顺序的对象时,应使用


在Python 3.7中,插入顺序是保留的,因此您的键将始终匹配。

我建议使用unittest,并避免使用太多嵌套for循环

from unittest import TestCase

import pandas as pd
import requests


def mocked_server_response():
    expected = {"data": {"id": 2, "first_name": "Janet", "last_name": "Weaver",
                         "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"}}
    data = expected['data']
    df = pd.DataFrame(my_dict['data'], index=[0])
    return [expected, data, df]


此时,模拟的\u服务器\u响应将为您提供以下信息:

Out[27]:
   id first_name last_name                                             avatar
0   2      Janet    Weaver  https://s3.amazonaws.com/uifaces/faces/twitter...
现在,您可以轻松地在类中进行测试


class TestServerResponse(TestCase):
    real_response = requests.get('https://reqres.in/api/users/2')

    def setUp(self):
        self.actual_response = real_response

    def response(self):
        self.assertEqual(self.actual_response, mocked_server_response()[0])

    def test_data_in_response(self):
        self.assertEqual(self.actual_response['data'], mocked_server_response()[1])

    def test_dataframe(self):
        self.assertEqual(pd.DataFrame(self.actual_response['data'], index=[0]), mocked_server_response()[2])





我建议使用unittest,避免使用太多嵌套for循环

from unittest import TestCase

import pandas as pd
import requests


def mocked_server_response():
    expected = {"data": {"id": 2, "first_name": "Janet", "last_name": "Weaver",
                         "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"}}
    data = expected['data']
    df = pd.DataFrame(my_dict['data'], index=[0])
    return [expected, data, df]


此时,模拟的\u服务器\u响应将为您提供以下信息:

Out[27]:
   id first_name last_name                                             avatar
0   2      Janet    Weaver  https://s3.amazonaws.com/uifaces/faces/twitter...
现在,您可以轻松地在类中进行测试


class TestServerResponse(TestCase):
    real_response = requests.get('https://reqres.in/api/users/2')

    def setUp(self):
        self.actual_response = real_response

    def response(self):
        self.assertEqual(self.actual_response, mocked_server_response()[0])

    def test_data_in_response(self):
        self.assertEqual(self.actual_response['data'], mocked_server_response()[1])

    def test_dataframe(self):
        self.assertEqual(pd.DataFrame(self.actual_response['data'], index=[0]), mocked_server_response()[2])





你的字典似乎什么也没做。即使使用相同的名称变量,也不能通过将输入参数指定给不同的变量来改变输入参数。您不必序列化为json进行比较。有关dict比较的示例,请参阅。此外,如果更改,它们将是字符串。@Selcuk,谢谢。这是一个关于比较的论坛!。这有助于解决我的问题。你的字典似乎什么都没做。即使使用相同的名称变量,也不能通过将输入参数指定给不同的变量来改变输入参数。您不必序列化为json进行比较。有关dict比较的示例,请参阅。此外,如果更改,它们将是字符串。@Selcuk,谢谢。这是一个关于比较的论坛!。这有助于解决我的问题。虽然这段代码可能会回答这个问题,但是你能考虑为你解决的问题增加一些解释,以及你是如何解决的?这将有助于未来读者更好地理解你的答案并从中学习。虽然这段代码可能会回答这个问题,但是你能考虑为你解决的问题增加一些解释,以及你是如何解决的?这将帮助未来的读者更好地理解你的答案并从中学习。