Skip to content

Mark parent step as failed if child step failed with soft check (fix #827) #854

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
4 changes: 4 additions & 0 deletions allure-pytest/src/listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from allure_pytest.utils import get_status, get_status_details
from allure_pytest.utils import get_outcome_status, get_outcome_status_details
from allure_pytest.utils import get_pytest_report_status
from allure_pytest.utils import sync_steps_statuses
from allure_pytest.utils import format_allure_link
from allure_pytest.utils import get_history_id
from allure_pytest.compat import getfixturedefs
Expand Down Expand Up @@ -226,6 +227,9 @@ def pytest_runtest_makereport(self, item, call):
if test_result.status == Status.PASSED:
test_result.status = status
test_result.statusDetails = status_details
has_failed_steps = sync_steps_statuses(test_result.steps)
if has_failed_steps and not hasattr(report, "wasxfail"):
test_result.status = Status.FAILED

if report.when == 'teardown':
if status in (Status.FAILED, Status.BROKEN) and test_result.status == Status.PASSED:
Expand Down
11 changes: 11 additions & 0 deletions allure-pytest/src/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,17 @@ def get_pytest_report_status(pytest_report):
return status


def sync_steps_statuses(steps):
any_failed = False
for step in steps:
if step.steps and sync_steps_statuses(step.steps):
if step.status != Status.SKIPPED:
step.status = Status.FAILED
if step.status == Status.FAILED:
any_failed = True
return any_failed


def get_history_id(full_name, parameters, original_values):
return md5(
full_name,
Expand Down
43 changes: 43 additions & 0 deletions tests/allure_pytest/acceptance/status/base_step_status_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,49 @@ def test_pytest_fail_in_step(allure_pytest_runner: AllurePytestRunner):
)


def test_pytest_fail_in_nested_step_with_soft_check(allure_pytest_runner: AllurePytestRunner):
"""
>>> import allure
>>> from pytest_check import check as soft_check

>>> def test_pytest_fail_in_nested_step_with_soft_check():
... with allure.step("Parent step"):
... with soft_check, allure.step("Child failed step"):
... assert False
... with soft_check, allure.step("Child passed step"):
... assert True
"""
from pytest_check import check_log

allure_results = allure_pytest_runner.run_docstring()
# Prevent failed soft check checks from triggering an 'assert False'.
check_log.clear_failures()

assert_that(
allure_results,
has_test_case(
"test_pytest_fail_in_nested_step_with_soft_check",
with_status("failed"),
has_step(
"Parent step",
with_status("failed"),
has_step(
"Child failed step",
with_status("failed"),
has_status_details(
with_message_contains("AssertionError: assert False"),
with_trace_contains("test_pytest_fail_in_nested_step_with_soft_check")
)
),
has_step(
"Child passed step",
with_status("passed")
)
)
)
)


def test_pytest_bytes_data_in_assert(allure_pytest_runner: AllurePytestRunner):
"""
>>> import allure
Expand Down