Skip to content
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

Pytest crash when exception is raised in fixture teardown and --exitfirst flag is set #9266

Closed
oleg-kondaurov opened this issue Nov 4, 2021 Discussed in #9213 · 1 comment
Labels
topic: config related to config handling, argument parsing and config file topic: fixtures anything involving fixtures directly or indirectly type: bug problem that needs to be addressed

Comments

@oleg-kondaurov
Copy link

Discussed in #9213

Originally posted by oleg-kondaurov October 18, 2021

When error is raised in fixture teardown, --exitfirst flag is set, and some additional test is still not started => Pytest crash is observed instead of a report.

Use the following tests/test2.py file to reproduce the issue:

import pytest


class TestT:
    @pytest.fixture(scope='class')
    def fix1(self):
        print('setup 1')
        yield
        print('teardown 1')
        raise Exception('test 1 teardown exception')

    @pytest.fixture(scope='function')
    def fix2(self):
        print('setup 2')
        yield
        print('teardown 2')
        raise Exception('test 2 teardown exception')

    def test1(self, fix1, fix2):
        print('test 1')

    def test2(self):
        print('test 2')

If the --etixfirst flag is not set the test run returns test report with 2 passed, 2 errors, short test summary info and failed tests traces:

 $ py.test tests/test2.py  -s 
======================================================================================================================================================================== test session starts ========================================================================================================================================================================
platform linux -- Python 3.8.10, pytest-6.2.5, py-1.10.0, pluggy-0.13.1
rootdir: /home/okondaurov/GitHub/kyiv-qa-tests, configfile: pytest.ini
plugins: metadata-1.11.0, cov-3.0.0, mock-3.6.1, html-3.1.1, dependency-0.5.1
collected 2 items                                                                                                                                                                                                                                                                                                                                                   

tests/test2.py setup 1
setup 2
test 1
.teardown 2
Etest 2
.teardown 1
E

============================================================================================================================================================================== ERRORS ===============================================================================================================================================================================
_________________________________________________________________________________________________________________________________________________________________ ERROR at teardown of TestT.test1 __________________________________________________________________________________________________________________________________________________________________

self = <tests.test2.TestT object at 0x7f060d412460>

    @pytest.fixture(scope='function')
    def fix2(self):
        print('setup 2')
        yield
        print('teardown 2')
>       raise Exception('test 2 teardown exception')
E       Exception: test 2 teardown exception

tests/test2.py:17: Exception
_________________________________________________________________________________________________________________________________________________________________ ERROR at teardown of TestT.test2 __________________________________________________________________________________________________________________________________________________________________

self = <tests.test2.TestT object at 0x7f060d3f9fd0>

    @pytest.fixture(scope='class')
    def fix1(self):
        print('setup 1')
        yield
        print('teardown 1')
>       raise Exception('test 1 teardown exception')
E       Exception: test 1 teardown exception

tests/test2.py:10: Exception
====================================================================================================================================================================== short test summary info ======================================================================================================================================================================
ERROR tests/test2.py::TestT::test1 - Exception: test 2 teardown exception
ERROR tests/test2.py::TestT::test2 - Exception: test 1 teardown exception
==================================================================================================================================================================== 2 passed, 2 errors in 0.06s ====================================================================================================================================================================

If the --etixfirst flag is set pytest is crashed due to unhandled exception:

$ py.test tests/test2.py  -s --exitfirst
======================================================================================================================================================================== test session starts ========================================================================================================================================================================
platform linux -- Python 3.8.10, pytest-6.2.5, py-1.10.0, pluggy-0.13.1
rootdir: /home/okondaurov/GitHub/kyiv-qa-tests, configfile: pytest.ini
plugins: metadata-1.11.0, cov-3.0.0, mock-3.6.1, html-3.1.1, dependency-0.5.1
collected 2 items                                                                                                                                                                                                                                                                                                                                                   

tests/test2.py setup 1
setup 2
test 1
.teardown 2
Eteardown 1
Traceback (most recent call last):
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/bin/py.test", line 8, in <module>
    sys.exit(console_main())
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/_pytest/config/__init__.py", line 185, in console_main
    code = main()
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/_pytest/config/__init__.py", line 162, in main
    ret: Union[ExitCode, int] = config.hook.pytest_cmdline_main(
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/pluggy/hooks.py", line 286, in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/pluggy/manager.py", line 93, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/pluggy/manager.py", line 84, in <lambda>
    self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/pluggy/callers.py", line 208, in _multicall
    return outcome.get_result()
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/pluggy/callers.py", line 80, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/pluggy/callers.py", line 187, in _multicall
    res = hook_impl.function(*args)
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/_pytest/main.py", line 316, in pytest_cmdline_main
    return wrap_session(config, _main)
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/_pytest/main.py", line 304, in wrap_session
    config.hook.pytest_sessionfinish(
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/pluggy/hooks.py", line 286, in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/pluggy/manager.py", line 93, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/pluggy/manager.py", line 84, in <lambda>
    self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/pluggy/callers.py", line 203, in _multicall
    gen.send(outcome)
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/_pytest/terminal.py", line 803, in pytest_sessionfinish
    outcome.get_result()
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/pluggy/callers.py", line 80, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/pluggy/callers.py", line 187, in _multicall
    res = hook_impl.function(*args)
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/_pytest/runner.py", line 103, in pytest_sessionfinish
    session._setupstate.teardown_all()
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/_pytest/runner.py", line 412, in teardown_all
    self._pop_and_teardown()
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/_pytest/runner.py", line 387, in _pop_and_teardown
    self._teardown_with_finalization(colitem)
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/_pytest/runner.py", line 405, in _teardown_with_finalization
    self._callfinalizers(colitem)
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/_pytest/runner.py", line 402, in _callfinalizers
    raise exc
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/_pytest/runner.py", line 395, in _callfinalizers
    fin()
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/_pytest/fixtures.py", line 1034, in finish
    raise exc
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/_pytest/fixtures.py", line 1027, in finish
    func()
  File "/home/okondaurov/GitHub/kyiv-qa-tests/venv/lib/python3.8/site-packages/_pytest/fixtures.py", line 941, in _teardown_yield_fixture
    next(it)
  File "/home/okondaurov/GitHub/kyiv-qa-tests/tests/test2.py", line 10, in fix1
    raise Exception('test 1 teardown exception')
Exception: test 1 teardown exception
@Zac-HD Zac-HD added topic: config related to config handling, argument parsing and config file topic: fixtures anything involving fixtures directly or indirectly type: bug problem that needs to be addressed labels Nov 10, 2021
@bluetech
Copy link
Member

bluetech commented Jan 4, 2024

This is fixed by #11721 I believe, will be part of pytest 8.0.0.

@bluetech bluetech closed this as completed Jan 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: config related to config handling, argument parsing and config file topic: fixtures anything involving fixtures directly or indirectly type: bug problem that needs to be addressed
Projects
None yet
Development

No branches or pull requests

3 participants