【问题标题】:what is assertEqual in Python UnitTest supposed to do?Python UnitTest 中的 assertEqual 应该做什么?
【发布时间】:2016-04-16 04:15:10
【问题描述】:

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

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

文档说,

测试第一个和第二个是否相等。如果值不比较 相等,测试将失败。

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

正在测试的课程

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

测试用例

class CarTest(unittest.TestCase):

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

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

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

结果是

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() 失败了?

【问题讨论】:

  • @Rogalski,不,不要挖掘旧帖子。它是专门关于 assertEqual 的。
  • 这与比较对象如何实现相等运算符密切相关(您知道,因为您已经引用了说明的文档)。
  • @Rogalski 这个问题是关于内置单元测试模块及其提供的方法assertEquals,提到的问题是关于比较两个实例。这些问题有什么关系?这个问题是关于 UNITTEST.ASSERTEQUAL ::
  • @Rivadiz:不完全是,您的测试失败是因为您没有实现__eq__ 方法。

标签: python unit-testing assert


【解决方案1】:

您的测试运行良好,但发现了一个错误。万岁!

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

如果您希望如此,请在 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

那么测试应该通过了。

【讨论】:

  • 感谢您的回答,但是assertEqual 应该做什么?
  • @Rivadiz 如果两个项目不相等,它将引发AssertionError。如果是,它会默默地过去。
  • 那么为什么test_name_equal() 失败了?
  • 因为car1car2 相等。它们是两个不同的对象。如果您希望它们被视为平等,则需要按照此答案的建议实现 __eq__ 特殊方法。
  • @Rivadiz:它失败了,因为在test_name_equalcar1car2不相等。它们是两个独立的对象。它们碰巧有一个相等的属性 (name),但这并不意味着它们相等。
【解决方案2】:

整个问题可以简化为“Python 如何比较对象”,这在官方文档的Section 5.9: Comparisons 中精确定义。

引用官方文档(强调我的)以澄清您所要求的方面。

大多数其他内置类型的对象比较不相等,除非它们是 同一个对象;一个对象是否被认为更小的选择 或大于另一个是任意的,但始终在 一个程序的一次执行。

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

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

运算符 、==、>=、您可以控制对象的比较行为 通过定义 __cmp__ 方法或丰富的比较来实现非内置类型 像 __gt__ 这样的方法,在 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)

2.1 版中的新功能。

这些是所谓的“丰富的比较”方法,需要 比较运算符优先于下面的__cmp__()。这 运算符符号和方法名称之间的对应关系为 如下:(...) x==y calls x.__eq__(y), (...)

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

问题与单元测试模块无关。

【讨论】:

    【解决方案3】:

    补充已经说过的内容:对于给出的示例,您需要直接比较对象的属性,而不是对象本身,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)
    

    现在应该可以按预期工作(并且失败)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-23
      • 1970-01-01
      • 2017-08-05
      • 2011-11-20
      • 2018-09-05
      • 2015-09-17
      • 1970-01-01
      相关资源
      最近更新 更多