【问题标题】:How to test assert whether two lists of dictionaries (where a dict item contains a list) are the same如何测试断言两个字典列表(其中一个字典项目包含一个列表)是否相同
【发布时间】:2020-03-13 16:28:05
【问题描述】:

我正在创建我的第一个测试脚本(耶!)我有一个字典列表,其中一个键是一个列表。如果列表(在字典中)按任何顺序排列,我希望通过测试。我知道您可以使用assertCountEqual 来检查列表是否相等,而不管顺序如何,但是您可以对包含列表字典的列表执行此操作吗?见下例

会成功

def test(self):
    output = [2,1]
    desired_output = [1,2]
    self.assertCountEqual(output, desired_output)

会失败

def test(self):
    desired_output = [{'count': 2, 'columns': ['col2', 'col5']}]
    output = [{'count': 2, 'columns': ['col5', 'col2']}]
    self.assertCountEqual(output, desired_output)

谢谢

【问题讨论】:

  • 您需要在字典中使用列表吗?如果顺序不重要,为什么不换成套呢?
  • 您可以尝试对每个列表进行排序。每当你有很多差异时——无论是否在单元测试中——排序总是需要考虑的。 @dspencer - 重复项会在一组中丢失,导致错误相等。
  • 很好的电话@dspencer。我不需要使用列表。套装也适合我

标签: python python-3.x unit-testing python-unittest


【解决方案1】:

assertCountEqual(first, second, msg=None):

测试第一个序列是否包含与第二个相同的元素, 不管他们的顺序如何。如果他们不这样做,则会列出错误消息 将产生序列之间的差异。

重要:

调用assertCountEqual(first, second, msg=None)等同于调用assertEqual(Counter(list(first)), Counter(list(second)))

注意:

Counter 是一个 dict 子类,用于计算可散列对象。它是一个集合,其中元素存储为字典键,它们的计数存储为字典值。 为此,密钥必须是hashable,但不幸的是dictunhashable,因为它是可变的。


为了执行所需的任务,您可以使用frozensetfrozenset 构建了唯一元素的不可变无序集合。 为了使测试成功,您必须构建一个与其键对应的值是不可变的字典。我们可以使用递归的方法来构建一个包含不可变值的字典。

试试这个(更新):

def getHashableDict(dictionary):
    hashable_dict = {}
    for key, value in dictionary.items():
        if isinstance(value, list):
            hashable_dict[key] = frozenset(value)
        elif isinstance(value, dict):
            hashable_dict[key] = getHashableDict(value)
        else:
            hashable_dict[key] = value

    return frozenset(hashable_dict.items())

def test(self):
    desired_output = [{'count': 2, 'columns': ['col2', 'col5']}]
    output = [{'count': 2, 'columns': ['col5', 'col2']}]

    output = [getHashableDict(item) for item in output] #--> create list of hashable types
    desired_output = [getHashableDict(item) for item in desired_output]

    self.assertCountEqual(output, desired_output)

现在测试会成功。

【讨论】:

  • 在现代(CPython/PyPy 为 3.6+,语言保证为 3.7)dicts 默认为插入顺序; Counter 继承了这种行为,所以它不像你说的那样无序;键按在计数时首次出现的时间排序。
  • 聪明! @dspencer 指出,在这种情况下,集合同样可以很好地工作。至少在我使用它时确实如此。但是,这也解决了这个问题,我学到了一些东西。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-23
  • 2018-01-25
  • 1970-01-01
  • 2021-02-05
  • 1970-01-01
相关资源
最近更新 更多