Search code examples
jsonpython-3.xpython-unittesttrello

Validating trello board API responses in Python unittest


I am writing a unittest that queries the trello board API and want to assert that a particular card exists.

The first attempt was using the /1/boards/[board_id]/lists rewuest which gives results like:

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

I want to assert that 'item6' is indeed in the above mentioned list. Loading the json and using assertTrue, like this:

element = [item for item in json_data if item['name'] == "item6"]
self.assertTrue(element)

but I receive an error: 'TypeError: the JSON object must be str, bytes or bytearray, not 'list'.

Then discovered using the /1/boards/[board_id]/cards request gives a plain list of cards:

[
    {'id': 'id1', 'name': 'item1'},
    {'id': 'id2', 'name': 'item2'},
    ...
]

How should I write this unittest assertion?


Solution

  • The neatest option is to create a class that will equal the dict for the card you want to ensure is there, then use that in an assertion. For your example, with a list of cards returned over the api:

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

    Here's a reasonable implementation for the Card() helper class, it may look a little complex but is mostly straight forward:

    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)
    

    You could add more fields to validate as needed.

    One question worth touching on at this point is whether the unit test should be making real api queries. Generally a unit test would have test data to just focus on the function you control, but perhaps this is really an integration test for your trello deployment using the unittest module?