Compare expected vs actual json response for a get request in Python
当您访问此站点https://reqres.in/api/users/2时,会得到一个小的JSON响应。
我将响应保存在一个变量中(实际)。我还将响应放入了另一个变量(预期的)。两个响应都是相同的。我正在更改值以测试失败的案例。最终目标是比较2并确保它们匹配。
我有两个函数,一个比较两个字典的键和值,另一个函数对字典进行排序。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | 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?顺便说一下,我考虑过**参数,但我认为在这种情况下,这不是一个好的选择。
感谢您的专家意见和时间。
我建议使用UnitTest并避免使用如此多的嵌套for循环
1 2 3 4 5 6 7 8 9 10 11 12 | 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] |
此时,
1 2 3 | Out[27]: id first_name last_name avatar 0 2 Janet Weaver https://s3.amazonaws.com/uifaces/faces/twitter... |
号
现在,您可以轻松地在一个类中进行测试。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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]) |
在3.7下的Python版本中,不能保证键顺序;当需要创建记住键顺序的对象时,应该使用collections.ordereddict。
在Python3.7中,插入顺序是保留的,因此您的键将始终匹配。