Python UnitTest中的assertEqual应该做什么?

2024-10-01 15:47:04 发布

您现在位置:Python中文网/ 问答频道 /正文

这个问题不是上述问题的重复,我并不是要一个方法来比较实例,而是关于方法assertEqual,以及它的目的是什么。在

assertEqual(a, b)检查a == b是否返回True或False

文件上说

Test that first and second are equal. If the values do not compare equal, the test will fail.

我在一个简单的类上用assertEqual运行三个测试

考试课

class Car:
    def __init__(self, name):
        self.name = name

测试用例

^{pr2}$

结果是

F.F
======================================================================
FAIL: test_diff_equal (cartest.CarTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "cartest.py", line 10, in test_diff_equal
    self.assertEqual(car1, car2)
AssertionError: <car.Car instance at 0x7f499ec12ef0> != <car.Car instance at 0x7f499ec12f38>

======================================================================
FAIL: test_name_equal (cartest.CarTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "cartest.py", line 15, in test_name_equal
    self.assertEqual(car1, car2)
AssertionError: <car.Car instance at 0x7f499ec12fc8> != <car.Car instance at 0x7f499ec12f38>

----------------------------------------------------------------------
Ran 3 tests in 0.000s

FAILED (failures=2)

是否使用assertEqual检查两个实例是否相同?或者我的设置有什么问题吗?为什么test_name_equal()失败?在


Tags: the实例方法instancenameintestself
3条回答

整个问题可以归结为“Python如何比较对象”,这是官方文档中精确定义的。在

引用官方文件(强调我的)来澄清你所要求的方面。在

Most other objects of built-in types compare unequal unless they are the same object; the choice whether one object is considered smaller or larger than another one is made arbitrarily but consistently within one execution of a program.

这就是test_instance_equal所涵盖的内容,本质上是:

o1 = object()
o1 == o1  # will always be True

The operators <, >, ==, >=, <=, and != compare the values of two objects. The objects need not have the same type. If both are numbers, they are converted to a common type. Otherwise, objects of different types always compare unequal, and are ordered consistently but arbitrarily. You can control comparison behavior of objects of non-built-in types by defining a __cmp__ method or rich comparison methods like __gt__, described in section Special method names.*

引用特殊方法名称:

object.__lt__(self, other)
object.__le__(self, other)
object.__eq__(self, other)
object.__ne__(self, other)
object.__gt__(self, other)
object.__ge__(self, other)

New in version 2.1.

These are the so-called “rich comparison” methods, and are called for comparison operators in preference to __cmp__() below. The correspondence between operator symbols and method names is as follows: (...) x==y calls x.__eq__(y), (...)

这就是test_diff_equaltest_name_equal显示的内容。没有定义__eq__魔术方法,因此,它返回到默认实现(除非它们是同一个对象,否则它们比较不相等)。在

这个问题和单元测试模块无关。在

添加到已经说过的内容:对于给定的示例,您需要直接比较对象的属性,而不是对象本身,unittest.TestCase.assertEqual才能工作。在

class CarTest(unittest.TestCase):

    def test_diff_equal(self):
        car1 = Car('Ford')
        car2 = Car('Hyundai')
        self.assertEqual(car1.name, car2.name)

    def test_name_equal(self):
        car1 = Car('Ford')
        car2 = Car('Ford')
        self.assertEqual(car1.name, car2.name)

    def test_instance_equal(self):
        car1 = Car('Ford')
        self.assertEqual(car1.name, car1.name)

现在这应该会像预期的那样工作(并且失败)。在

你的测试运行得非常好,发现了一个bug。万岁!在

您的两个汽车对象可能具有相同的名称,但为什么这意味着它们是同一辆车?你的代码中没有任何东西能说明这一点。在

如果您希望这样,请在Car类上实现__eq__

def __eq__(self, other):
    """Return True if other is also a car and has the same name as
    this one."""

    return isinstance(other, Car) and self.name == other.name

那么这个测试应该通过了。在

相关问题 更多 >

    热门问题