Skip to content

Destructor not executed after execution of a single test #105

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
buster3 opened this issue Nov 25, 2015 · 3 comments
Closed

Destructor not executed after execution of a single test #105

buster3 opened this issue Nov 25, 2015 · 3 comments

Comments

@buster3
Copy link

buster3 commented Nov 25, 2015

Running a test with the xml test runner differs from running a test with the default text runner. In the default setup after each test local objects are deleted. With the xml test runner the destructors are called after test completion. It is important to rise an assertionError in the test to get this error.

import xmlrunner
import unittest

class dummy(object):
    def __init__(self, inst):
        self.inst = inst
        print("ctro, inst %s"%inst)

    def __del__(self):
        print("dtro, inst %s"%self.inst)

class test_spuCfgParser(unittest.TestCase):

    def test_foo(self):
        print("test_foo")
        dummyInst = dummy("foo")
        raise AssertionError("SomeError")


    def test_foofoo(self):
        print("test_foofoo")
        dummyInst = dummy("foofoo")
        raise AssertionError("SomeError")


if __name__ == '__main__':
    #unittest.main()

    unittest.main(testRunner=xmlrunner.XMLTestRunner(output='test-reports'), failfast=False, buffer=False, catchbreak=False)

Output with unittest.main():

test_foo
ctro, inst foo
Fdtro, inst foo
test_foofoo
ctro, inst foofoo
Fdtro, inst foofoo

Output with xmlrunner:

Running tests...
----------------------------------------------------------------------
FF
======================================================================
FAIL [0.000s]: test_foo (__main__.test_spuCfgParser)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "debugxmlrunner.py", line 17, in test_foo
    raise AssertionError("SomeError")
AssertionError: SomeError

Stdout:
test_foo
ctro, inst foo

======================================================================
FAIL [0.000s]: test_foofoo (__main__.test_spuCfgParser)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "debugxmlrunner.py", line 23, in test_foofoo
    raise AssertionError("SomeError")
AssertionError: SomeError

Stdout:
test_foofoo
ctro, inst foofoo

----------------------------------------------------------------------
Ran 2 tests in 0.000s

FAILED (failures=2)

Generating XML reports...
dtro, inst foofoo
dtro, inst foo
@dnozay
Copy link
Member

dnozay commented Nov 25, 2015

I don't think this is a bug. There is no documented behavior that one implementation should prevail. If you have important resources that need to be cleaned up; that's what the unittest.TestCase.tearDown method is about.

@buster3
Copy link
Author

buster3 commented Nov 25, 2015

Thanks for your comment. But lets add e.g. a static instance count to to dummy object

import xmlrunner
import unittest

class dummy(object):
    count = 0
    def __init__(self, inst):
        self.inst = inst
        dummy.count += 1
        print("ctro, inst %s, count %d"%(inst, dummy.count))

    def __del__(self):
        dummy.count -= 1
        print("dtro, inst %s, count %d"%(self.inst, dummy.count))

class test_spuCfgParser(unittest.TestCase):

    def test_foo(self):
        print("test_foo")
        dummyInst = dummy("foo")
        raise AssertionError("SomeError")


    def test_foofoo(self):
        print("test_foofoo")
        dummyInst = dummy("foofoo")
        raise AssertionError("SomeError")


if __name__ == '__main__':
    #unittest.main()

    unittest.main(testRunner=xmlrunner.XMLTestRunner(output='test-reports'), failfast=False, buffer=False, catchbreak=False)

output:

Running tests...
----------------------------------------------------------------------
FF
======================================================================
FAIL [0.000s]: test_foo (__main__.test_spuCfgParser)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./debugxmlrunner.py", line 20, in test_foo
    raise AssertionError("SomeError")
AssertionError: SomeError

Stdout:
test_foo
ctro, inst foo, count 1

======================================================================
FAIL [0.000s]: test_foofoo (__main__.test_spuCfgParser)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./debugxmlrunner.py", line 26, in test_foofoo
    raise AssertionError("SomeError")
AssertionError: SomeError

Stdout:
test_foofoo
ctro, inst foofoo, count 2

----------------------------------------------------------------------
Ran 2 tests in 0.000s

FAILED (failures=2)

Generating XML reports...
dtro, inst foofoo, count 1
dtro, inst foo, count 0

I definitely do not expect that there is an instance of dummy saved somewhere in the background. Therefore this is a bug to me.

@dnozay
Copy link
Member

dnozay commented Dec 2, 2015

https://docs.python.org/2/reference/datamodel.html#object.__del__

This is not a bug; the traceback is holding references to local variables. You can either use del in a try/finally or do your cleanup in a tearDown.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants