Skip to content
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
4 changes: 2 additions & 2 deletions allure-behave/src/listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ def global_attach_file(self, source, name, attachment_type, extension):
self.logger.global_attach_file(uuid4(), source, name=name, attachment_type=attachment_type, extension=extension)

@allure_commons.hookimpl
def global_error(self, message, trace):
self.logger.global_error(message=message, trace=trace)
def global_error(self, message, trace, status):
self.logger.global_error(message=message, trace=trace, status=status)

@allure_commons.hookimpl
def add_description(self, test_description):
Expand Down
4 changes: 2 additions & 2 deletions allure-pytest-bdd/src/allure_api_listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,5 +130,5 @@ def global_attach_file(self, source, name, attachment_type, extension):
global_attach_file(self.lifecycle, source, name, attachment_type, extension)

@allure_commons.hookimpl
def global_error(self, message, trace):
global_error(self.lifecycle, message, trace)
def global_error(self, message, trace, status):
global_error(self.lifecycle, message, trace, status)
5 changes: 3 additions & 2 deletions allure-pytest-bdd/src/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import pytest

from allure_commons.types import ErrorStatus
from allure_commons.model2 import Label
from allure_commons.model2 import Link
from allure_commons.model2 import StatusDetails
Expand Down Expand Up @@ -338,8 +339,8 @@ def global_attach_file(lifecycle, source, name, attachment_type, extension=None)
)


def global_error(lifecycle, message, trace=None):
lifecycle.global_error(message=message, trace=trace)
def global_error(lifecycle, message, trace=None, status=ErrorStatus.BROKEN):
lifecycle.global_error(message=message, trace=trace, status=status)


def format_csv(rows):
Expand Down
4 changes: 2 additions & 2 deletions allure-pytest/src/listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,8 @@ def global_attach_file(self, source, name, attachment_type, extension):
)

@allure_commons.hookimpl
def global_error(self, message, trace):
self.allure_logger.global_error(message=message, trace=trace)
def global_error(self, message, trace, status):
self.allure_logger.global_error(message=message, trace=trace, status=status)

@allure_commons.hookimpl
def add_title(self, test_title):
Expand Down
4 changes: 3 additions & 1 deletion allure-python-commons/src/allure/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from allure_commons.types import Severity as severity_level
from allure_commons.types import AttachmentType as attachment_type
from allure_commons.types import ParameterMode as parameter_mode
from allure_commons.types import ErrorStatus as error_status


__all__ = [
Expand Down Expand Up @@ -43,5 +44,6 @@
"global_attach",
"global_error",
"attachment_type",
"parameter_mode"
"parameter_mode",
"error_status"
]
20 changes: 14 additions & 6 deletions allure-python-commons/src/allure_commons/_allure.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from typing import Any, Callable, TypeVar, Union, overload

from allure_commons._core import plugin_manager
from allure_commons.types import LabelType, LinkType, ParameterMode
from allure_commons.types import LabelType, LinkType, ParameterMode, ErrorStatus
from allure_commons.utils import uuid4
from allure_commons.utils import format_exception, format_traceback
from allure_commons.utils import func_parameters, represent
Expand Down Expand Up @@ -238,25 +238,33 @@ def file(self, source, name=None, attachment_type=None, extension=None):

global_attach = GlobalAttach()


@overload
def global_error(value: BaseException) -> None:
def global_error(
value: BaseException,
*,
status: ErrorStatus = ErrorStatus.BROKEN
) -> None:
...


@overload
def global_error(value: str, trace: Union[str, None] = None) -> None:
def global_error(
value: str,
trace: Union[str, None] = None,
*,
status: ErrorStatus = ErrorStatus.BROKEN
) -> None:
...


def global_error(value, trace=None):
def global_error(value, trace=None, *, status: ErrorStatus = ErrorStatus.BROKEN):
message = None
if isinstance(value, BaseException):
message = format_exception(type(value), value)
trace = format_traceback(value.__traceback__)
else:
message = value
plugin_manager.hook.global_error(message=message, trace=trace)
plugin_manager.hook.global_error(message=message, trace=trace, status=status)


class fixture:
Expand Down
2 changes: 1 addition & 1 deletion allure-python-commons/src/allure_commons/_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def global_attach_file(self, source, name, attachment_type, extension):
""" attach global file """

@hookspec
def global_error(self, message, trace):
def global_error(self, message, trace, status):
""" global error """


Expand Down
5 changes: 3 additions & 2 deletions allure-python-commons/src/allure_commons/lifecycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from allure_commons.model2 import ExecutableItem
from allure_commons.model2 import TestBeforeResult
from allure_commons.model2 import TestAfterResult
from allure_commons.types import ErrorStatus
from allure_commons.utils import uuid4
from allure_commons.utils import now
from allure_commons.types import AttachmentType
Expand Down Expand Up @@ -168,9 +169,9 @@ def global_attach_data(self, uuid, body, name=None, attachment_type=None, extens
GlobalAttachment(source=file_name, name=name, type=mime_type, timestamp=now())
]))

def global_error(self, message=None, trace=None):
def global_error(self, message=None, trace=None, status=ErrorStatus.BROKEN):
plugin_manager.hook.report_globals(globals_item=Globals(errors=[
GlobalError(message=message, trace=trace, timestamp=now())
GlobalError(status=status, message=message, trace=trace, timestamp=now())
]))

def __resolve_attachment_filename_and_type(self, uuid, attachment_type=None, extension=None):
Expand Down
2 changes: 2 additions & 0 deletions allure-python-commons/src/allure_commons/model2.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from attr import attrs, attrib
from attr import Factory
from allure_commons.types import ErrorStatus


TEST_GROUP_PATTERN = "{prefix}-container.json"
Expand Down Expand Up @@ -111,6 +112,7 @@ class GlobalAttachment(Attachment):

@attrs
class GlobalError(StatusDetails):
status = attrib(default=ErrorStatus.BROKEN)
timestamp = attrib(default=None)


Expand Down
5 changes: 3 additions & 2 deletions allure-python-commons/src/allure_commons/reporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from allure_commons.model2 import TestResult
from allure_commons.model2 import Attachment, ATTACHMENT_PATTERN
from allure_commons.model2 import GlobalAttachment, GlobalError, Globals
from allure_commons.types import ErrorStatus
from allure_commons.utils import now
from allure_commons._core import plugin_manager

Expand Down Expand Up @@ -172,9 +173,9 @@ def global_attach_data(self, uuid, body, name=None, attachment_type=None, extens
GlobalAttachment(source=file_name, name=name, type=mime_type, timestamp=now())
]))

def global_error(self, message=None, trace=None):
def global_error(self, message=None, trace=None, status=ErrorStatus.BROKEN):
plugin_manager.hook.report_globals(globals_item=Globals(errors=[
GlobalError(message=message, trace=trace, timestamp=now())
GlobalError(status=status, message=message, trace=trace, timestamp=now())
]))

def __resolve_attachment_filename_and_type(self, uuid, attachment_type=None, extension=None):
Expand Down
5 changes: 5 additions & 0 deletions allure-python-commons/src/allure_commons/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,8 @@ class ParameterMode(Enum):
HIDDEN = "hidden"
MASKED = "masked"
DEFAULT = None


class ErrorStatus(str, Enum):
BROKEN = "broken"
FAILED = "failed"
4 changes: 2 additions & 2 deletions allure-robotframework/src/library/allure_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ def global_attach_file(source, name=None, attachment_type=None, extension=None):
allure.global_attach.file(source, name=name, attachment_type=_attachment_type(attachment_type), extension=extension)


def global_error(message, trace=None):
allure.global_error(message, trace=trace)
def global_error(message, trace=None, *, status = allure.error_status.BROKEN):
allure.global_error(message, trace=trace, status=status)
4 changes: 2 additions & 2 deletions allure-robotframework/src/listener/allure_listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,8 @@ def global_attach_file(self, source, name, attachment_type, extension):
)

@allure_commons.hookimpl
def global_error(self, message, trace):
self.lifecycle.global_error(message=message, trace=trace)
def global_error(self, message, trace, status):
self.lifecycle.global_error(message=message, trace=trace, status=status)

@allure_commons.hookimpl
def start_step(self, uuid, title, params):
Expand Down
37 changes: 35 additions & 2 deletions tests/allure_behave/acceptance/allure_api/globals/globals_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from hamcrest import assert_that, equal_to, has_item, has_length
from allure_commons_test.result import has_global_attachment_with_content
from allure_commons_test.result import has_global_error
from allure_commons_test.result import with_message_contains
from allure_commons_test.result import with_message_contains, with_status


def test_global_attachment_and_error_hooks(behave_runner: Runner):
Expand Down Expand Up @@ -50,7 +50,40 @@ def after_all(context):
behave_runner.allure_results.globals,
has_item(
has_global_error(
with_message_contains("behave global error")
with_message_contains("behave global error"),
with_status("broken"),
)
)
)


def test_global_error_support_explicit_status(behave_runner: Runner):
behave_runner.run_behave(
feature_literals=[
"""
Feature: Failed global error
Scenario: Global error
Given noop
"""
],
step_literals=["given('noop')(lambda c: None)"],
environment_literal=textwrap.dedent(
"""
import allure


def after_all(context):
allure.global_error("behave global error", status=allure.error_status.FAILED)
"""
),
)

assert_that(
behave_runner.allure_results.globals,
has_item(
has_global_error(
with_message_contains("behave global error"),
with_status("failed"),
)
)
)
66 changes: 64 additions & 2 deletions tests/allure_pytest/acceptance/globals/globals_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from allure_commons_test.result import with_message_contains
from allure_commons_test.result import with_trace_contains
from allure_commons_test.result import with_no_trace
from allure_commons_test.result import with_status


def test_globals_from_session_hooks(allure_pytest_runner: AllurePytestRunner):
Expand Down Expand Up @@ -62,18 +63,79 @@ def pytest_sessionfinish(session, exitstatus):
has_global_error(
with_message_contains("message only error"),
with_no_trace(),
with_status("broken"),
)
),
has_item(
has_global_error(
with_message_contains("ValueError: error from exception"),
with_trace_contains("raise ValueError")
with_trace_contains("raise ValueError"),
with_status("broken"),
)
),
has_item(
has_global_error(
with_message_contains("message with trace"),
with_trace_contains("explicit trace")
with_trace_contains("explicit trace"),
with_status("broken"),
)
)
)
)


def test_global_error_support_status(allure_pytest_runner: AllurePytestRunner):
allure_results = allure_pytest_runner.run_pytest(
"""
def test_globals_from_session_hooks():
pass
""",
conftest_literal=(
"""
import allure


def pytest_sessionstart(session):
allure.global_error("message only error", status = allure.error_status.FAILED)


def pytest_sessionfinish(session, exitstatus):
try:
raise ValueError("error from exception")
except ValueError as error:
allure.global_error(error, status = allure.error_status.FAILED)
allure.global_error("message with trace", "explicit trace", status = allure.error_status.FAILED)
"""
)
)

assert_that(
allure_results.globals,
has_length(3),
)

assert_that(
allure_results.globals,
all_of(
has_item(
has_global_error(
with_message_contains("message only error"),
with_no_trace(),
with_status("failed"),
)
),
has_item(
has_global_error(
with_message_contains("ValueError: error from exception"),
with_trace_contains("raise ValueError"),
with_status("failed"),
)
),
has_item(
has_global_error(
with_message_contains("message with trace"),
with_trace_contains("explicit trace"),
with_status("failed"),
)
)
)
Expand Down
Loading
Loading