From 4742b9d8d8488a3ef19d30b3a4a6a38360524175 Mon Sep 17 00:00:00 2001 From: Stas Seliverstov Date: Tue, 13 Feb 2018 19:26:59 +0300 Subject: [PATCH] refactoring (fixes ##205 fixes #201 fixes #169) --- .gitignore | 2 +- allure-behave/features/steps/report_steps.py | 4 +- allure-pytest/src/listener.py | 48 +++--- allure-pytest/src/utils.py | 22 ++- .../function_scope/finalizers_simple_test.py | 2 +- .../fixtures_parametrization_test.py | 2 +- .../test/status/base_call_status_test.py | 74 +++++++++ .../test/status/base_setup_status_test.py | 140 ++++++++++++++++++ .../test/status/base_step_status_test.py | 45 ++++++ .../test/status/base_teardown_status_test.py | 65 ++++++++ .../test/status/skip_call_status_test.py | 68 +++++++++ .../test/status/skip_setup_status_test.py | 29 ++++ .../test/status/skip_step_status_test.py | 21 +++ .../test/status/skip_teardown_status_test.py | 30 ++++ allure-pytest/test/status/step_status_test.py | 64 -------- allure-pytest/test/status/test_status_test.py | 101 ------------- .../test/status/xfail_call_status_test.py | 82 ++++++++++ .../test/status/xfail_setup_status_test.py | 58 ++++++++ .../test/status/xfail_step_status_test.py | 24 +++ .../test/status/xfail_teardown_status_test.py | 32 ++++ .../placeholders_agrs_count_test.py | 2 +- allure-python-commons-test/src/result.py | 8 +- allure-python-commons/src/utils.py | 2 +- 23 files changed, 717 insertions(+), 208 deletions(-) create mode 100644 allure-pytest/test/status/base_call_status_test.py create mode 100644 allure-pytest/test/status/base_setup_status_test.py create mode 100644 allure-pytest/test/status/base_step_status_test.py create mode 100644 allure-pytest/test/status/base_teardown_status_test.py create mode 100644 allure-pytest/test/status/skip_call_status_test.py create mode 100644 allure-pytest/test/status/skip_setup_status_test.py create mode 100644 allure-pytest/test/status/skip_step_status_test.py create mode 100644 allure-pytest/test/status/skip_teardown_status_test.py delete mode 100644 allure-pytest/test/status/step_status_test.py delete mode 100644 allure-pytest/test/status/test_status_test.py create mode 100644 allure-pytest/test/status/xfail_call_status_test.py create mode 100644 allure-pytest/test/status/xfail_setup_status_test.py create mode 100644 allure-pytest/test/status/xfail_step_status_test.py create mode 100644 allure-pytest/test/status/xfail_teardown_status_test.py diff --git a/.gitignore b/.gitignore index c83a4ce8..af0bb13b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ .DS_Store .idea .tox -.cache +.pytest_cache .python-version *.pyc diff --git a/allure-behave/features/steps/report_steps.py b/allure-behave/features/steps/report_steps.py index 314aad30..05b88302 100644 --- a/allure-behave/features/steps/report_steps.py +++ b/allure-behave/features/steps/report_steps.py @@ -7,7 +7,7 @@ from allure_commons_test.result import has_attachment from allure_commons_test.result import has_parameter from allure_commons_test.result import has_status_details -from allure_commons_test.result import with_status_message +from allure_commons_test.result import with_message_contains from allure_commons_test.container import has_container from allure_commons_test.container import has_before, has_after from allure_commons_test.label import has_severity @@ -86,7 +86,7 @@ def step_status(context, item, status): @then(u'this {item} has status details with message "{message}"') def step_status(context, item, message): context_matcher = getattr(context, item) - matcher = partial(context_matcher, has_status_details, with_status_message, message) + matcher = partial(context_matcher, has_status_details, with_message_contains, message) assert_that(context.allure_report, matcher()) diff --git a/allure-pytest/src/listener.py b/allure-pytest/src/listener.py index cec2d49b..63c5c999 100644 --- a/allure-pytest/src/listener.py +++ b/allure-pytest/src/listener.py @@ -19,6 +19,7 @@ from allure_pytest.utils import allure_full_name, allure_package, allure_name 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 class AllureListener(object): @@ -142,45 +143,38 @@ def pytest_fixture_post_finalizer(self, fixturedef): @pytest.hookimpl(hookwrapper=True) def pytest_runtest_makereport(self, item, call): uuid = self._cache.set(item.nodeid) + report = (yield).get_result() - allure_item = self.allure_logger.get_item(uuid) - status = allure_item.status or None + + test_result = self.allure_logger.get_test(uuid) + status = get_pytest_report_status(report) status_details = None - if call.excinfo and hasattr(call.excinfo.value, 'msg'): - status_details = StatusDetails(message=call.excinfo.value.msg) - elif hasattr(report, 'wasxfail'): - status_details = StatusDetails(message=report.wasxfail) - elif report.failed: + if call.excinfo: status_details = StatusDetails(message=call.excinfo.exconly(), trace=report.longreprtext) + if (status != Status.SKIPPED + and not (call.excinfo.errisinstance(AssertionError) + or call.excinfo.errisinstance(pytest.fail.Exception))): + status = Status.BROKEN + + if status == Status.PASSED and hasattr(report, 'wasxfail'): + reason = report.wasxfail + message = 'XPASS {reason}'.format(reason=reason) if reason else 'XPASS' + status_details = StatusDetails(message=message) if report.when == 'setup': - if report.passed: - status = Status.PASSED - if report.failed: - status = Status.BROKEN - if report.skipped: - status = Status.SKIPPED + test_result.status = status + test_result.statusDetails = status_details if report.when == 'call': - if report.passed and status == Status.PASSED: - pass - if report.failed: - status = Status.FAILED - if report.skipped: - status = Status.SKIPPED + if test_result.status == Status.PASSED: + test_result.status = status + test_result.statusDetails = status_details if report.when == 'teardown': - if report.failed and status == Status.PASSED: - status = Status.BROKEN - - test_result = self.allure_logger.get_test(uuid) - if test_result: - if status_details: + if status in (Status.FAILED, Status.BROKEN) and test_result.status == Status.PASSED: test_result.status = status test_result.statusDetails = status_details - else: - test_result.status = status @allure_commons.hookimpl def attach_data(self, body, name, attachment_type, extension): diff --git a/allure-pytest/src/utils.py b/allure-pytest/src/utils.py index 99e5d6ef..7ec4bc4a 100644 --- a/allure-pytest/src/utils.py +++ b/allure-pytest/src/utils.py @@ -120,16 +120,24 @@ def get_outcome_status_details(outcome): def get_status(exception): if exception: - if isinstance(exception, AssertionError): + if isinstance(exception, AssertionError) or isinstance(exception, pytest.fail.Exception): return Status.FAILED elif isinstance(exception, pytest.skip.Exception): return Status.SKIPPED - return Status.PASSED + return Status.BROKEN + else: + return Status.PASSED def get_status_details(exception_type, exception, exception_traceback): - if isinstance(exception, pytest.skip.Exception): - return StatusDetails(message=exception.msg) - elif exception: - return StatusDetails(message=format_exception(exception_type, exception), - trace=format_traceback(exception_traceback)) + message = format_exception(exception_type, exception) + trace = format_traceback(exception_traceback) + return StatusDetails(message=message, trace=trace) if message or trace else None + + +def get_pytest_report_status(pytest_report): + pytest_statuses = ('failed', 'passed', 'skipped') + statuses = (Status.FAILED, Status.PASSED, Status.SKIPPED) + for pytest_status, status in zip(pytest_statuses, statuses): + if getattr(pytest_report, pytest_status): + return status diff --git a/allure-pytest/test/fixtures/function_scope/finalizers_simple_test.py b/allure-pytest/test/fixtures/function_scope/finalizers_simple_test.py index 72b03459..62823d43 100644 --- a/allure-pytest/test/fixtures/function_scope/finalizers_simple_test.py +++ b/allure-pytest/test/fixtures/function_scope/finalizers_simple_test.py @@ -55,7 +55,7 @@ def test_two_fixures_with_finalizer(fixture_with_passed_finalizer, fixture_faile ... finalizer='failed_finalizer'), ... with_status('failed'), ... has_status_details( - ... with_status_message('AssertionError') + ... with_message_contains('AssertionError') ... ) ... ) ... ) diff --git a/allure-pytest/test/fixtures/function_scope/fixtures_parametrization_test.py b/allure-pytest/test/fixtures/function_scope/fixtures_parametrization_test.py index 6d3b69e9..29d94dc3 100644 --- a/allure-pytest/test/fixtures/function_scope/fixtures_parametrization_test.py +++ b/allure-pytest/test/fixtures/function_scope/fixtures_parametrization_test.py @@ -26,7 +26,7 @@ def test_function_scope_parametrized_fixture(parametrized_fixture): ... has_before('parametrized_fixture', ... with_status('passed' if passed else 'failed'), ... has_status_details( - ... with_status_message('AssertionError') + ... with_message_contains('AssertionError') ... ) if not passed else anything() ... ) ... ) diff --git a/allure-pytest/test/status/base_call_status_test.py b/allure-pytest/test/status/base_call_status_test.py new file mode 100644 index 00000000..ab7b1949 --- /dev/null +++ b/allure-pytest/test/status/base_call_status_test.py @@ -0,0 +1,74 @@ +import pytest + + +def test_passed(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_passed', + ... with_status('passed') + ... ) + ... ) + """ + pass + + +def test_failed(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_failed', + ... with_status('failed'), + ... has_status_details(with_message_contains("AssertionError"), + ... with_trace_contains("def test_failed():") + ... ) + ... ) + ... ) + """ + assert False + + +def test_broken(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_broken', + ... with_status('broken'), + ... has_status_details(with_message_contains("IndentationError"), + ... with_trace_contains("def test_broken():") + ... ) + ... ) + ... ) + """ + raise IndentationError() + + +def test_call_pytest_fail(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_call_pytest_fail', + ... with_status('failed'), + ... has_status_details(with_message_contains("Failed: "), + ... with_trace_contains("def test_call_pytest_fail():") + ... ) + ... ) + ... ) + """ + pytest.fail() + + +def test_call_pytest_fail_with_reason(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_call_pytest_fail_with_reason', + ... with_status('failed'), + ... has_status_details(with_message_contains("Fail message"), + ... with_trace_contains("def test_call_pytest_fail():") + ... ) + ... ) + ... ) + """ + pytest.fail("Fail message") + diff --git a/allure-pytest/test/status/base_setup_status_test.py b/allure-pytest/test/status/base_setup_status_test.py new file mode 100644 index 00000000..007fbc0e --- /dev/null +++ b/allure-pytest/test/status/base_setup_status_test.py @@ -0,0 +1,140 @@ +import pytest + + +@pytest.fixture +def failed_fixture(): + assert False + + +def test_failed_fixture(failed_fixture): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_failed_fixture', + ... with_status('failed'), + ... has_status_details(with_message_contains("AssertionError"), + ... with_trace_contains("def failed_fixture():") + ... ), + ... has_container(allure_report, + ... has_before('failed_fixture', + ... with_status('failed'), + ... has_status_details(with_message_contains("AssertionError"), + ... with_trace_contains("failed_fixture") + ... ), + ... ), + ... ) + ... ) + ... ) + """ + pass + + +@pytest.fixture +def broken_fixture(): + raise IndexError + + +def test_broken_fixture(broken_fixture): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_broken_fixture', + ... with_status('broken'), + ... has_status_details(with_message_contains("IndexError"), + ... with_trace_contains("def broken_fixture():") + ... ), + ... has_container(allure_report, + ... has_before('broken_fixture', + ... with_status('broken'), + ... has_status_details(with_message_contains("IndexError"), + ... with_trace_contains("broken_fixture") + ... ), + ... ), + ... ) + ... ) + ... ) + """ + pass + + +@pytest.fixture +def skip_fixture(): + pytest.skip() + + +def test_skip_fixture(skip_fixture): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_skip_fixture', + ... with_status('skipped'), + ... has_status_details(with_message_contains("Skipped: ")), + ... has_container(allure_report, + ... has_before('skip_fixture', + ... with_status('skipped'), + ... has_status_details(with_message_contains("Skipped: "), + ... with_trace_contains("skip_fixture") + ... ), + ... ), + ... ) + ... ) + ... ) + """ + + +@pytest.fixture +def pytest_fail_fixture(): + pytest.fail() + + +def test_pytest_fail_fixture(pytest_fail_fixture): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_pytest_fail_fixture', + ... with_status('failed'), + ... has_status_details(with_message_contains("Failed: "), + ... with_trace_contains("def pytest_fail_fixture():") + ... ), + ... has_container(allure_report, + ... has_before('pytest_fail_fixture', + ... with_status('failed'), + ... has_status_details(with_message_contains("Failed: "), + ... with_trace_contains("pytest_fail_fixture") + ... ), + ... ), + ... ) + ... ) + ... ) + """ + pass + + +@pytest.fixture +def pytest_fail_with_reason_fixture(): + pytest.fail("Fail message") + + +def test_pytest_fail_with_reason_fixture(pytest_fail_with_reason_fixture): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_pytest_fail_with_reason_fixture', + ... with_status('failed'), + ... has_status_details(with_message_contains("Fail message"), + ... with_trace_contains("def pytest_fail_with_reason_fixture():") + ... ), + ... has_container(allure_report, + ... has_before('pytest_fail_with_reason_fixture', + ... with_status('failed'), + ... has_status_details(with_message_contains("Fail message"), + ... with_trace_contains("pytest_fail_with_reason_fixture") + ... ), + ... ), + ... ) + ... ) + ... ) + """ + pass + + diff --git a/allure-pytest/test/status/base_step_status_test.py b/allure-pytest/test/status/base_step_status_test.py new file mode 100644 index 00000000..c57abf3a --- /dev/null +++ b/allure-pytest/test/status/base_step_status_test.py @@ -0,0 +1,45 @@ +import pytest + + +def test_broken_step(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_broken_step', + ... with_status('broken'), + ... has_status_details(with_message_contains("ZeroDivisionError"), + ... with_trace_contains("def test_broken_step():") + ... ), + ... has_step('Step', + ... with_status('broken'), + ... has_status_details(with_message_contains("ZeroDivisionError"), + ... with_trace_contains("test_broken_step") + ... ) + ... ) + ... ) + ... ) + """ + with pytest.allure.step('Step'): + raise ZeroDivisionError + + +def test_pytest_fail_in_step(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_pytest_fail_in_step', + ... with_status('failed'), + ... has_status_details(with_message_contains("Failed: "), + ... with_trace_contains("def test_pytest_fail_in_step():") + ... ), + ... has_step('Step', + ... with_status('failed'), + ... has_status_details(with_message_contains("Failed: "), + ... with_trace_contains("test_pytest_fail_in_step") + ... ) + ... ) + ... ) + ... ) + """ + with pytest.allure.step('Step'): + pytest.fail() diff --git a/allure-pytest/test/status/base_teardown_status_test.py b/allure-pytest/test/status/base_teardown_status_test.py new file mode 100644 index 00000000..14740d31 --- /dev/null +++ b/allure-pytest/test/status/base_teardown_status_test.py @@ -0,0 +1,65 @@ +import pytest + + +@pytest.fixture +def failed_finalizer_fixture(request): + def fixture_finalizer(): + assert False + request.addfinalizer(fixture_finalizer) + + +def test_failed_finalizer_fixture(failed_finalizer_fixture): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_failed_finalizer_fixture', + ... with_status('failed'), + ... has_status_details(with_message_contains("AssertionError"), + ... with_trace_contains("def fixture_finalizer():") + ... ), + ... has_container(allure_report, + ... has_after('{fixture}::{finalizer}'.format( + ... fixture='failed_finalizer_fixture', + ... finalizer='fixture_finalizer'), + ... with_status('failed'), + ... has_status_details(with_message_contains("AssertionError"), + ... with_trace_contains("fixture_finalizer") + ... ), + ... ), + ... ) + ... ) + ... ) + """ + pass + + +@pytest.fixture +def pytest_failed_finalizer_fixture(request): + def fixture_finalizer(): + pytest.fail() + request.addfinalizer(fixture_finalizer) + + +def test_pytest_failed_finalizer_fixture(pytest_failed_finalizer_fixture): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_pytest_failed_finalizer_fixture', + ... with_status('failed'), + ... has_status_details(with_message_contains("Failed: "), + ... with_trace_contains("def fixture_finalizer():") + ... ), + ... has_container(allure_report, + ... has_after('{fixture}::{finalizer}'.format( + ... fixture='pytest_failed_finalizer_fixture', + ... finalizer='fixture_finalizer'), + ... with_status('failed'), + ... has_status_details(with_message_contains("Failed: "), + ... with_trace_contains("fixture_finalizer") + ... ), + ... ), + ... ) + ... ) + ... ) + """ + pass \ No newline at end of file diff --git a/allure-pytest/test/status/skip_call_status_test.py b/allure-pytest/test/status/skip_call_status_test.py new file mode 100644 index 00000000..c82b0668 --- /dev/null +++ b/allure-pytest/test/status/skip_call_status_test.py @@ -0,0 +1,68 @@ +import pytest + + +def test_skip(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_skip', + ... with_status('skipped'), + ... has_status_details(with_message_contains("Skipped: ")) + ... ) + ... ) + """ + pytest.skip() + + +def test_skip_with_reason(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_skip_with_reason', + ... with_status('skipped'), + ... has_status_details(with_message_contains("Skipped: Skip reason")) + ... ) + ... ) + """ + pytest.skip('Skip reason') + + +@pytest.mark.skip(reason='Skip reason') +def test_skip_decorator_and_reason(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_skip_decorator_and_reason', + ... with_status('skipped'), + ... has_status_details(with_message_contains("Skipped: Skip reason")) + ... ) + ... ) + """ + pass + + +@pytest.mark.skipif(True, reason='Skip reason') +def test_skipif_true(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_skipif_true', + ... with_status('skipped'), + ... has_status_details(with_message_contains("Skipped: Skip reason")) + ... ) + ... ) + """ + pass + + +@pytest.mark.skipif(False, reason='Skip reason') +def test_skipif_false(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_skipif_false', + ... with_status('passed') + ... ) + ... ) + """ + pass diff --git a/allure-pytest/test/status/skip_setup_status_test.py b/allure-pytest/test/status/skip_setup_status_test.py new file mode 100644 index 00000000..cb2ea384 --- /dev/null +++ b/allure-pytest/test/status/skip_setup_status_test.py @@ -0,0 +1,29 @@ +import pytest + + +@pytest.fixture +def skip_fixture(): + pytest.skip() + + +@pytest.mark.xfail() +def test_skip_fixture(skip_fixture): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_skip_fixture', + ... with_status('skipped'), + ... has_status_details(with_message_contains("Skipped: ")), + ... has_container(allure_report, + ... has_before('skip_fixture', + ... with_status('skipped'), + ... has_status_details(with_message_contains("Skipped: "), + ... with_trace_contains("skip_fixture") + ... ), + ... ), + ... ) + ... ) + ... ) + """ + pass + diff --git a/allure-pytest/test/status/skip_step_status_test.py b/allure-pytest/test/status/skip_step_status_test.py new file mode 100644 index 00000000..d383e91d --- /dev/null +++ b/allure-pytest/test/status/skip_step_status_test.py @@ -0,0 +1,21 @@ +import pytest + + +def test_skip_in_step(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_skip_in_step', + ... with_status('skipped'), + ... has_status_details(with_message_contains("Skipped: ")), + ... has_step('Step', + ... with_status('skipped'), + ... has_status_details(with_message_contains("Skipped: "), + ... with_trace_contains("test_skip_in_step") + ... ) + ... ) + ... ) + ... ) + """ + with pytest.allure.step('Step'): + pytest.skip() diff --git a/allure-pytest/test/status/skip_teardown_status_test.py b/allure-pytest/test/status/skip_teardown_status_test.py new file mode 100644 index 00000000..67b09207 --- /dev/null +++ b/allure-pytest/test/status/skip_teardown_status_test.py @@ -0,0 +1,30 @@ +import pytest + + +@pytest.fixture +def skip_finalizer_fixture(request): + def fixture_finalizer(): + pytest.skip() + request.addfinalizer(fixture_finalizer) + + +def test_skip_finalizer_fixture(skip_finalizer_fixture): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_skip_finalizer_fixture', + ... with_status('passed'), + ... has_container(allure_report, + ... has_after('{fixture}::{finalizer}'.format( + ... fixture='skip_finalizer_fixture', + ... finalizer='fixture_finalizer'), + ... with_status('skipped'), + ... has_status_details(with_message_contains("Skipped: "), + ... with_trace_contains("fixture_finalizer") + ... ), + ... ), + ... ) + ... ) + ... ) + """ + pass diff --git a/allure-pytest/test/status/step_status_test.py b/allure-pytest/test/status/step_status_test.py deleted file mode 100644 index 7f2f4464..00000000 --- a/allure-pytest/test/status/step_status_test.py +++ /dev/null @@ -1,64 +0,0 @@ -import pytest - - -def test_skip_in_step(): - """ - >>> allure_report = getfixture('allure_report') - >>> assert_that(allure_report, - ... has_test_case('test_skip_in_step', - ... with_status('skipped'), - ... has_step('Step1', - ... with_status('skipped') - ... ) - ... ) - ... ) - """ - with pytest.allure.step('Step1'): - pytest.skip() - - -def test_skip_in_deep_step(): - """ - >>> allure_report = getfixture('allure_report') - >>> assert_that(allure_report, - ... has_test_case('test_skip_in_deep_step', - ... with_status('skipped'), - ... has_step('Step1', - ... with_status('skipped'), - ... has_step('Step2', - ... with_status('skipped'), - ... has_status_details( - ... with_status_message('oops!') - ... ) - ... ) - ... ) - ... ) - ... ) - """ - with pytest.allure.step('Step1'): - with pytest.allure.step('Step2'): - pytest.skip('oops!') - - -def test_fail_in_step_after_step(): - """ - >>> allure_report = getfixture('allure_report') - >>> assert_that(allure_report, - ... has_test_case('test_fail_in_step_after_step', - ... with_status('failed'), - ... has_step('Step1', - ... with_status('failed'), - ... has_status_details( - ... with_status_message('AssertionError') - ... ), - ... has_step('Step2', - ... with_status('passed') - ... ) - ... ) - ... ) - ... ) - """ - with pytest.allure.step('Step1'): - with pytest.allure.step('Step2'): - pass - assert False diff --git a/allure-pytest/test/status/test_status_test.py b/allure-pytest/test/status/test_status_test.py deleted file mode 100644 index 13b524f2..00000000 --- a/allure-pytest/test/status/test_status_test.py +++ /dev/null @@ -1,101 +0,0 @@ -import pytest - - -XFAIL_REASON = "THIS IS EXPECTED FAIL" -SKIP_REASON = "SKIPPED TEST" - - -def test_passed(): - """ - >>> allure_report = getfixture('allure_report') - >>> assert_that(allure_report, has_test_case('test_passed', with_status('passed'))) - """ - pass - - -def test_failed(): - """ - >>> allure_report = getfixture('allure_report') - >>> assert_that(allure_report, has_test_case('test_failed', with_status('failed'))) - """ - assert False - - -@pytest.mark.xfail(reason=XFAIL_REASON) -def test_xfailed(): - """ - >>> allure_report = getfixture('allure_report') # doctest: +SKIP - >>> assert_that(allure_report, has_test_case('test_xfailed', - ... with_status('failed'), - ... has_status_details(with_status_message(XFAIL_REASON)))) # doctest: +SKIP - """ - assert False - - -@pytest.mark.xfail(raises=RuntimeError) -def test_xfailed_not_mentioned_exception(): - """ - >>> allure_report = getfixture('allure_report') - >>> assert_that(allure_report, has_test_case('test_passed', with_status('passed'))) - """ - assert False - - -@pytest.mark.xfail(reason=XFAIL_REASON) -def test_xfailed_but_passed(): - """ - >>> allure_report = getfixture('allure_report') - >>> assert_that(allure_report, has_test_case('test_xfailed_but_passed', - ... with_status('passed'), - ... has_status_details(with_status_message(XFAIL_REASON)))) - """ - pass - - -def test_skip_in_test(): - """ - >>> allure_report = getfixture('allure_report') - >>> assert_that(allure_report, test_skip_in_test, with_status('skipped')) - """ - pytest.skip() - - -def test_skip_with_reason_in_test(): - """ - >>> allure_report = getfixture('allure_report') - >>> assert_that(allure_report, has_test_case('test_skip_with_reason_in_test', - ... with_status('skipped'), - ... has_status_details(with_status_message(SKIP_REASON)))) - """ - pytest.skip(SKIP_REASON) - - -@pytest.mark.skip(reason=SKIP_REASON) -def test_skip_with_decorator_and_reason(): - """ - >>> allure_report = getfixture('allure_report') - >>> assert_that(allure_report, has_test_case('test_skip_with_decorator_and_reason', - ... with_status('skipped'), - ... has_status_details(with_status_message(SKIP_REASON)))) - """ - pass - - -@pytest.mark.skipif(True, reason=SKIP_REASON) -def test_skipif_true(): - """ - >>> allure_report = getfixture('allure_report') - >>> assert_that(allure_report, has_test_case('test_skipif_true', - ... with_status('skipped'), - ... has_status_details(with_status_message(SKIP_REASON)))) - """ - pass - - -@pytest.mark.skipif(False, reason=SKIP_REASON) -def test_skipif_false(): - """ - >>> allure_report = getfixture('allure_report') - >>> assert_that(allure_report, has_test_case('test_skipif_false', with_status('passed'))) - """ - pass diff --git a/allure-pytest/test/status/xfail_call_status_test.py b/allure-pytest/test/status/xfail_call_status_test.py new file mode 100644 index 00000000..052bf1db --- /dev/null +++ b/allure-pytest/test/status/xfail_call_status_test.py @@ -0,0 +1,82 @@ +import pytest + + +@pytest.mark.xfail() +def test_xfail(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_xfail', + ... with_status('skipped'), + ... has_status_details(with_message_contains("AssertionError"), + ... with_trace_contains("def test_xfail():") + ... ) + ... ) + ... ) + """ + assert False + + +@pytest.mark.xfail(raises=AssertionError) +def test_xfail_raise_mentioned_exception(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_xfail_raise_mentioned_exception', + ... with_status('skipped'), + ... has_status_details(with_message_contains("AssertionError"), + ... with_trace_contains("def test_xfail_raise_mentioned_exception():") + ... ) + ... ) + ... ) + """ + assert False + + +@pytest.mark.xfail(raises=AssertionError) +def test_xfail_raise_not_mentioned_exception(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_xfail_raise_not_mentioned_exception', + ... with_status('broken'), + ... has_status_details(with_message_contains("ZeroDivisionError"), + ... with_trace_contains("def test_xfail_raise_not_mentioned_exception():") + ... ) + ... ) + ... ) + """ + raise ZeroDivisionError + + +@pytest.mark.xfail(raises=AssertionError) +def test_xfail_do_not_raise_mentioned_exception(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_xfail_do_not_raise_mentioned_exception', + ... with_status('passed'), + ... has_status_details(with_message_contains("XPASS"), + ... ) + ... ) + ... ) + """ + pass + + +@pytest.mark.xfail(raises=AssertionError, reason='Some reason') +def test_xfail_with_reason_do_not_raise_mentioned_exception(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_xfail_with_reason_do_not_raise_mentioned_exception', + ... with_status('passed'), + ... has_status_details(with_message_contains("XPASS Some reason"), + ... ) + ... ) + ... ) + """ + pass + + + diff --git a/allure-pytest/test/status/xfail_setup_status_test.py b/allure-pytest/test/status/xfail_setup_status_test.py new file mode 100644 index 00000000..75fdae84 --- /dev/null +++ b/allure-pytest/test/status/xfail_setup_status_test.py @@ -0,0 +1,58 @@ +import pytest + + +@pytest.mark.xfail(run=False) +def test_xfail_with_run_false(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_xfail_with_run_false', + ... with_status('skipped'), + ... has_status_details(with_message_contains("Failed: [NOTRUN]")), + ... ) + ... ) + """ + pass + + +@pytest.mark.xfail(run=False, reason='Some reason') +def test_xfail_with_run_false_and_with_reason(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_xfail_with_run_false_and_with_reason', + ... with_status('skipped'), + ... has_status_details(with_message_contains("Failed: [NOTRUN] Some reason")) + ... ) + ... ) + """ + pass + + +@pytest.fixture +def broken_fixture(): + raise NotImplementedError + + +@pytest.mark.xfail() +def test_xfail_fixture(broken_fixture): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_xfail_fixture', + ... with_status('skipped'), + ... has_status_details(with_message_contains("NotImplementedError"), + ... with_trace_contains("def broken_fixture():") + ... ), + ... has_container(allure_report, + ... has_before('broken_fixture', + ... with_status('broken'), + ... has_status_details(with_message_contains("NotImplementedError"), + ... with_trace_contains("broken_fixture") + ... ), + ... ), + ... ) + ... ) + ... ) + """ + pass diff --git a/allure-pytest/test/status/xfail_step_status_test.py b/allure-pytest/test/status/xfail_step_status_test.py new file mode 100644 index 00000000..ebdbdcbf --- /dev/null +++ b/allure-pytest/test/status/xfail_step_status_test.py @@ -0,0 +1,24 @@ +import pytest + + +@pytest.mark.xfail() +def test_xfail_step_failure(): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_xfail_step_failure', + ... with_status('skipped'), + ... has_status_details(with_message_contains("AssertionError"), + ... with_trace_contains("def test_xfail_step_failure():") + ... ), + ... has_step('Step', + ... with_status('failed'), + ... has_status_details(with_message_contains("AssertionError"), + ... with_trace_contains("test_xfail_step_failure") + ... ) + ... ) + ... ) + ... ) + """ + with pytest.allure.step('Step'): + assert False diff --git a/allure-pytest/test/status/xfail_teardown_status_test.py b/allure-pytest/test/status/xfail_teardown_status_test.py new file mode 100644 index 00000000..04e80622 --- /dev/null +++ b/allure-pytest/test/status/xfail_teardown_status_test.py @@ -0,0 +1,32 @@ +import pytest + + +@pytest.fixture +def failed_finalizer_fixture(request): + def fixture_finalizer(): + assert False + request.addfinalizer(fixture_finalizer) + + +@pytest.mark.xfail() +def test_xfail_failed_finalizer_fixture(failed_finalizer_fixture): + """ + >>> allure_report = getfixture('allure_report') + >>> assert_that(allure_report, + ... has_test_case('test_xfail_failed_finalizer_fixture', + ... with_status('passed'), + ... has_status_details(with_message_contains("XPASS")), + ... has_container(allure_report, + ... has_after('{fixture}::{finalizer}'.format( + ... fixture='failed_finalizer_fixture', + ... finalizer='fixture_finalizer'), + ... with_status('failed'), + ... has_status_details(with_message_contains("AssertionError"), + ... with_trace_contains("fixture_finalizer") + ... ), + ... ), + ... ) + ... ) + ... ) + """ + pass diff --git a/allure-pytest/test/steps/placeholders/placeholders_agrs_count_test.py b/allure-pytest/test/steps/placeholders/placeholders_agrs_count_test.py index 13c353e5..7b83c95f 100644 --- a/allure-pytest/test/steps/placeholders/placeholders_agrs_count_test.py +++ b/allure-pytest/test/steps/placeholders/placeholders_agrs_count_test.py @@ -61,7 +61,7 @@ def test_args_less(): >>> assert_that(allure_report, ... has_test_case('test_args_less', ... has_status_details( - ... with_status_message('IndexError: tuple index out of range') + ... with_message_contains('IndexError: tuple index out of range') ... ) ... ) ... ) diff --git a/allure-python-commons-test/src/result.py b/allure-python-commons-test/src/result.py index 08127bc0..d6feb3d3 100644 --- a/allure-python-commons-test/src/result.py +++ b/allure-python-commons-test/src/result.py @@ -141,8 +141,12 @@ def has_status_details(*matchers): return has_entry('statusDetails', all_of(*matchers)) -def with_status_message(message): - return has_entry('message', contains_string(message)) +def with_message_contains(string): + return has_entry('message', contains_string(string)) + + +def with_trace_contains(string): + return has_entry('trace', contains_string(string)) def has_history_id(): diff --git a/allure-python-commons/src/utils.py b/allure-python-commons/src/utils.py index c21d1aca..72457501 100644 --- a/allure-python-commons/src/utils.py +++ b/allure-python-commons/src/utils.py @@ -167,4 +167,4 @@ def format_exception(etype, value): ... format_exception(etype, e) # doctest: +ELLIPSIS "AssertionError: \\nExpected:...but:..." """ - return '\n'.join(format_exception_only(etype, value)) + return '\n'.join(format_exception_only(etype, value)) if etype or value else None