在 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())