Python unittest __del__行为wrt模块

时间:2015-06-21 23:27:59

标签: python setuptools python-unittest

我正在编写一个Lua包装器,并在其lua_close方法中调用最高级别的抽象调用__del__。据我所知,除了setuptools测试(即常规单元测试工作,没有设置工具的单元测试)之外,每个测试通过测试。我做错了什么,或者setuptools / unittest中有错误吗?

我的setup.py:

from setuptools import setup

setup(name="PyLua",
      version="0.1",
      description="A cffi based lua package.",
      packages=['lua'],
      author="Alex Orange",
      author_email="crazycasta@gmail.com",
      license="AGPLv3",
      test_suite='test',
     )

我的lua / lua.py:

from math import sin

class Test(object):
    def __del__(self):
        print sin(1)

我的测试/ lua.py:

from __future__ import absolute_import

import unittest

def load_tests(loader, tests, pattern):
    suite = unittest.TestSuite()
    tests = loader.loadTestsFromTestCase(RealCodeTestCase)
    suite.addTests(tests)
    return suite


class RealCodeTestCase(unittest.TestCase):
    def setUp(self):
        from lua.lua import Test
        self.L = Test()

    def testCallStuff(self):
        self.assertEqual(1,1)

我的test2.py:

import unittest
import test.lua

suite = unittest.TestLoader().loadTestsFromTestCase(test.lua.RealCodeTestCase)
unittest.TextTestRunner(verbosity=2).run(suite)

python setup.py test的结果:

running test
running egg_info
writing PyLua.egg-info/PKG-INFO
writing top-level names to PyLua.egg-info/top_level.txt
writing dependency_links to PyLua.egg-info/dependency_links.txt
reading manifest file 'PyLua.egg-info/SOURCES.txt'
writing manifest file 'PyLua.egg-info/SOURCES.txt'
running build_ext
testCallStuff (test.lua.RealCodeTestCase) ... ok

----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
Exception TypeError: "'NoneType' object is not callable" in <bound method Test.__del__ of <lua.lua.Test object at 0x7fa546ccc350>> ignored

python test2.py

的结果
testCallStuff (test.lua.RealCodeTestCase) ... ok

----------------------------------------------------------------------
Ran 1 test in 0.002s

OK
0.841470984808

P.S。 Python是CPython-2.7

1 个答案:

答案 0 :(得分:2)

您可以通过在测试中提供明确的tearDown来阻止这种情况发生:

class RealCodeTestCase(unittest.TestCase):
    def setUp(self):
        from lua.lua import Test
        self.L = Test()

    def tearDown(self):
        del self.L

    def testCallStuff(self):
        self.assertEqual(1,1)

我真的不知道错误发生的原因,但由于tearDown方法可以防止错误,我猜测在幕后,setuptools实现了自己的tearDown变体,它清除了有点过多,包括导入,例如from math import sin

错误消息表明无法调用sin,因为名称存在时,它已变为None。我只能猜测这种情况发生在setuptools实现的tearDown方法中。