在 Python 单元测试中验证 trello board API 响应
Validating trello board API responses in Python unittest
我正在编写一个查询 trello board API 的单元测试,并想断言特定的卡片存在。
第一次尝试使用 /1/boards/[board_id]/lists
rewuest,结果如下:
[{'cards': [
{'id': 'id1', 'name': 'item1'},
{'id': 'id2', 'name': 'item2'},
{'id': 'id3', 'name': 'item3'},
{'id': 'id4', 'name': 'item4'},
{'id': 'id5', 'name': 'item5'},
{'id': 'id6', 'name': 'item6'}],
'id': 'id7',
'name': 'ABC'},
{'cards': [], 'id': 'id8', 'name': 'DEF'},
{'cards': [], 'id': 'id9', 'name': 'GHI'}]
我想断言 'item6' 确实在上面提到的列表中。加载 json 并使用 assertTrue,如下所示:
element = [item for item in json_data if item['name'] == "item6"]
self.assertTrue(element)
但我收到一个错误:'TypeError: JSON 对象必须是 str、bytes 或 bytearray,而不是 'list'。
然后发现使用/1/boards/[board_id]/cards
请求给出了一个简单的卡片列表:
[
{'id': 'id1', 'name': 'item1'},
{'id': 'id2', 'name': 'item2'},
...
]
我应该如何编写这个单元测试断言?
最巧妙的选择是创建一个 class 等于您要确保存在的卡片的字典,然后在断言中使用它。对于您的示例,通过 api:
返回卡片列表
cards = board.get_cards()
self.assertIn(Card(name="item6"), cards)
下面是 Card()
帮助器 class 的合理实现,它可能看起来有点复杂,但大部分是直截了当的:
class Card(object):
"""Class that matches a dict with card details from json api response."""
def __init__(self, name):
self.name = name
def __eq__(self, other):
if isinstance(other, dict):
return other.get("name", None) == self.name
return NotImplemented
def __repr__(self):
return "{}({!r}, {!r})".format(
self.__class__.__name__, self.key, self.value)
您可以根据需要添加更多字段进行验证。
此时值得一提的一个问题是单元测试是否应该进行真正的 api 查询。通常一个单元测试会有测试数据只关注你控制的功能,但也许这真的是一个使用 unittest 模块的 trello 部署的集成测试?
import unittest
from urllib.request import urlopen
import json
class Basic(unittest.TestCase):
url = 'https://api.trello.com/1/boards/[my_id]/cards?fields=id,name,idList,url&key=[my_key]&token=[my_token]'
response = urlopen(url)
resp = response.read()
json_ob = json.loads(resp)
el_list = [item for item in json_ob if item['name'] == 'card6']
def testBasic(self):
self.assertTrue(self.el_list)
if __name__ == '__main__':
unittest.main()
所以我做错了什么:我过于关注使用以下代码后得到的列表本身:
import requests
from pprint import pprint
import json
url = "https://api.trello.com/1/boards/[my_id]/lists"
params = {"cards":"open","card_fields":"name","fields":"name","key":"[my_key]","token":"[my_token]"}
response = requests.get(url=url, params=params)
pprint(response.json())
我正在编写一个查询 trello board API 的单元测试,并想断言特定的卡片存在。
第一次尝试使用 /1/boards/[board_id]/lists
rewuest,结果如下:
[{'cards': [
{'id': 'id1', 'name': 'item1'},
{'id': 'id2', 'name': 'item2'},
{'id': 'id3', 'name': 'item3'},
{'id': 'id4', 'name': 'item4'},
{'id': 'id5', 'name': 'item5'},
{'id': 'id6', 'name': 'item6'}],
'id': 'id7',
'name': 'ABC'},
{'cards': [], 'id': 'id8', 'name': 'DEF'},
{'cards': [], 'id': 'id9', 'name': 'GHI'}]
我想断言 'item6' 确实在上面提到的列表中。加载 json 并使用 assertTrue,如下所示:
element = [item for item in json_data if item['name'] == "item6"]
self.assertTrue(element)
但我收到一个错误:'TypeError: JSON 对象必须是 str、bytes 或 bytearray,而不是 'list'。
然后发现使用/1/boards/[board_id]/cards
请求给出了一个简单的卡片列表:
[
{'id': 'id1', 'name': 'item1'},
{'id': 'id2', 'name': 'item2'},
...
]
我应该如何编写这个单元测试断言?
最巧妙的选择是创建一个 class 等于您要确保存在的卡片的字典,然后在断言中使用它。对于您的示例,通过 api:
返回卡片列表cards = board.get_cards()
self.assertIn(Card(name="item6"), cards)
下面是 Card()
帮助器 class 的合理实现,它可能看起来有点复杂,但大部分是直截了当的:
class Card(object):
"""Class that matches a dict with card details from json api response."""
def __init__(self, name):
self.name = name
def __eq__(self, other):
if isinstance(other, dict):
return other.get("name", None) == self.name
return NotImplemented
def __repr__(self):
return "{}({!r}, {!r})".format(
self.__class__.__name__, self.key, self.value)
您可以根据需要添加更多字段进行验证。
此时值得一提的一个问题是单元测试是否应该进行真正的 api 查询。通常一个单元测试会有测试数据只关注你控制的功能,但也许这真的是一个使用 unittest 模块的 trello 部署的集成测试?
import unittest
from urllib.request import urlopen
import json
class Basic(unittest.TestCase):
url = 'https://api.trello.com/1/boards/[my_id]/cards?fields=id,name,idList,url&key=[my_key]&token=[my_token]'
response = urlopen(url)
resp = response.read()
json_ob = json.loads(resp)
el_list = [item for item in json_ob if item['name'] == 'card6']
def testBasic(self):
self.assertTrue(self.el_list)
if __name__ == '__main__':
unittest.main()
所以我做错了什么:我过于关注使用以下代码后得到的列表本身:
import requests
from pprint import pprint
import json
url = "https://api.trello.com/1/boards/[my_id]/lists"
params = {"cards":"open","card_fields":"name","fields":"name","key":"[my_key]","token":"[my_token]"}
response = requests.get(url=url, params=params)
pprint(response.json())