进行接口自动化时,有时候我们需要断言的数据比较多,一个字段一个字段进行断言比较麻烦,如果可以直接断言整个响应结果,岂不美哉,那该如何实现该功能呢?
在进入正式实现前,我们先简单说一下递归。因为该功能我们主要使用递归实现,以防小伙伴们看不懂。
递归是一种算法或函数设计方法,它通过将一个问题不断分解成规模更小的子问题来解决原始问题。在 Python 中,递归是一种函数自身调用自身的过程。通过递归,程序可以在问题空间中向下深入,并通过返回值将解决子问题的结果合并起来,最终获得整个问题的解。
在 Python 中使用递归,首先需要定义边界条件,即递归的结束条件。当满足边界条件时,递归停止,返回结果。同时,还需要定义递归情况,即在未满足边界条件时,如何继续递归调用函数来解决子问题。递归函数应该能够将问题领域缩小,使其逐渐接近边界条件。
首先,递归可能会导致堆栈溢出,特别是在处理大规模问题时。其次,递归的执行效率可能较低,因为每次递归都需要保存函数调用的上下文。此外,递归需要合理设置边界条件,否则可能导致无限循环和程序崩溃。在编写递归函数时,需要仔细考虑边界条件和递归情况,确保递归能够正确结束,并得到期望的结果。同时,为了提高递归性能,可以考虑使用尾递归优化或迭代等技术。
class AssertInfo: data = [] def diff_json(response_data, assert_data): if isinstance(response_data, dict): for key in assert_data: if key not in response_data: info = f"Response data has no key: {key}" print(info) AssertInfo.data.append(info) for key in response_data: if key in assert_data: diff_json(response_data[key], assert_data[key]) else: info = f"Assert data has not key: {key}" print(info) elif isinstance(response_data, list): if len(response_data) == 0: print("response is []") if len(response_data) != len(assert_data): print(f"list len: '{len(response_data)}' != '{len(assert_data)}'") if response_data: if isinstance(response_data[0], dict): response_data = sorted(response_data, key=lambda x: x[list(response_data[0].keys())[0]]) else: response_data = sorted(response_data) if assert_data: if isinstance(assert_data[0], dict): assert_data = sorted(assert_data, key=lambda x: x[list(assert_data[0].keys())[0]]) else: assert_data = sorted(assert_data) for src_list, dst_list in zip(response_data, assert_data): diff_json(src_list, dst_list) else: if str(response_data) != str(assert_data): info = f"Value are not equal: {response_data}" print(info) AssertInfo.data.append(info)代码其实也不难理解,我们做一个简单解释:
response_data = { "name": "Alice", "age": 25, "email": "alice@example.com" } assert_data = { "name": "Alice", "email": "Alice@example.com" } diff_json(response_data, assert_data)执行之后,会打印出如下结果:
Assert data has not key: age Value are not equal: alice@example.com
完美解决!