Merge branch 'pytest-dev:main' into okken_12231_xfail_tb
This commit is contained in:
commit
8551173751
1
AUTHORS
1
AUTHORS
|
@ -36,6 +36,7 @@ Andrey Paramonov
|
||||||
Andrzej Klajnert
|
Andrzej Klajnert
|
||||||
Andrzej Ostrowski
|
Andrzej Ostrowski
|
||||||
Andy Freeland
|
Andy Freeland
|
||||||
|
Anita Hammer
|
||||||
Anthon van der Neut
|
Anthon van der Neut
|
||||||
Anthony Shaw
|
Anthony Shaw
|
||||||
Anthony Sottile
|
Anthony Sottile
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Fix reporting of teardown errors in higher-scoped fixtures when using `--maxfail` or `--stepwise`.
|
||||||
|
|
||||||
|
Originally added in pytest 8.0.0, but reverted in 8.0.2 due to a regression in pytest-xdist.
|
||||||
|
This regression was fixed in pytest-xdist 3.6.1.
|
|
@ -0,0 +1 @@
|
||||||
|
Keyboard interrupts and system exits are now properly handled during the test collection.
|
|
@ -134,6 +134,10 @@ def runtestprotocol(
|
||||||
show_test_item(item)
|
show_test_item(item)
|
||||||
if not item.config.getoption("setuponly", False):
|
if not item.config.getoption("setuponly", False):
|
||||||
reports.append(call_and_report(item, "call", log))
|
reports.append(call_and_report(item, "call", log))
|
||||||
|
# If the session is about to fail or stop, teardown everything - this is
|
||||||
|
# necessary to correctly report fixture teardown errors (see #11706)
|
||||||
|
if item.session.shouldfail or item.session.shouldstop:
|
||||||
|
nextitem = None
|
||||||
reports.append(call_and_report(item, "teardown", log, nextitem=nextitem))
|
reports.append(call_and_report(item, "teardown", log, nextitem=nextitem))
|
||||||
# After all teardown hooks have been called
|
# After all teardown hooks have been called
|
||||||
# want funcargs and request info to go away.
|
# want funcargs and request info to go away.
|
||||||
|
@ -389,7 +393,9 @@ def pytest_make_collect_report(collector: Collector) -> CollectReport:
|
||||||
|
|
||||||
return list(collector.collect())
|
return list(collector.collect())
|
||||||
|
|
||||||
call = CallInfo.from_call(collect, "collect")
|
call = CallInfo.from_call(
|
||||||
|
collect, "collect", reraise=(KeyboardInterrupt, SystemExit)
|
||||||
|
)
|
||||||
longrepr: Union[None, Tuple[str, int, str], str, TerminalRepr] = None
|
longrepr: Union[None, Tuple[str, int, str], str, TerminalRepr] = None
|
||||||
if not call.excinfo:
|
if not call.excinfo:
|
||||||
outcome: Literal["passed", "skipped", "failed"] = "passed"
|
outcome: Literal["passed", "skipped", "failed"] = "passed"
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
anyio[curio,trio]==4.3.0
|
anyio[curio,trio]==4.3.0
|
||||||
django==5.0.4
|
django==5.0.4
|
||||||
pytest-asyncio==0.23.6
|
pytest-asyncio==0.23.6
|
||||||
# Temporarily not installed until pytest-bdd is fixed:
|
pytest-bdd==7.1.2
|
||||||
# https://github.com/pytest-dev/pytest/pull/11785
|
|
||||||
# pytest-bdd==7.0.1
|
|
||||||
pytest-cov==5.0.0
|
pytest-cov==5.0.0
|
||||||
pytest-django==4.8.0
|
pytest-django==4.8.0
|
||||||
pytest-flakes==4.0.5
|
pytest-flakes==4.0.5
|
||||||
|
|
|
@ -7,6 +7,7 @@ import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import textwrap
|
import textwrap
|
||||||
from typing import List
|
from typing import List
|
||||||
|
from typing import Type
|
||||||
|
|
||||||
from _pytest.assertion.util import running_on_ci
|
from _pytest.assertion.util import running_on_ci
|
||||||
from _pytest.config import ExitCode
|
from _pytest.config import ExitCode
|
||||||
|
@ -1856,3 +1857,33 @@ def test_do_not_collect_symlink_siblings(
|
||||||
# Ensure we collect it only once if we pass the symlinked directory.
|
# Ensure we collect it only once if we pass the symlinked directory.
|
||||||
result = pytester.runpytest(symlink_path, "-sv")
|
result = pytester.runpytest(symlink_path, "-sv")
|
||||||
result.assert_outcomes(passed=1)
|
result.assert_outcomes(passed=1)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"exception_class, msg",
|
||||||
|
[
|
||||||
|
(KeyboardInterrupt, "*!!! KeyboardInterrupt !!!*"),
|
||||||
|
(SystemExit, "INTERNALERROR> SystemExit"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_respect_system_exceptions(
|
||||||
|
pytester: Pytester,
|
||||||
|
exception_class: Type[BaseException],
|
||||||
|
msg: str,
|
||||||
|
):
|
||||||
|
head = "Before exception"
|
||||||
|
tail = "After exception"
|
||||||
|
ensure_file(pytester.path / "test_eggs.py").write_text(
|
||||||
|
f"print('{head}')", encoding="UTF-8"
|
||||||
|
)
|
||||||
|
ensure_file(pytester.path / "test_ham.py").write_text(
|
||||||
|
f"raise {exception_class.__name__}()", encoding="UTF-8"
|
||||||
|
)
|
||||||
|
ensure_file(pytester.path / "test_spam.py").write_text(
|
||||||
|
f"print('{tail}')", encoding="UTF-8"
|
||||||
|
)
|
||||||
|
|
||||||
|
result = pytester.runpytest_subprocess("-s")
|
||||||
|
result.stdout.fnmatch_lines([f"*{head}*"])
|
||||||
|
result.stdout.fnmatch_lines([msg])
|
||||||
|
result.stdout.no_fnmatch_line(f"*{tail}*")
|
||||||
|
|
|
@ -1216,3 +1216,53 @@ def test_pytest_version_env_var(pytester: Pytester, monkeypatch: MonkeyPatch) ->
|
||||||
result = pytester.runpytest_inprocess()
|
result = pytester.runpytest_inprocess()
|
||||||
assert result.ret == ExitCode.OK
|
assert result.ret == ExitCode.OK
|
||||||
assert os.environ["PYTEST_VERSION"] == "old version"
|
assert os.environ["PYTEST_VERSION"] == "old version"
|
||||||
|
|
||||||
|
|
||||||
|
def test_teardown_session_failed(pytester: Pytester) -> None:
|
||||||
|
"""Test that higher-scoped fixture teardowns run in the context of the last
|
||||||
|
item after the test session bails early due to --maxfail.
|
||||||
|
|
||||||
|
Regression test for #11706.
|
||||||
|
"""
|
||||||
|
pytester.makepyfile(
|
||||||
|
"""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def baz():
|
||||||
|
yield
|
||||||
|
pytest.fail("This is a failing teardown")
|
||||||
|
|
||||||
|
def test_foo(baz):
|
||||||
|
pytest.fail("This is a failing test")
|
||||||
|
|
||||||
|
def test_bar(): pass
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
result = pytester.runpytest("--maxfail=1")
|
||||||
|
result.assert_outcomes(failed=1, errors=1)
|
||||||
|
|
||||||
|
|
||||||
|
def test_teardown_session_stopped(pytester: Pytester) -> None:
|
||||||
|
"""Test that higher-scoped fixture teardowns run in the context of the last
|
||||||
|
item after the test session bails early due to --stepwise.
|
||||||
|
|
||||||
|
Regression test for #11706.
|
||||||
|
"""
|
||||||
|
pytester.makepyfile(
|
||||||
|
"""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def baz():
|
||||||
|
yield
|
||||||
|
pytest.fail("This is a failing teardown")
|
||||||
|
|
||||||
|
def test_foo(baz):
|
||||||
|
pytest.fail("This is a failing test")
|
||||||
|
|
||||||
|
def test_bar(): pass
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
result = pytester.runpytest("--stepwise")
|
||||||
|
result.assert_outcomes(failed=1, errors=1)
|
||||||
|
|
4
tox.ini
4
tox.ini
|
@ -134,11 +134,9 @@ changedir = testing/plugins_integration
|
||||||
deps = -rtesting/plugins_integration/requirements.txt
|
deps = -rtesting/plugins_integration/requirements.txt
|
||||||
setenv =
|
setenv =
|
||||||
PYTHONPATH=.
|
PYTHONPATH=.
|
||||||
# Command temporarily removed until pytest-bdd is fixed:
|
|
||||||
# https://github.com/pytest-dev/pytest/pull/11785
|
|
||||||
# pytest bdd_wallet.py
|
|
||||||
commands =
|
commands =
|
||||||
pip check
|
pip check
|
||||||
|
pytest bdd_wallet.py
|
||||||
pytest --cov=. simple_integration.py
|
pytest --cov=. simple_integration.py
|
||||||
pytest --ds=django_settings simple_integration.py
|
pytest --ds=django_settings simple_integration.py
|
||||||
pytest --html=simple.html simple_integration.py
|
pytest --html=simple.html simple_integration.py
|
||||||
|
|
Loading…
Reference in New Issue