有没有一种方法可以比较unittest
中的嵌套数据结构,但忽略具体类型的对象,例如assertSequenceEqual
但递归:
#!/usr/bin/env python
import unittest
class DeepCompareTestCase(unittest.TestCase):
def test_compare(self):
# this test fails
self.assertSequenceEqual(
[['abc', 'def']],
(('abc', 'def'),)
)
unittest.main()
(类似Perl中的Test::Deep
)
发布于 2016-03-19 03:15:12
像这样的东西可以工作吗?
import unittest
from itertools import zip_longest
class RecursiveTestCase(unittest.TestCase):
def assertSequenceDeepEqual(self, x, y):
MissingValue = MissingValueSentinel()
for x, y, in zip_longest(x, y, fillvalue=MissingValue):
try:
self.assertSequenceDeepEqual(self, x, y)
except TypeError:
self.assertEqual(x, y)
self.assertIsNot(x, MissingValue)
self.assertIsNot(y, MissingValue)
class MissingValueSentinel(object):
pass
如果一个或多个项目不是迭代器,则zip_longest
将引发TypeError
,这表明您处于递归的底部。
如果其中一个迭代器比另一个短,我让它返回一个自定义MissingValueSentinel
对象,该对象由函数末尾的assertIsNot
调用检测到。这样做的唯一原因是,如果x
或y
有一个类,无论出于什么原因,它都等同于像MissingValueSentinel
这样的即席类,但assertEqual
在该类的两个不同对象之间仍然有意义。这似乎是一种非常奇怪的边缘情况,您可以放心地忽略它。
使用zip_longest
而不是zip
可以防止[1, 2, 3]
与[1, 2]
不正确匹配。
发布于 2018-08-01 07:42:38
我遇到了与您类似的问题,但在我的例子中,我测试的是传递给API端点的数据结构。我最终做的是比较每个值的标准化JSON序列化。这不是一个通用的解决方案,因为它会在任何不能序列化为JSON的值上抛出异常,但在我的例子中,这是一个特性,而不是一个bug,它在你的例子中确实有效,所以我想我应该分享一下。
我创建了一个包含以下代码的tests/assertions.py
文件:
import json
class ApiAssertionsMixin(object):
def assertJsonEqual(self, first, second, msg=None):
j1 = json.dumps(first, sort_keys=True, indent=4)
j2 = json.dumps(second, sort_keys=True, indent=4)
self.maxDiff = None
self.assertEqual(j1, j2, msg)
在您的示例中,您将像这样使用它:
import unittest
from tests.assertions import ApiAssertionsMixin
class DeepCompareTestCase(ApiAssertionsMixin, unittest.TestCase):
def test_compare(self):
self.assertJsonEqual(
[['abc', 'def']],
(('abc', 'def'),)
)
unittest.main()
应该会过去的。下面是一个失败测试的例子:
def test_deep_compare(self):
self.assertJsonEqual(
{ 'name': 'Bob', 'aliases': ['Kate', 'Robbie'], 'age': 19 },
{ 'name': 'Bob', 'age': 20, 'aliases': ['Robbie'] }
)
输出如下所示:
.F
======================================================================
FAIL: test_deep_compare (__main__.DeepCompareTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "tests/test_nested.py", line 18, in test_deep_compare
{ 'name': 'Bob', 'age': 20, 'aliases': ['Robbie'] }
File "./tests/assertions.py", line 10, in assertJsonEqual
self.assertEqual(j1, j2, msg)
AssertionError: '{\n "age": 19,\n "aliases": [\n "Kate",\n [41 chars]"\n}' != '{\n "age": 20,\n "aliases": [\n "Robbie"\n[24 chars]"\n}'
{
- "age": 19,
? ^^
+ "age": 20,
? ^^
"aliases": [
- "Kate",
"Robbie"
],
"name": "Bob"
}
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)
正如您所看到的,在失败的情况下,您可以获得大量的上下文来找出哪里出了问题。
这种方法的一个缺点是,测试的输出是JSON而不是Python,所以如果你从输出中复制/粘贴来修复测试,你需要翻译:true
=> True
,false
=> False
,null
=> None
。
发布于 2019-01-24 23:21:13
也许deepdiff模块有帮助,但我没有测试它。
https://stackoverflow.com/questions/36092399
复制相似问题