From f6a6f6aa42f63ddf6ca2047a230fc4a7ff942b5b Mon Sep 17 00:00:00 2001 From: Artem Ryabkov Date: Mon, 7 Dec 2020 01:04:45 +0300 Subject: [PATCH 1/3] Titled fixtures and tests for them --- allure-pytest/__init__.py | 0 allure-pytest/src/helper.py | 16 ++-- allure-pytest/src/listener.py | 8 +- allure-pytest/src/plugin.py | 13 +-- allure-pytest/src/utils.py | 3 +- .../display_name/display_name_test.py | 24 +++++ .../test/acceptance/fixture/fixture_test.py | 87 +++++++++++++++++++ 7 files changed, 135 insertions(+), 16 deletions(-) create mode 100644 allure-pytest/__init__.py diff --git a/allure-pytest/__init__.py b/allure-pytest/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/allure-pytest/src/helper.py b/allure-pytest/src/helper.py index c7e48560..07c4894c 100644 --- a/allure-pytest/src/helper.py +++ b/allure-pytest/src/helper.py @@ -3,20 +3,26 @@ import pytest import allure_commons -from allure_pytest.utils import ALLURE_DISPLAY_NAME_MARK from allure_pytest.utils import ALLURE_DESCRIPTION_MARK, ALLURE_DESCRIPTION_HTML_MARK from allure_pytest.utils import ALLURE_LABEL_MARK, ALLURE_LINK_MARK class AllureTestHelper(object): - def __init__(self, config): - self.config = config + def __init__(self, config=None): + self.config = None @allure_commons.hookimpl def decorate_as_title(self, test_title): - allure_title = getattr(pytest.mark, ALLURE_DISPLAY_NAME_MARK) - return allure_title(test_title) + def decorator(func): + if getattr(func, '__pytest_wrapped__', None): + function = func.__pytest_wrapped__.obj + else: + function = func + function.__allure_display_name__ = test_title + return func + + return decorator @allure_commons.hookimpl def decorate_as_description(self, test_description): diff --git a/allure-pytest/src/listener.py b/allure-pytest/src/listener.py index 374220e7..879616b9 100644 --- a/allure-pytest/src/listener.py +++ b/allure-pytest/src/listener.py @@ -122,7 +122,7 @@ def pytest_runtest_teardown(self, item): @pytest.hookimpl(hookwrapper=True) def pytest_fixture_setup(self, fixturedef, request): - fixture_name = fixturedef.argname + fixture_name = getattr(fixturedef.func, '__allure_display_name__', fixturedef.argname) container_uuid = self._cache.get(fixturedef) @@ -146,7 +146,7 @@ def pytest_fixture_setup(self, fixturedef, request): finalizers = getattr(fixturedef, '_finalizers', []) for index, finalizer in enumerate(finalizers): - name = '{fixture}::{finalizer}'.format(fixture=fixturedef.argname, + name = '{fixture}::{finalizer}'.format(fixture=fixture_name, finalizer=getattr(finalizer, "__name__", index)) finalizers[index] = allure_commons.fixture(finalizer, parent_uuid=container_uuid, name=name) @@ -177,8 +177,8 @@ def pytest_runtest_makereport(self, item, call): message=message, trace=trace) if (status != Status.SKIPPED - and not (call.excinfo.errisinstance(AssertionError) - or call.excinfo.errisinstance(pytest.fail.Exception))): + and not (call.excinfo.errisinstance(AssertionError) + or call.excinfo.errisinstance(pytest.fail.Exception))): status = Status.BROKEN if status == Status.PASSED and hasattr(report, 'wasxfail'): diff --git a/allure-pytest/src/plugin.py b/allure-pytest/src/plugin.py index 4501ab60..35bfe80e 100644 --- a/allure-pytest/src/plugin.py +++ b/allure-pytest/src/plugin.py @@ -12,7 +12,6 @@ from allure_pytest.helper import AllureTestHelper from allure_pytest.listener import AllureListener -from allure_pytest.utils import ALLURE_DISPLAY_NAME_MARK from allure_pytest.utils import ALLURE_DESCRIPTION_MARK, ALLURE_DESCRIPTION_HTML_MARK from allure_pytest.utils import ALLURE_LABEL_MARK, ALLURE_LINK_MARK @@ -111,13 +110,18 @@ def clean_up(): return clean_up +def pytest_addhooks(pluginmanager): + test_helper = AllureTestHelper() + # TODO: Why helper is present anyway? + allure_commons.plugin_manager.register(test_helper) + + def pytest_configure(config): report_dir = config.option.allure_report_dir clean = config.option.clean_alluredir - test_helper = AllureTestHelper(config) - # TODO: Why helper is present anyway? - allure_commons.plugin_manager.register(test_helper) + test_helper = list(allure_commons.plugin_manager.get_plugin_manager()._name2plugin.values())[0] + test_helper.config = config config.add_cleanup(cleanup_factory(test_helper)) if report_dir: @@ -133,7 +137,6 @@ def pytest_configure(config): config.addinivalue_line("markers", "{mark}: allure label marker".format(mark=ALLURE_LABEL_MARK)) config.addinivalue_line("markers", "{mark}: allure link marker".format(mark=ALLURE_LINK_MARK)) - config.addinivalue_line("markers", "{mark}: allure test name marker".format(mark=ALLURE_DISPLAY_NAME_MARK)) config.addinivalue_line("markers", "{mark}: allure description".format(mark=ALLURE_DESCRIPTION_MARK)) config.addinivalue_line("markers", "{mark}: allure description html".format(mark=ALLURE_DESCRIPTION_HTML_MARK)) diff --git a/allure-pytest/src/utils.py b/allure-pytest/src/utils.py index f1d90eb5..e000a02e 100644 --- a/allure-pytest/src/utils.py +++ b/allure-pytest/src/utils.py @@ -11,7 +11,6 @@ from allure_commons.types import LabelType -ALLURE_DISPLAY_NAME_MARK = 'allure_display_name' ALLURE_DESCRIPTION_MARK = 'allure_description' ALLURE_DESCRIPTION_HTML_MARK = 'allure_description_html' ALLURE_LABEL_MARK = 'allure_label' @@ -32,7 +31,7 @@ def get_marker_value(item, keyword): def allure_title(item): - return get_marker_value(item, ALLURE_DISPLAY_NAME_MARK) + return getattr(item._obj, '__allure_display_name__', None) def allure_description(item): diff --git a/allure-pytest/test/acceptance/display_name/display_name_test.py b/allure-pytest/test/acceptance/display_name/display_name_test.py index 18cef052..b8528637 100644 --- a/allure-pytest/test/acceptance/display_name/display_name_test.py +++ b/allure-pytest/test/acceptance/display_name/display_name_test.py @@ -4,6 +4,7 @@ from hamcrest import assert_that from allure_commons_test.report import has_test_case from allure_commons_test.result import has_title +from allure_commons_test.label import has_label def test_display_name(executed_docstring_path): @@ -73,3 +74,26 @@ def test_fixture_value_in_display_name(executed_docstring_source): has_title("title with fixture value") ) ) + + +def test_display_name_with_features(allured_testdir): + allured_testdir.testdir.makepyfile(""" + import allure + import pytest + + @allure.feature('Feature 1') + @allure.title('Titled test with features') + @allure.feature('Feature 2') + def test_feature_label_for_titled_test(): + pass + """) + + allured_testdir.run_with_allure() + + assert_that(allured_testdir.allure_report, + has_test_case("test_feature_label_for_titled_test", + has_label("feature", "Feature 1"), + has_label("feature", "Feature 2"), + has_title("Titled test with features") + ) + ) diff --git a/allure-pytest/test/acceptance/fixture/fixture_test.py b/allure-pytest/test/acceptance/fixture/fixture_test.py index 3422b218..d407049e 100644 --- a/allure-pytest/test/acceptance/fixture/fixture_test.py +++ b/allure-pytest/test/acceptance/fixture/fixture_test.py @@ -130,3 +130,90 @@ def test_nested_fixtures(executed_docstring_source): ) ) ) + + +@allure.feature("Fixture") +def test_fixture_allure_title(allured_testdir): + allured_testdir.testdir.makepyfile(""" + import pytest + import allure + + @pytest.fixture + @allure.title("Allure fixture title") + def first_fixture(): + pass + + def test_titled_fixture_example(first_fixture): + pass + """) + + allured_testdir.run_with_allure() + + assert_that(allured_testdir.allure_report, + has_test_case("test_titled_fixture_example", + has_container(allured_testdir.allure_report, + has_before("Allure fixture title") + ) + ) + ) + + +@allure.feature("Fixture") +def test_fixture_allure_title_before(allured_testdir): + allured_testdir.testdir.makepyfile(""" + import pytest + import allure + + @allure.title("Allure fixture title") + @pytest.fixture + def first_fixture(): + pass + + def test_titled_before_fixture_example(first_fixture): + pass + """) + + allured_testdir.run_with_allure() + + assert_that(allured_testdir.allure_report, + has_test_case("test_titled_before_fixture_example", + has_container(allured_testdir.allure_report, + has_before("Allure fixture title") + ) + ) + ) + + +def test_titled_fixture_from_conftest(allured_testdir): + allured_testdir.testdir.makeconftest(""" + import allure + import pytest + + @allure.title('Titled fixture before pytest.fixture') + @pytest.fixture + def first_fixture(): + pass + + @pytest.fixture + @allure.title('Titled fixture after pytest.fixture') + def second_fixture(): + pass + """) + + allured_testdir.testdir.makepyfile(""" + def test_with_titled_conftest_fixtures(first_fixture, second_fixture): + pass + """) + + allured_testdir.run_with_allure() + + assert_that(allured_testdir.allure_report, + has_test_case("test_with_titled_conftest_fixtures", + has_container(allured_testdir.allure_report, + has_before("Titled fixture before pytest.fixture") + ), + has_container(allured_testdir.allure_report, + has_before("Titled fixture after pytest.fixture") + ) + ) + ) From 373bb6d9b5ed62bd891e44dd70019f18fbd757f1 Mon Sep 17 00:00:00 2001 From: Artem Ryabkov Date: Mon, 7 Dec 2020 01:23:27 +0300 Subject: [PATCH 2/3] Splited helper --- allure-pytest/src/helper.py | 9 +++++++-- allure-pytest/src/plugin.py | 11 +++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/allure-pytest/src/helper.py b/allure-pytest/src/helper.py index 07c4894c..5c0f49f7 100644 --- a/allure-pytest/src/helper.py +++ b/allure-pytest/src/helper.py @@ -7,10 +7,10 @@ from allure_pytest.utils import ALLURE_LABEL_MARK, ALLURE_LINK_MARK -class AllureTestHelper(object): +class AllureTitleHelper(object): def __init__(self, config=None): - self.config = None + self.config = config @allure_commons.hookimpl def decorate_as_title(self, test_title): @@ -24,6 +24,11 @@ def decorator(func): return decorator + +class AllureTestHelper(object): + def __init__(self, config): + self.config = config + @allure_commons.hookimpl def decorate_as_description(self, test_description): allure_description = getattr(pytest.mark, ALLURE_DESCRIPTION_MARK) diff --git a/allure-pytest/src/plugin.py b/allure-pytest/src/plugin.py index 35bfe80e..cabcc513 100644 --- a/allure-pytest/src/plugin.py +++ b/allure-pytest/src/plugin.py @@ -9,7 +9,7 @@ from allure_commons.utils import get_testplan from allure_pytest.utils import allure_label, allure_labels, allure_full_name -from allure_pytest.helper import AllureTestHelper +from allure_pytest.helper import AllureTestHelper, AllureTitleHelper from allure_pytest.listener import AllureListener from allure_pytest.utils import ALLURE_DESCRIPTION_MARK, ALLURE_DESCRIPTION_HTML_MARK @@ -111,17 +111,16 @@ def clean_up(): def pytest_addhooks(pluginmanager): - test_helper = AllureTestHelper() - # TODO: Why helper is present anyway? - allure_commons.plugin_manager.register(test_helper) + title_helper = AllureTitleHelper() + allure_commons.plugin_manager.register(title_helper) def pytest_configure(config): report_dir = config.option.allure_report_dir clean = config.option.clean_alluredir - test_helper = list(allure_commons.plugin_manager.get_plugin_manager()._name2plugin.values())[0] - test_helper.config = config + test_helper = AllureTestHelper(config) + allure_commons.plugin_manager.register(test_helper) config.add_cleanup(cleanup_factory(test_helper)) if report_dir: From 5e93c9720cf7cd1a0a6e2d81717b2a791764123b Mon Sep 17 00:00:00 2001 From: Artem Ryabkov Date: Mon, 7 Dec 2020 01:42:01 +0300 Subject: [PATCH 3/3] Cleaned up, added comments --- allure-pytest/src/helper.py | 5 +---- allure-pytest/src/plugin.py | 1 + 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/allure-pytest/src/helper.py b/allure-pytest/src/helper.py index 5c0f49f7..5333ddee 100644 --- a/allure-pytest/src/helper.py +++ b/allure-pytest/src/helper.py @@ -8,13 +8,10 @@ class AllureTitleHelper(object): - - def __init__(self, config=None): - self.config = config - @allure_commons.hookimpl def decorate_as_title(self, test_title): def decorator(func): + # pytest.fixture wraps function, so we need to get it directly if getattr(func, '__pytest_wrapped__', None): function = func.__pytest_wrapped__.obj else: diff --git a/allure-pytest/src/plugin.py b/allure-pytest/src/plugin.py index cabcc513..deea01d2 100644 --- a/allure-pytest/src/plugin.py +++ b/allure-pytest/src/plugin.py @@ -111,6 +111,7 @@ def clean_up(): def pytest_addhooks(pluginmanager): + # Need register title hooks before conftest init title_helper = AllureTitleHelper() allure_commons.plugin_manager.register(title_helper)