pytest icon indicating copy to clipboard operation
pytest copied to clipboard

Pytest does not show addClassCleanup errors

Open LukasJerabek opened this issue 1 year ago • 1 comments

  • [x] a detailed description of the bug or problem you are having Below in minimal example is a code that if I run with python, I get
Running test one
.E
======================================================================
ERROR: tearDownClass (__main__.SomeTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "tst.py", line 11, in clean_up_class
    raise AttributeError
AttributeError

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

FAILED (errors=1)

which is fine, but if I run it with pytest I get:

==================================================================================== test session starts =====================================================================================
platform linux -- Python 3.8.18, pytest-7.4.3, pluggy-1.3.0
rootdir: /home/vagrant
collected 1 item                                                                                                                                                                             

tst.py .                                                                                                                                                                               [100%]

===================================================================================== 1 passed in 0.01s ======================================================================================

Without any sign of that an error has happend. Therefore it fail silently without anyone knowing something wrong happend.

Expected: Pytest shows error as well.

  • [x] output of pip list from the virtual environment you are using
Package        Version
-------------- -------
exceptiongroup 1.2.0
iniconfig      2.0.0
packaging      23.2
pip            23.3.2
pluggy         1.3.0
pytest         7.4.3
setuptools     56.0.0
tomli          2.0.1

  • [x] pytest and operating system versions pytest 7.4.3 Centos7

  • [x] minimal example if possible

import unittest


class SomeTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.addClassCleanup(cls.clean_up_class)
        
    @classmethod
    def clean_up_class(cls):
        raise AttributeError

    def test_one(self):
        print("Running test one")
        self.assertTrue(True)

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

LukasJerabek avatar Dec 20 '23 16:12 LukasJerabek

@bluetech hi, may I ask how is this going? I think it is rather inconvenient not being able to see certain errors.

LukasJerabek avatar Jan 17 '24 12:01 LukasJerabek

This workaround can be dropped in a plugin module or conftest.py

import pytest


@pytest.hookimpl
def pytest_configure():
    patch_unittest_TestCase_doClassCleanup()


def patch_unittest_TestCase_doClassCleanup():
    """Raise/print errors caught during class cleanup

    pytest ignores `TestCase.tearDown_exceptions`, which causes them to
    pass silently.
    """

    @classmethod
    def doClassCleanupAndRaiseLastError(cls):
        doClassCleanups()
        errors = cls.tearDown_exceptions
        if errors:
            if len(errors) > 1:
                num = len(errors)
                for n, (exc_type, exc, tb) in enumerate(errors[:-1], start=1):
                    print(f"\nclass cleanup error ({n} of {num}):", file=sys.stderr)
                    print_exception(exc_type, exc, tb)
            raise errors[-1][1]

    import sys
    from traceback import print_exception
    from unittest.case import TestCase
    doClassCleanups = TestCase.doClassCleanups
    TestCase.doClassCleanups = doClassCleanupAndRaiseLastError

millerdev avatar Apr 26 '24 12:04 millerdev