From 097fcf687fe22f075dffbfcd2a0d9a44eb04195c Mon Sep 17 00:00:00 2001 From: IvanBuruyane Date: Mon, 25 Mar 2024 13:39:10 +0200 Subject: [PATCH] Add logs, stdout and stderr to the allure-pytest-bdd report (#801) --- allure-pytest-bdd/src/pytest_bdd_listener.py | 8 +- .../acceptance/capture/__init__.py | 0 .../acceptance/capture/capture_attach_test.py | 155 ++++++++++++++++++ 3 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 tests/allure_pytest_bdd/acceptance/capture/__init__.py create mode 100644 tests/allure_pytest_bdd/acceptance/capture/capture_attach_test.py diff --git a/allure-pytest-bdd/src/pytest_bdd_listener.py b/allure-pytest-bdd/src/pytest_bdd_listener.py index 9a4f5fac..d4c73115 100644 --- a/allure-pytest-bdd/src/pytest_bdd_listener.py +++ b/allure-pytest-bdd/src/pytest_bdd_listener.py @@ -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 @@ -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) diff --git a/tests/allure_pytest_bdd/acceptance/capture/__init__.py b/tests/allure_pytest_bdd/acceptance/capture/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/allure_pytest_bdd/acceptance/capture/capture_attach_test.py b/tests/allure_pytest_bdd/acceptance/capture/capture_attach_test.py new file mode 100644 index 00000000..2a744b70 --- /dev/null +++ b/tests/allure_pytest_bdd/acceptance/capture/capture_attach_test.py @@ -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"))), + ) + ) + )