【问题标题】:Validating trello board API responses in Python unittest在 Python unittest 中验证 trello board API 响应
【发布时间】:2017-10-05 04:31:56
【问题描述】:

我正在编写一个查询trello board API 的单元测试,并希望断言特定卡存在。

第一次尝试是使用/1/boards/[board_id]/listsrewuest,结果如下:

[{'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'},
    ...
]

我应该如何编写这个 unittest 断言?

【问题讨论】:

  • my_list 已经是 Python 列表,不需要 json.loads()。 Json.loads() 仅适用于 JSON 序列化字符串。试试:element = [item for item in my_list[0]['items'] if item['name'] == "item6"]

标签: json python-3.x python-unittest trello


【解决方案1】:

最好的选择是创建一个类,该类将等于您要确保存在的卡片的字典,然后在断言中使用它。对于您的示例,使用通过 api 返回的卡片列表:

cards = board.get_cards()
self.assertIn(Card(name="item6"), cards)

这是Card() 辅助类的一个合理实现,它可能看起来有点复杂,但大部分都是直截了当的:

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 部署进行的集成测试?

【讨论】:

  • 谢谢,虽然我不得不说我只是一个初学者,我对你的代码还不太了解(比如 return "{}({!r}, {!r} )".format(self.__class__.__name__, self.key, self.value)。我也设法自己解决了这个问题。:) 我对这个列表太执着了,我忘记了我可以更容易地做到这一点。
  • 是在猜测您的问题,所以我的答案可能比您需要的更通用,知道它的 trello board api 有帮助。有关格式字符串的含义,请参阅str.format() docs - 该方法使对象在传递给repr() 时具有合理的输出。
【解决方案2】:
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())

【讨论】:

    猜你喜欢
    • 2017-11-11
    • 2017-06-24
    • 2021-03-01
    • 1970-01-01
    • 2013-07-23
    • 1970-01-01
    • 2015-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多