gpt4 book ai didi

复杂数据结构上的python unittest.TestCase.assertEquals()

转载 作者:行者123 更新时间:2023-11-28 21:31:36 25 4
gpt4 key购买 nike

我正在对一个函数进行单元测试,该函数返回一个非常 复杂的数据结构(集合列表列表的字典等)。我手动验证了输出,现在我想确保它不会在我不注意的情况下发生变化。

现在我有:

   self.assertEquals(data,
{'Instr1': {'COUPON_LIST': '0 % SEMI 30/360',
'LEGAL_ENTITY': 'LE_XS0181523803',
'MATURITY_DATE': '2014/12/31',
'scenarios': {'Base': {'Spread Over Yield': -1.9/100,
'THEO/PV01': -1500.15,
'THEO/Value': 0.333,
'THEO/Yield': 3.3/100},
'UP': {'Spread Over Yield': -2.2/100,
'THEO/PV01': -1000.1,
'THEO/Value': 0.111,
'THEO/Yield': 5.5/100}}},
'Instr2': {'COUPON_LIST': None,
'LEGAL_ENTITY': 'LE_US059512AJ22',
'MATURITY_DATE': '2014/12/31',
'scenarios': {'Base': {'Spread Over Yield': None,
'THEO/PV01': None,
'THEO/Value': 1.0,
'THEO/Yield': 0.0},
'UP': {'Spread Over Yield': None,
'THEO/PV01': -15.15,
'THEO/Value': 4055.344,
'THEO/Yield': 4.4/100}}},
'Instr3': {'COUPON_LIST': '0 % SEMI 30/360',
'LEGAL_ENTITY': 'LE_XS0181523803',
'MATURITY_DATE': '2014/12/31',
'scenarios': {'Base': {'Spread Over Yield': -1.9/100,
'THEO/PV01': -1500.15,
'THEO/Value': 0.333,
'THEO/Yield': 3.3/100},
'UP': {'Spread Over Yield': -2.2/100,
'THEO/PV01': -1000.1,
'THEO/Value': 0.111,
'THEO/Yield': 5.5/100}}},
'Instr4': {'COUPON_LIST': None,
'LEGAL_ENTITY': 'LE_US059512AJ22',
'MATURITY_DATE': '2014/12/31',
'scenarios': {'Base': {'Spread Over Yield': None,
'THEO/PV01': None,
'THEO/Value': 1.0,
'THEO/Yield': 0.0},
'UP': {'Spread Over Yield': None,
'THEO/PV01': -15.15,
'THEO/Value': 4055.344,
'THEO/Yield': 4.4/100}}}}

我有两个问题:

  1. 测试类不稳定,数据可能会发生变化。在那种情况下,我想快速查明输出发生变化的位置,并且只验证差异。例如。我正在寻找一个不错的输出说

    数据['Instr1']['MATURITY_DATE']: '2014/12/31' != '31/12/2014'

    data['Instr5']: 在 lhs 中找不到节点

    但同时我不想手动测试结构的每个节点。

  2. 如您所见,一些元素是 float 的,并且 4.4/100 != 0.044。我需要在 float 节点上运行 AssertAlmostEqual 并在其他所有节点上运行 AssertEqual 的逻辑。

是否有任何库可以执行此操作,还是我必须自己编写?

最佳答案

快速而肮脏 的解决方案是使用 difflib 比较数据的 pretty-print 表示。然而,这个解决方案绝对稳健:

In [22]: import copy
...: import difflib
...: import pprint
...:
In [23]: data = {'Instr1': {'COUPON_LIST': '0 % SEMI 30/360',
...: 'LEGAL_ENTITY': 'LE_XS0181523803',
...: 'MATURITY_DATE': '2014/12/31',
...: 'scenarios': {'Base': {'Spread Over Yield': -1.9/100,
...: 'THEO/PV01': -1500.15,
...: 'THEO/Value': 0.333,
...: 'THEO/Yield': 3.3/100},
...: 'UP': {'Spread Over Yield': -2.2/100,
...: 'THEO/PV01': -1000.1,
...: 'THEO/Value': 0.111,
...: 'THEO/Yield': 5.5/100}}},
...: 'Instr2': {'COUPON_LIST': None,
...: 'LEGAL_ENTITY': 'LE_US059512AJ22',
...: 'MATURITY_DATE': '2014/12/31',
...: 'scenarios': {'Base': {'Spread Over Yield': None,
...: 'THEO/PV01': None,
...: 'THEO/Value': 1.0,
...: 'THEO/Yield': 0.0},
...: 'UP': {'Spread Over Yield': None,
...: 'THEO/PV01': -15.15,
...: 'THEO/Value': 4055.344,
...: 'THEO/Yield': 4.4/100}}},
...: 'Instr3': {'COUPON_LIST': '0 % SEMI 30/360',
...: 'LEGAL_ENTITY': 'LE_XS0181523803',
...: 'MATURITY_DATE': '2014/12/31',
...: 'scenarios': {'Base': {'Spread Over Yield': -1.9/100,
...: 'THEO/PV01': -1500.15,
...: 'THEO/Value': 0.333,
...: 'THEO/Yield': 3.3/100},
...: 'UP': {'Spread Over Yield': -2.2/100,
...: 'THEO/PV01': -1000.1,
...: 'THEO/Value': 0.111,
...: 'THEO/Yield': 5.5/100}}},
...: 'Instr4': {'COUPON_LIST': None,
...: 'LEGAL_ENTITY': 'LE_US059512AJ22',
...: 'MATURITY_DATE': '2014/12/31',
...: 'scenarios': {'Base': {'Spread Over Yield': None,
...: 'THEO/PV01': None,
...: 'THEO/Value': 1.0,
...: 'THEO/Yield': 0.0},
...: 'UP': {'Spread Over Yield': None,
...: 'THEO/PV01': -15.15,
...: 'THEO/Value': 4055.344,
...: 'THEO/Yield': 4.4/100}}}}

In [24]: data_repr = pprint.pformat(data)

In [25]: data2 = copy.deepcopy(data)

In [26]: data2['Instr1']['MATURITY_DATE'] = '31/12/2014'

In [27]: data2_repr = pprint.pformat(data2)

In [28]: def get_diff(a, b):
...: differ = difflib.unified_diff(a.splitlines(True), b.splitlines(True))
...: return ''.join(line for line in differ if not line.startswith(' '))

In [29]: print(get_diff(data_repr, data2_repr))
---
+++
@@ -1,6 +1,6 @@
- 'MATURITY_DATE': '2014/12/31',
+ 'MATURITY_DATE': '31/12/2014',

但是这并不能解决 float 的问题。您可以通过首先使用简单的递归函数将 floating points 值替换为 rounded 值到某个有效数字来解决这个问题。

据我所知,没有这样的库可以对比较进行这种级别的精细控制,因此如果您想要一个可靠的解决方案,最好自己编写整个代码。

我还要指出,也许您应该将此数据结构重构为结构化程度更高的类,这会使事情变得更容易。

最后但同样重要的是:您可以使用 unittestaddTypeEqualityFunc确保 TestCase 在比较 float 时调用 assertAlmostEqual,而不是手动执行。


现在我想到了,您可以使用 addTypeEqualityFunc 执行自定义比较 dict,这可以添加更多关于不匹配的信息。要找到 所有 不匹配项,您必须使用一些 except AssertionError as e: block 到您的自定义函数中,始终检查所有子元素,然后“加入”错误消息不知何故。但我不认为解决方案会如此干净。

关于复杂数据结构上的python unittest.TestCase.assertEquals(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19315640/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com