From c9787ac2a99a8dab6ce84577f06c8536bffff224 Mon Sep 17 00:00:00 2001 From: Stas Seliverstov Date: Mon, 21 Dec 2020 15:39:30 +0300 Subject: [PATCH 1/4] robot testplan --- allure-python-commons/src/mapping.py | 18 ++++++++++-- allure-python-commons/src/types.py | 1 - .../examples/testplan/testplan.rst | 21 ++++++++++++++ .../src/listener/__init__.py | 3 +- .../src/listener/allure_listener.py | 5 ++-- .../src/listener/allure_testplan.py | 28 +++++++++++++++++++ allure-robotframework/src/listener/utils.py | 16 ++++------- .../test/run_robot_library.py | 12 +++++++- .../test/testplan/testplan.robot | 16 +++++++++++ 9 files changed, 101 insertions(+), 19 deletions(-) create mode 100644 allure-robotframework/examples/testplan/testplan.rst create mode 100644 allure-robotframework/src/listener/allure_testplan.py create mode 100644 allure-robotframework/test/testplan/testplan.robot diff --git a/allure-python-commons/src/mapping.py b/allure-python-commons/src/mapping.py index 2a80fd23..59a09713 100644 --- a/allure-python-commons/src/mapping.py +++ b/allure-python-commons/src/mapping.py @@ -1,6 +1,6 @@ from itertools import chain, islice import attr - +import re from allure_commons.types import Severity, LabelType, LinkType from allure_commons.types import ALLURE_UNIQUE_LABELS from allure_commons.model2 import Label, Link @@ -8,6 +8,16 @@ TAG_PREFIX = "allure" +semi_sep = re.compile("allure[\.\w]+:") +eq_sep = re.compile("allure[\.\w]+=") + + +def allure_tag_sep(tag): + if semi_sep.search(tag): + return ":" + if eq_sep.search(tag): + return "=" + def __is(kind, t): return kind in [v for k, v in t.__dict__.items() if not k.startswith('__')] @@ -39,7 +49,8 @@ def parse_tag(tag, issue_pattern=None, link_pattern=None): >>> parse_tag("allure.foo:1") Label(name='tag', value='allure.foo:1') """ - schema, value = islice(chain(tag.split(':', 1), [None]), 2) + sep = allure_tag_sep(tag) + schema, value = islice(chain(tag.split(sep, 1), [None]), 2) prefix, kind, name = islice(chain(schema.split('.'), [None], [None]), 3) if tag in [severity for severity in Severity]: @@ -57,6 +68,9 @@ def parse_tag(tag, issue_pattern=None, link_pattern=None): if __is(kind, LabelType): return Label(name=kind, value=value) + if kind == "id": + return Label(name=LabelType.ID, value=value) + if kind == "label" and name is not None: return Label(name=name, value=value) diff --git a/allure-python-commons/src/types.py b/allure-python-commons/src/types.py index d2fef791..3f9f2df5 100644 --- a/allure-python-commons/src/types.py +++ b/allure-python-commons/src/types.py @@ -32,7 +32,6 @@ class LabelType(str): FRAMEWORK = 'framework' LANGUAGE = 'language' - class AttachmentType(Enum): def __init__(self, mime_type, extension): diff --git a/allure-robotframework/examples/testplan/testplan.rst b/allure-robotframework/examples/testplan/testplan.rst new file mode 100644 index 00000000..404d171d --- /dev/null +++ b/allure-robotframework/examples/testplan/testplan.rst @@ -0,0 +1,21 @@ + +.. code:: robotframework + + *** Test Cases *** + First testcase + No Operation + + Second testcase + No Operation + + +.. code:: robotframework + + *** Test Cases *** + Test case with allure id + [Tags] allure.id=123 + No Operation + + One more case with allure id + [Tags] allure.id=777 + No Operation diff --git a/allure-robotframework/src/listener/__init__.py b/allure-robotframework/src/listener/__init__.py index 24ef9b55..d2640a4e 100644 --- a/allure-robotframework/src/listener/__init__.py +++ b/allure-robotframework/src/listener/__init__.py @@ -1,3 +1,4 @@ from allure_robotframework.robot_listener import allure_robotframework +from allure_robotframework.allure_testplan import allure_testplan as testplan -__all__ = ['allure_robotframework'] +__all__ = ['allure_robotframework', "testplan"] diff --git a/allure-robotframework/src/listener/allure_listener.py b/allure-robotframework/src/listener/allure_listener.py index 784a5838..89fab2c9 100644 --- a/allure-robotframework/src/listener/allure_listener.py +++ b/allure-robotframework/src/listener/allure_listener.py @@ -149,15 +149,14 @@ def stop_test(self, _, attributes, messages): test_result.labels.append(Label(name=LabelType.HOST, value=self._host)) test_result.labels.append(Label(name=LabelType.THREAD, value=pool_id())) test_result.labels.extend(allure_tags(attributes)) + tags = attributes.get('tags', ()) + test_result.labels.extend(allure_labels(tags)) test_result.statusDetails = StatusDetails(message=attributes.get('message'), trace=self._current_tb) if attributes.get('critical') == 'yes': test_result.labels.append(Label(name=LabelType.SEVERITY, value=Severity.CRITICAL)) - for label_type in (LabelType.EPIC, LabelType.FEATURE, LabelType.STORY): - test_result.labels.extend(allure_labels(attributes, label_type)) - for link_type in (LinkType.ISSUE, LinkType.TEST_CASE, LinkType.LINK): test_result.links.extend(allure_links(attributes, link_type)) diff --git a/allure-robotframework/src/listener/allure_testplan.py b/allure-robotframework/src/listener/allure_testplan.py new file mode 100644 index 00000000..3730bab7 --- /dev/null +++ b/allure-robotframework/src/listener/allure_testplan.py @@ -0,0 +1,28 @@ +from robot.api import SuiteVisitor +from allure_commons.utils import get_testplan +from allure_robotframework.utils import allure_labels +from allure_commons.types import LabelType + + +# noinspection PyPep8Naming +class allure_testplan(SuiteVisitor): + def __init__(self): + self.testplan = get_testplan() + + def start_suite(self, suite): + if self.testplan: + # included_tests = [test["selector"] for test in self.testplan] + suite.filter(included_tests=self.included_tests(suite)) + + def included_tests(self, suite): + included_tests = [""] + for test in suite.tests: + allure_id = None + for label in allure_labels(test.tags): + if label.name == LabelType.ID: + allure_id = str(label.value) + if allure_id and any([allure_id == item.get("id", None) for item in self.testplan]): + included_tests.append(test.name) + + return included_tests or [test["selector"] for test in self.testplan] + diff --git a/allure-robotframework/src/listener/utils.py b/allure-robotframework/src/listener/utils.py index 02be3c31..8060de07 100644 --- a/allure-robotframework/src/listener/utils.py +++ b/allure-robotframework/src/listener/utils.py @@ -3,6 +3,7 @@ from allure_commons.model2 import Status, Label, Parameter, Link from allure_commons.types import LabelType from allure_robotframework.types import RobotStatus +from allure_commons.mapping import parse_tag, labels_set, allure_tag_sep def get_allure_status(status): @@ -40,19 +41,12 @@ def get_allure_suites(longname): def allure_tags(attributes): - return [Label(LabelType.TAG, tag) for tag in attributes.get('tags', ())] + return [Label(LabelType.TAG, tag) for tag in attributes.get('tags', ()) if not allure_tag_sep(tag)] -def allure_labels(attributes, prefix): - tags = attributes.get('tags', ()) - - def is_label(label): - return label.startswith("{label}:".format(label=prefix)) - - def label_value(label): - return label.split(':')[1] or 'unknown' - - return [Label(name=prefix, value=label_value(tag)) for tag in tags if is_label(tag)] +def allure_labels(tags): + parsed = [parse_tag(item) for item in tags] + return labels_set(list(filter(lambda x: isinstance(x, Label), parsed))) def allure_links(attributes, prefix): diff --git a/allure-robotframework/test/run_robot_library.py b/allure-robotframework/test/run_robot_library.py index 980b6fb4..4b9f36f0 100644 --- a/allure-robotframework/test/run_robot_library.py +++ b/allure-robotframework/test/run_robot_library.py @@ -1,5 +1,5 @@ import os -from tempfile import mkdtemp +from tempfile import mkdtemp, mkstemp from robot import run from multiprocessing import Process from allure_commons_test.report import AllureReport @@ -10,6 +10,14 @@ def run_robot_with_allure(*args, **kwargs): targets = map(lambda target: os.path.join(root, target), args) tmp_path = mkdtemp(dir=os.environ.get('TEST_TMP', '/tmp')) + if "testplan" in kwargs: + # kwargs.pop("testplan") + kwargs["prerunmodifier"] = "allure_robotframework.testplan" + file, filename = mkstemp(suffix=".json", dir=tmp_path) + os.environ["ALLURE_TESTPLAN_PATH"] = filename + with os.fdopen(file, 'w') as tmp: + tmp.write(kwargs["testplan"]) + def run_robot(path, **kw): # ToDo: fix it (_core not works correctly with multiprocessing) @@ -38,4 +46,6 @@ def run_robot(path, **kw): robot_process.start() robot_process.join() + os.environ.pop("ALLURE_TESTPLAN_PATH", None) + return AllureReport(tmp_path) diff --git a/allure-robotframework/test/testplan/testplan.robot b/allure-robotframework/test/testplan/testplan.robot new file mode 100644 index 00000000..7ba18820 --- /dev/null +++ b/allure-robotframework/test/testplan/testplan.robot @@ -0,0 +1,16 @@ +*** Settings *** +Library ../run_robot_library.py +Library ../test_allure_library.py + + +*** Variables ** +${PLAN_A} \{ +... "version":"1.0", +... "tests": [ +... { "id": "123", "selector": "Second testcase"} +... ] +... \} + +*** Test Case *** +Failed Test Case With Message + ${allure_report} Run Robot With Allure examples/testplan/testplan.rst testplan=${PLAN_A} \ No newline at end of file From 7acc6190ca8f7b21479a8922c7e6a6bff9b5bbb4 Mon Sep 17 00:00:00 2001 From: Stas Seliverstov Date: Mon, 21 Dec 2020 16:02:00 +0300 Subject: [PATCH 2/4] fix static check --- allure-robotframework/src/listener/allure_testplan.py | 1 - 1 file changed, 1 deletion(-) diff --git a/allure-robotframework/src/listener/allure_testplan.py b/allure-robotframework/src/listener/allure_testplan.py index 3730bab7..342d9792 100644 --- a/allure-robotframework/src/listener/allure_testplan.py +++ b/allure-robotframework/src/listener/allure_testplan.py @@ -25,4 +25,3 @@ def included_tests(self, suite): included_tests.append(test.name) return included_tests or [test["selector"] for test in self.testplan] - From 0cca71c6358c9e6204e07c3861fdbcca26d82167 Mon Sep 17 00:00:00 2001 From: Stas Seliverstov Date: Mon, 21 Dec 2020 16:08:18 +0300 Subject: [PATCH 3/4] fix static checks --- allure-python-commons/src/mapping.py | 4 ++-- allure-python-commons/src/types.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/allure-python-commons/src/mapping.py b/allure-python-commons/src/mapping.py index 59a09713..311be1a8 100644 --- a/allure-python-commons/src/mapping.py +++ b/allure-python-commons/src/mapping.py @@ -8,8 +8,8 @@ TAG_PREFIX = "allure" -semi_sep = re.compile("allure[\.\w]+:") -eq_sep = re.compile("allure[\.\w]+=") +semi_sep = re.compile(r"allure[\.\w]+:") +eq_sep = re.compile(r"allure[\.\w]+=") def allure_tag_sep(tag): diff --git a/allure-python-commons/src/types.py b/allure-python-commons/src/types.py index 3f9f2df5..d2fef791 100644 --- a/allure-python-commons/src/types.py +++ b/allure-python-commons/src/types.py @@ -32,6 +32,7 @@ class LabelType(str): FRAMEWORK = 'framework' LANGUAGE = 'language' + class AttachmentType(Enum): def __init__(self, mime_type, extension): From c37c7a5e9ba96b068d5c03e7fec258d297183080 Mon Sep 17 00:00:00 2001 From: Stas Seliverstov Date: Mon, 21 Dec 2020 16:22:18 +0300 Subject: [PATCH 4/4] fix test --- allure-robotframework/examples/label/__init__.rst | 2 +- allure-robotframework/examples/label/testcase_bdd_label.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/allure-robotframework/examples/label/__init__.rst b/allure-robotframework/examples/label/__init__.rst index 5f76f33a..334faa45 100644 --- a/allure-robotframework/examples/label/__init__.rst +++ b/allure-robotframework/examples/label/__init__.rst @@ -2,4 +2,4 @@ .. code:: robotframework *** Settings *** - Force Tags epic:Tag + Force Tags allure.epic:Tag diff --git a/allure-robotframework/examples/label/testcase_bdd_label.rst b/allure-robotframework/examples/label/testcase_bdd_label.rst index cc274cb9..f08ac8fa 100644 --- a/allure-robotframework/examples/label/testcase_bdd_label.rst +++ b/allure-robotframework/examples/label/testcase_bdd_label.rst @@ -2,9 +2,9 @@ .. code:: robotframework *** Settings *** - Force Tags feature:Label + Force Tags allure.feature:Label *** Test Case *** Test Cases With BDD Labels - [Tags] story:Test case BDD labels + [Tags] allure.story:Test case BDD labels No Operation