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

fix --maxfail and --exitfirst pytest args and show skip reason in the robot log #289

Merged
merged 3 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion pytest_robotframework/_internal/pytest/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
TempPathFactory,
TestReport,
hookimpl,
skip,
version_tuple as pytest_version,
)
from robot.api import logger
Expand Down Expand Up @@ -350,7 +351,7 @@ def _robot_run_tests(session: Session, xdist_item: Item | None = None):
"listener": listeners,
},
)
# if item_context is not set then it's being run from pytest_runtest_protocol instead of
# if xdist_item is not set then it's being run from pytest_runtest_protocol instead of
# pytest_runtestloop so we don't need to re-implement pytest_runtest_protocol
if xdist_item:
robot_options = merge_robot_options(
Expand Down Expand Up @@ -577,6 +578,16 @@ def pytest_collect_file(parent: Collector, file_path: Path) -> Collector | None:

@hookimpl(wrapper=True)
def pytest_runtest_setup(item: Item) -> HookWrapperResult:
should_fail = item.session.shouldfail
if should_fail:
# this is usually handled in `pytest_runtestloop`, but since we replace it we need to
# re-implement it here. ideally it would just stop the execution entirely instead of
# skipping to match what pytest does by default, but we still want to generate a robot log
skip(
"shouldfail was set to `True`, skipping the rest of the tests"
if isinstance(should_fail, bool)
else should_fail
)
if not isinstance(item, RobotItem):
# `set_variables` and `import_resource` is only supported in python files.
# when running robot files, suite variables should be set using the `*** Variables ***`
Expand Down
12 changes: 5 additions & 7 deletions pytest_robotframework/_internal/robot/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,11 @@ def _call_and_report_robot_edition(
if report.skipped:
# empty string means xfail with no reason, None means it was not an xfail
xfail_reason = report.wasxfail if hasattr(report, "wasxfail") else None
BuiltIn().skip(
# TODO: is there a reliable way to get the reason when skipped by a skip/skipif marker?
# https://github.com/DetachHead/pytest-robotframework/issues/51
""
if xfail_reason is None
else ("xfail" + (f": {xfail_reason}" if xfail_reason else ""))
)
if xfail_reason is None:
skip_reason = report.longrepr[2] if isinstance(report.longrepr, tuple) else ""
else:
skip_reason = "xfail" + (f": {xfail_reason}" if xfail_reason else "")
BuiltIn().skip(skip_reason)
elif report.failed:
# make robot show the exception:
exception = item.stash.get(exception_key, None)
Expand Down
8 changes: 8 additions & 0 deletions tests/fixtures/test_python/test_exitfirst.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from __future__ import annotations


def test_foo():
raise Exception


def test_bar(): ...
12 changes: 12 additions & 0 deletions tests/fixtures/test_python/test_maxfail.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from __future__ import annotations


def test_foo():
raise Exception


def test_bar():
raise Exception


def test_baz(): ...
21 changes: 19 additions & 2 deletions tests/test_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from typing import TYPE_CHECKING, List, cast

from _pytest.assertion.util import running_on_ci
from pytest import ExitCode, MonkeyPatch
from pytest import ExitCode, MonkeyPatch, skip

from pytest_robotframework._internal.robot.utils import robot_6
from tests.conftest import (
Expand Down Expand Up @@ -36,7 +36,8 @@ def test_one_test_skipped(pr: PytestRobotTester):
pr.run_and_assert_result(skipped=1)
pr.assert_log_file_exists()
assert output_xml().xpath(
"./suite//test[@name='test_one_test_skipped']/kw[@type='SETUP']/msg[@level='SKIP']"
"./suite//test[@name='test_one_test_skipped']/kw[@type='SETUP']/msg[@level='SKIP' and "
+ ".='Skipped: foo']"
)


Expand Down Expand Up @@ -942,3 +943,19 @@ def test_console_output(pr: PytestRobotTester):
assert f"Output: {pr.pytester.path / 'output.xml'}" in result.outlines
else:
assert "Output: output.xml" in result.outlines


def test_exitfirst(pr: PytestRobotTester):
if pr.xdist:
skip(
"--exitfirst doesn't work with xdist. https://github.com/pytest-dev/pytest-xdist/issues/420"
)
pr.run_and_assert_result("-x", failed=1, skipped=1)


def test_maxfail(pr: PytestRobotTester):
if pr.xdist:
skip(
"--maxfail doesn't work with xdist. https://github.com/pytest-dev/pytest-xdist/issues/868"
)
pr.run_and_assert_result("--maxfail=2", failed=2, skipped=1)
Loading