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..5333ddee 100644 --- a/allure-pytest/src/helper.py +++ b/allure-pytest/src/helper.py @@ -3,21 +3,29 @@ 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): +class AllureTitleHelper(object): + @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: + function = func + function.__allure_display_name__ = test_title + return func + + return decorator + +class AllureTestHelper(object): def __init__(self, config): self.config = config - @allure_commons.hookimpl - def decorate_as_title(self, test_title): - allure_title = getattr(pytest.mark, ALLURE_DISPLAY_NAME_MARK) - return allure_title(test_title) - @allure_commons.hookimpl def decorate_as_description(self, test_description): allure_description = getattr(pytest.mark, ALLURE_DESCRIPTION_MARK) 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..deea01d2 100644 --- a/allure-pytest/src/plugin.py +++ b/allure-pytest/src/plugin.py @@ -9,10 +9,9 @@ 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_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,12 +110,17 @@ def clean_up(): return clean_up +def pytest_addhooks(pluginmanager): + # Need register title hooks before conftest init + 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 = AllureTestHelper(config) - # TODO: Why helper is present anyway? allure_commons.plugin_manager.register(test_helper) config.add_cleanup(cleanup_factory(test_helper)) @@ -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") + ) + ) + )