3

我正在尝试使用 python 的unittest库来编写一些单元测试。我有一个返回无序列表对象的函数。我想验证对象是否相同,并且我正在尝试使用assertCountEqual来执行此操作。

然而,这似乎失败了,尽管各个对象==彼此相等 ( )。这是断言失败的“差异”输出:

First has 1, Second has 0:  Intersection(time=8.033252939677466e-08, del_time=8.033252939677466e-08, pos=Vector(10.00, 0.00), line=Line(Vector(500.00, 0.00), Vector(0.00, 0.00)), ent=None, oth=None, invalid=False)
First has 1, Second has 0:  Intersection(time=-9.918729244820295e-16, del_time=-9.918729244820295e-16, pos=Vector(10.00, 0.00), line=Line(Vector(500.00, 0.00), Vector(0.00, 0.00)), ent=None, oth=None, invalid=False)
First has 0, Second has 1:  Intersection(time=8.033252939677466e-08, del_time=8.033252939677466e-08, pos=Vector(10.00, 0.00), line=Line(Vector(500.00, 0.00), Vector(0.00, 0.00)), ent=None, oth=None, invalid=False)
First has 0, Second has 1:  Intersection(time=-9.918729244820295e-16, del_time=-9.918729244820295e-16, pos=Vector(10.00, 0.00), line=Line(Vector(500.00, 0.00), Vector(0.00, 0.00)), ent=None, oth=None, invalid=False)

验证它们是否相等:

>>> i = Intersection(time=8.033252939677466e-08, del_time=8.033252939677466e-08, pos=Vector(10.00, 0.00), line=Line(Vector(500.00, 0.00), Vector(0.00, 0.00)), ent=None, oth=None, invalid=False)
>>> j = Intersection(time=8.033252939677466e-08, del_time=8.033252939677466e-08, pos=Vector(10.00, 0.00), line=Line(Vector(500.00, 0.00), Vector(0.00, 0.00)), ent=None, oth=None, invalid=False)
>>> i == j
True
>>> i = Intersection(time=-9.918729244820295e-16, del_time=-9.918729244820295e-16, pos=Vector(10.00, 0.00), line=Line(Vector(500.00, 0.00), Vector(0.00, 0.00)), ent=None, oth=None, invalid=False)
>>> j = Intersection(time=-9.918729244820295e-16, del_time=-9.918729244820295e-16, pos=Vector(10.00, 0.00), line=Line(Vector(500.00, 0.00), Vector(0.00, 0.00)), ent=None, oth=None, invalid=False)
>>> i == j
True

我的猜测是该assertCountEqual函数正在检查两者是否具有相同的身份(例如i is j),而不是相等。

  • 是否有一个 unittest 函数可以提供相同的差异功能,但使用相等比较,而不是身份?
  • 或者,有什么方法可以编写一个类似于的函数assertCountEqual

编辑:我正在运行 python 3.2.2。

4

3 回答 3

4

您可以自己寻找比较是如何完成的

由于您的 s 是对象,因此默认情况下Intersection它们是可散列的,但是如果您不提供合适的散列函数(如果您提供比较方法,则应该这样做),它们将被视为不同。

那么,您的Intersection班级是否履行了哈希合同?

于 2012-05-04T21:10:51.313 回答
1

使用无序列表时,我通常使用这种模式(如果可以的话)

在扩展 TestCase 的类中

self.assertTrue(set(a) == set(b), 'The lists are not equal.')

set在这种情况下使用它是因为它允许比较无序组但是如果 a 有两个相同的对象,则比较应该失败,但在这种情况下您不需要对两个列表进行排序然后进行比较。

我尽量远离,is除非比较它,None因为它依赖于这样的实例

这是一个例子

In [2]: a = [0,1,2]

In [3]: b = [0,2,1,0]

In [4]: set(a) == set(b)
Out[4]: True

In [5]: c = [2,0,1]

In [6]: a.sort() == c.sort()
Out[6]: True

对于更复杂的对象或类,您可能想尝试类似

self.assertTrue(a==b)

或者您可以编写自己的比较方法

def compare_complex(*args): 
  for attr in ...
    if getattr(args[0],attr) != getattr(args[1],attr): return False
  return True

我过去在分析两个使用属性存储重要值的类或 Numpy 实例时使用过类似的东西

于 2012-05-04T20:41:26.470 回答
1

assertCountEqual()collections.Counter如果您的元素是可散列的,则使用。在 Python 3 中,如果您的类定义了自己的类__eq__,则默认__hash__会被禁止。

你有你自己的__eq__——定义一个__hash__(它必须在相等的地方__eq__相等),你应该没问题。

于 2012-05-04T22:03:14.647 回答