如何在Python中正确测试析构函数?

时间:2019-04-11 10:23:23

标签: python testing destructor

我想测试是否调用了Python对象的析构函数并可以正常工作,即它不会引发任何错误,也不会返回错误的退出代码。

我被困在编写单元测试中,因为似乎单元测试在删除对象之前就完成了。 我没有设法强制在测试返回之前删除该对象,并且由于以下两个原因,我不能在测试中直接调用__del__

  • 那不是我正在测试的东西

  • 这实际上导致对象被破坏两次,在我的情况下,析构函数释放了一些内存,因此在两次调用时会产生分段错误。

为了说明这一点,我创建了一个玩具示例,其中有两个对象。第一个MyWrongObject包含析构函数中的错误,第二个MyCorrectObject是正确的。 我已经为每个对象编写了测试。一个应该成功,而另一个应该失败。

import unittest
import gc


class MyWrongObject(object):
    def __init__(self):
        self.del_calls = 0

    def __del__(self):
        if self.del_calls:
            # Something really bad can happen here like a segmentation fault
            # because we may free some memory twice
            raise AssertionError("Already destroyed")
        self.del_calls += 1

        # Simulate an error
        raise ValueError("Error while destroying the object")


class MyCorrectObject(object):
    def __init__(self):
        self.del_calls = 0

    def __del__(self):
        if self.del_calls:
            # Something really bad can happen here like a segmentation fault
            # because we may free some memory twice
            raise AssertionError("Already destroyed")
        self.del_calls += 1

        # No error here


class TestDestructor(unittest.TestCase):
    def test_my_correct_object_should_destroy_itself(self):
        # Given
        my_object = MyCorrectObject()

        # When / Then
        del my_object
        gc.collect()

    # This test should fail
    def test_my_wrong_object_should_destroy_itself(self):
        # Given
        my_object = MyWrongObject()

        # When / Then
        del my_object
        gc.collect()

在当前状态下,两项测试均成功,第二项测试在标准输出中打印ValueError

python -m unittest snips_nlu.tests.test_destructor.TestDestructor                                                                                                     1 ↵
.Exception ignored in: <bound method MyWrongObject.__del__ of <snips_nlu.tests.test_destructor.MyWrongObject object at 0x1118bbda0>>
Traceback (most recent call last):
  File "/Users/adrien/dev/snips-nlu/snips_nlu/tests/test_destructor.py", line 17, in __del__
    raise ValueError("Error while destroying the object")
ValueError: Error while destroying the object
.
----------------------------------------------------------------------
Ran 2 tests in 0.044s

OK

我无法以一致的方式编写这些测试(两者都使用相同的代码),并且第一遍通过而第二遍失败(标准输出中没有任何AssertionError)。 / p>

感谢您的帮助!

0 个答案:

没有答案