Python 如何实现不完全字典比较的 helper

醋精测试媛 · 2020年12月09日 · 最后由 泰斯特 回复于 2020年12月16日 · 1988 次阅读

在测试中存在只需要比较对象/字典某些字段的情况,如有的对象或者字典生成时,会有 createtime 字段,创建的时间是无法知道的,因此应该忽略这个字段,对其他字段进行比较,这个 helper 如何实现呢?

现在的情况:

unittest 的 assertDictEqual 用于比较

使用 dict.pop(key) 将忽略的字段删除,但是希望这个功能更加具有通用性。

共收到 11 条回复 时间 点赞

做个过滤函数,过滤掉指定参数,生成新对象,这种可以使用装饰器来做。

比较就是比较,用另一个函数来做。不涉及过滤。

Jacky 回复
def assertDictEqual(self, d1, d2, msg=None, ignore_keys=None):
    if ignore_keys is None:
        super(BaseCase, self).assertDictEqual(d1, d2, msg)
    else:
        d1_filtered = dict((k, v) for k, v in d1.items() if k not in ignore_keys)
        d2_filtered = dict((k, v) for k, v in d2.items() if k not in ignore_keys)
        super(BaseCase, self).assertDictEqual(d1_filtered, d2_filtered, msg)

这样子可以吗

你这样这个用例比较时 pop 后,别的用例比较时还是需要 pop。

jsonschema,指定 required

如果这个功能常用,可以考虑把它封装起来,做成适用于各种数据结构的函数。

因为过滤和比较不是一个事情,在 assertDictEqual 直接用代码写死过滤,不是特别好的选择

我觉得你思路反了,不应该预先给定一个忽略值,而是最终返回一个不同值的列表,这样对于后续处理是显性的。

Karaser 回复

请问是返回不同值的列表是什么意思呢?我没有听很懂,不好意思,可以具体讲讲吗? @tester6636865 @Thirty-Thirty

返回值里有 10 个 (30 个) 字段,需要显性地给出需要验证的 8 个 (28 个) 字段。而不是忽略不需要的 2 个字段,这样思路就反了。

比较后产生发现的不同值的字段

dict_a = {'id': 1, 'createAt': 2}

ignore_keys = {'createAt'}

new_dict_a = {key: a[key] for key in a.keys() - ignore_keys}

print(new_dict_a) # {'id': 1}

可以利用这种方式将字典中不需要被比较的值去掉

Thirty-Thirty 接口测试脚本自动生成 中提及了此贴 09月01日 12:29
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册