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

Add logs, stdout and stderr to the allure-pytest-bdd report #801

Merged
merged 4 commits into from
Mar 25, 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
8 changes: 7 additions & 1 deletion allure-pytest-bdd/src/pytest_bdd_listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from allure_commons.model2 import Label
from allure_commons.model2 import Status

from allure_commons.types import LabelType
from allure_commons.types import LabelType, AttachmentType
from allure_commons.utils import platform_label
from allure_commons.utils import host_tag, thread_tag
from allure_commons.utils import md5
Expand Down Expand Up @@ -114,6 +114,12 @@ def pytest_runtest_makereport(self, item, call):
if test_result.status == Status.PASSED and status != Status.PASSED:
test_result.status = status
test_result.statusDetails = status_details
if report.caplog:
self.attach_data(report.caplog, "log", AttachmentType.TEXT, None)
if report.capstdout:
self.attach_data(report.capstdout, "stdout", AttachmentType.TEXT, None)
if report.capstderr:
self.attach_data(report.capstderr, "stderr", AttachmentType.TEXT, None)

if report.when == 'teardown':
self.lifecycle.write_test_case(uuid=uuid)
Expand Down
Empty file.
155 changes: 155 additions & 0 deletions tests/allure_pytest_bdd/acceptance/capture/capture_attach_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import pytest
from hamcrest import assert_that, empty
from hamcrest import all_of, is_, is_not
from hamcrest import has_property, has_value
from hamcrest import contains_string
from tests.allure_pytest.pytest_runner import AllurePytestRunner


@pytest.mark.parametrize("capture", ["sys", "fd", "no"])
def test_capture_stdout_in_bdd(allure_pytest_bdd_runner: AllurePytestRunner, capture):
feature_content = (
"""
Feature: Basic allure-pytest-bdd usage
Scenario: Simple passed example
Given the preconditions are satisfied
When the action is invoked
Then the postconditions are held
"""
)
steps_content = (
"""
from pytest_bdd import scenario, given, when, then
@scenario("scenario.feature", "Simple passed example")
def test_scenario_passes():
pass

@given("the preconditions are satisfied")
def given_the_preconditions_are_satisfied():
print("Print from given step")

@when("the action is invoked")
def when_the_action_is_invoked():
print("Print from when step")

@then("the postconditions are held")
def then_the_postconditions_are_held():
print("Print from then step")
"""
)

allure_results = allure_pytest_bdd_runner.run_pytest(
("scenario.feature", feature_content),
steps_content, cli_args=(f"--capture={capture}",)
)
if_pytest_capture_ = is_not if capture == "no" else is_

assert_that(
allure_results,
has_property(
"attachments",
all_of(
if_pytest_capture_(has_value(contains_string("Print from given step"))),
if_pytest_capture_(has_value(contains_string("Print from when step"))),
if_pytest_capture_(has_value(contains_string("Print from then step")))
)
)
)


@pytest.mark.parametrize("capture", ["sys", "fd"])
def test_capture_empty_stdout(allure_pytest_bdd_runner: AllurePytestRunner, capture):
feature_content = (
"""
Feature: Basic allure-pytest-bdd usage
Scenario: Simple passed example
Given the preconditions are satisfied
When the action is invoked
Then the postconditions are held
"""
)
steps_content = (
"""
from pytest_bdd import scenario, given, when, then
@scenario("scenario.feature", "Simple passed example")
def test_scenario_passes():
pass

@given("the preconditions are satisfied")
def given_the_preconditions_are_satisfied():
pass

@when("the action is invoked")
def when_the_action_is_invoked():
pass

@then("the postconditions are held")
def then_the_postconditions_are_held():
pass
"""
)

allure_results = allure_pytest_bdd_runner.run_pytest(
("scenario.feature", feature_content),
steps_content, cli_args=(f"--capture={capture}",)
)

assert_that(
allure_results,
has_property("attachments", empty())
)


@pytest.mark.parametrize("logging", [True, False])
def test_capture_log(allure_pytest_bdd_runner: AllurePytestRunner, logging):
feature_content = (
"""
Feature: Basic allure-pytest-bdd usage
Scenario: Simple passed example
Given the preconditions are satisfied
When the action is invoked
Then the postconditions are held
"""
)
steps_content = (
"""
import logging
from pytest_bdd import scenario, given, when, then
logger = logging.getLogger(__name__)
@scenario("scenario.feature", "Simple passed example")
def test_scenario_passes():
pass

@given("the preconditions are satisfied")
def given_the_preconditions_are_satisfied():
logging.info("Logging from given step")

@when("the action is invoked")
def when_the_action_is_invoked():
logging.info("Logging from when step")

@then("the postconditions are held")
def then_the_postconditions_are_held():
logging.info("Logging from then step")
"""
)

params = [] if logging else ["-p", "no:logging"]
allure_results = allure_pytest_bdd_runner.run_pytest(
("scenario.feature", feature_content),
steps_content, cli_args=("--log-level=INFO", *params)
)

if_logging_ = is_ if logging else is_not

assert_that(
allure_results,
has_property(
"attachments",
all_of(
if_logging_(has_value(contains_string("Logging from given step"))),
if_logging_(has_value(contains_string("Logging from when step"))),
if_logging_(has_value(contains_string("Logging from then step"))),
)
)
)
Loading