| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 4fa3e3a commit e262568
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,19 +1,25 @@ | |||
| 1 | 1 | import os | |
| 2 | 2 | from tempfile import mkdtemp | |
| 3 | + import allure_commons | ||
| 3 | 4 | from allure_commons_test.report import AllureReport | |
| 4 | 5 | from behave.parser import Parser | |
| 5 | 6 | from behave.runner import ModelRunner | |
| 6 | 7 | from behave.configuration import Configuration | |
| 7 | 8 | from behave.formatter._registry import make_formatters | |
| 8 | 9 | from behave.formatter.base import StreamOpener | |
| 9 | - import threading | ||
| 10 | + import tempfile | ||
| 11 | + from contextlib import contextmanager | ||
| 10 | 12 | ||
| 11 | 13 | ||
| 12 | 14 | @given(u'feature definition') | |
| 13 | 15 | @given(u'feature definition {lang}') | |
| 14 | 16 | def feature_definition(context, **kwargs): | |
| 15 | 17 | parser = Parser(language=kwargs.get('lang', None)) | |
| 16 | - context.feature_definition = parser.parse(context.text) | ||
| 18 | + feature = parser.parse(context.text) | ||
| 19 | + if hasattr(context, "feature_definition"): | ||
| 20 | + context.feature_definition.append(feature) | ||
| 21 | + else: | ||
| 22 | + context.feature_definition = [feature] | ||
| 17 | 23 | ||
| 18 | 24 | ||
| 19 | 25 | @given(u'hooks implementation') | |
@@ -22,26 +28,47 @@ def hooks_implementations(context): | |||
| 22 | 28 | exec(context.text, context.globals) | |
| 23 | 29 | ||
| 24 | 30 | ||
| 31 | + @given(u'test plan') | ||
| 32 | + def test_plan_helper(context): | ||
| 33 | + tmp_dir = os.environ.get("TEST_TMP") | ||
| 34 | + file, filename = tempfile.mkstemp(suffix=".json", dir=tmp_dir) | ||
| 35 | + os.environ["ALLURE_TESTPLAN_PATH"] = filename | ||
| 36 | + with os.fdopen(file, 'w') as tmp: | ||
| 37 | + tmp.write(context.text) | ||
| 38 | + context.test_plan = filename | ||
| 39 | + | ||
| 40 | + | ||
| 25 | 41 | @when(u'I run behave with allure formatter') | |
| 26 | 42 | @when(u'I run behave with allure formatter with options "{args}"') | |
| 27 | 43 | def run_behave_with_allure(context, **kwargs): | |
| 28 | - def run(context, **kwargs): | ||
| 44 | + with test_context(): | ||
| 29 | 45 | cmd_args = '-f allure_behave.formatter:AllureFormatter' | |
| 30 | 46 | cmd = '{options} {cmd}'.format(cmd=cmd_args, options=kwargs.get('args', '')) | |
| 31 | 47 | config = Configuration(command_args=cmd) | |
| 32 | - | ||
| 33 | 48 | result_tmp_dir = mkdtemp(dir=os.environ.get('TEST_TMP', None)) | |
| 34 | 49 | stream_opener = StreamOpener(filename=result_tmp_dir) | |
| 35 | - | ||
| 36 | - model_runner = ModelRunner(config, [context.feature_definition]) | ||
| 50 | + model_runner = ModelRunner(config, context.feature_definition) | ||
| 37 | 51 | model_runner.formatters = make_formatters(config, [stream_opener]) | |
| 38 | 52 | model_runner.formatters[0].listener.fixture_context.enter() | |
| 39 | 53 | model_runner.hooks = getattr(context, 'globals', dict()) | |
| 40 | 54 | model_runner.run() | |
| 41 | - | ||
| 42 | 55 | model_runner.formatters[0].listener.__del__() | |
| 43 | 56 | context.allure_report = AllureReport(result_tmp_dir) | |
| 44 | 57 | ||
| 45 | - behave_tread = threading.Thread(target=run, args=(context,), kwargs=kwargs) | ||
| 46 | - behave_tread.start() | ||
| 47 | - behave_tread.join() | ||
| 58 | + os.environ.pop("ALLURE_TESTPLAN_PATH", None) | ||
| 59 | + | ||
| 60 | + | ||
| 61 | + @contextmanager | ||
| 62 | + def test_context(): | ||
| 63 | + def _unregister_plugins(): | ||
| 64 | + plugins = [] | ||
| 65 | + for name, plugin in allure_commons.plugin_manager.list_name_plugin(): | ||
| 66 | + allure_commons.plugin_manager.unregister(plugin=plugin, name=name) | ||
| 67 | + plugins.append(plugin) | ||
| 68 | + return plugins | ||
| 69 | + | ||
| 70 | + plugins = _unregister_plugins() | ||
| 71 | + yield | ||
| 72 | + _unregister_plugins() | ||
| 73 | + for plugin in plugins: | ||
| 74 | + allure_commons.plugin_manager.register(plugin) | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,86 @@ | |||
| 1 | + Feature: Test plan | ||
| 2 | + Scenario: Select scenarios by fullname | ||
| 3 | + Given feature definition | ||
| 4 | + """ | ||
| 5 | + Feature: Test plan example | ||
| 6 | + | ||
| 7 | + Scenario: Scenario with passed step | ||
| 8 | + Given passed step | ||
| 9 | + | ||
| 10 | + Scenario: Ignored scenario | ||
| 11 | + Given passed step | ||
| 12 | + """ | ||
| 13 | + Given feature definition | ||
| 14 | + """ | ||
| 15 | + Feature: Another Test plan example | ||
| 16 | + | ||
| 17 | + Scenario: Another scenario with passed step | ||
| 18 | + Given passed step | ||
| 19 | + | ||
| 20 | + Scenario: Another ignored scenario | ||
| 21 | + Given passed step | ||
| 22 | + """ | ||
| 23 | + Given test plan | ||
| 24 | + """ | ||
| 25 | + { | ||
| 26 | + "version":"1.0", | ||
| 27 | + "tests": [ | ||
| 28 | + { | ||
| 29 | + "selector": "<string>:Scenario with passed step" | ||
| 30 | + }, | ||
| 31 | + { | ||
| 32 | + "selector": "<string>:Another scenario with passed step" | ||
| 33 | + } | ||
| 34 | + ] | ||
| 35 | + } | ||
| 36 | + """ | ||
| 37 | + When I run behave with allure formatter | ||
| 38 | + Then allure report has a scenario with name "Scenario with passed step" | ||
| 39 | + Then allure report has not a scenario with name "Ignored scenario" | ||
| 40 | + Then allure report has a scenario with name "Another scenario with passed step" | ||
| 41 | + Then allure report has not a scenario with name "Another ignored scenario" | ||
| 42 | + | ||
| 43 | + Scenario: Select scenarios by allureid | ||
| 44 | + Given feature definition | ||
| 45 | + """ | ||
| 46 | + Feature: Test plan example | ||
| 47 | + | ||
| 48 | + @allure.as_id:1 | ||
| 49 | + Scenario: Scenario with passed step | ||
| 50 | + Given passed step | ||
| 51 | + | ||
| 52 | + @allure.as_id:2 | ||
| 53 | + Scenario: Ignored scenario | ||
| 54 | + Given passed step | ||
| 55 | + """ | ||
| 56 | + Given feature definition | ||
| 57 | + """ | ||
| 58 | + Feature: Another Test plan example | ||
| 59 | + | ||
| 60 | + @allure.as_id:3 | ||
| 61 | + Scenario: Another scenario with passed step | ||
| 62 | + Given passed step | ||
| 63 | + | ||
| 64 | + @allure.as_id:4 | ||
| 65 | + Scenario: Another ignored scenario | ||
| 66 | + Given passed step | ||
| 67 | + """ | ||
| 68 | + Given test plan | ||
| 69 | + """ | ||
| 70 | + { | ||
| 71 | + "version":"1.0", | ||
| 72 | + "tests": [ | ||
| 73 | + { | ||
| 74 | + "id": "1" | ||
| 75 | + }, | ||
| 76 | + { | ||
| 77 | + "id": "3" | ||
| 78 | + } | ||
| 79 | + ] | ||
| 80 | + } | ||
| 81 | + """ | ||
| 82 | + When I run behave with allure formatter | ||
| 83 | + Then allure report has a scenario with name "Scenario with passed step" | ||
| 84 | + Then allure report has not a scenario with name "Ignored scenario" | ||
| 85 | + Then allure report has a scenario with name "Another scenario with passed step" | ||
| 86 | + Then allure report has not a scenario with name "Another ignored scenario" | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,6 +3,8 @@ | |||
| 3 | 3 | import allure_commons | |
| 4 | 4 | from allure_commons.logger import AllureFileLogger | |
| 5 | 5 | from allure_behave.listener import AllureListener | |
| 6 | + from allure_commons.utils import get_testplan | ||
| 7 | + from allure_behave.utils import is_planned_scenario | ||
| 6 | 8 | ||
| 7 | 9 | ||
| 8 | 10 | class AllureFormatter(Formatter): | |
@@ -15,12 +17,15 @@ def __init__(self, stream_opener, config): | |||
| 15 | 17 | allure_commons.plugin_manager.register(self.listener) | |
| 16 | 18 | allure_commons.plugin_manager.register(file_logger) | |
| 17 | 19 | ||
| 20 | + self.testplan = get_testplan() | ||
| 21 | + | ||
| 18 | 22 | def _wrap_scenario(self, scenarios): | |
| 19 | 23 | for scenario in scenarios: | |
| 20 | 24 | if isinstance(scenario, ScenarioOutline): | |
| 21 | 25 | self._wrap_scenario(scenario) | |
| 22 | 26 | else: | |
| 23 | 27 | scenario.run = allure_commons.test(scenario.run, context={'scenario': scenario}) | |
| 28 | + is_planned_scenario(scenario, self.testplan) | ||
| 24 | 29 | ||
| 25 | 30 | def feature(self, feature): | |
| 26 | 31 | self._wrap_scenario(feature.scenarios) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,6 +22,7 @@ | |||
| 22 | 22 | from allure_behave.utils import scenario_links | |
| 23 | 23 | from allure_behave.utils import scenario_labels | |
| 24 | 24 | from allure_behave.utils import get_fullname | |
| 25 | + from allure_behave.utils import TEST_PLAN_SKIP_REASON | ||
| 25 | 26 | ||
| 26 | 27 | ||
| 27 | 28 | BEFORE_FIXTURES = ['before_all', 'before_tag', 'before_feature', 'before_scenario'] | |
@@ -114,7 +115,8 @@ def stop_test(self, parent_uuid, uuid, name, context, exc_type, exc_val, exc_tb) | |||
| 114 | 115 | self.stop_scenario(context['scenario']) | |
| 115 | 116 | ||
| 116 | 117 | def stop_scenario(self, scenario): | |
| 117 | - if scenario.status == 'skipped' and not self.behave_config.show_skipped: | ||
| 118 | + if scenario.status == 'skipped' \ | ||
| 119 | + and not self.behave_config.show_skipped or scenario.skip_reason == TEST_PLAN_SKIP_REASON: | ||
| 118 | 120 | self.logger.drop_test(self.current_scenario_uuid) | |
| 119 | 121 | else: | |
| 120 | 122 | status = scenario_status(scenario) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,6 +11,7 @@ | |||
| 11 | 11 | from allure_commons.utils import format_exception, format_traceback | |
| 12 | 12 | from allure_commons.mapping import parse_tag, labels_set | |
| 13 | 13 | ||
| 14 | + TEST_PLAN_SKIP_REASON = "Not in allure test plan" | ||
| 14 | 15 | ||
| 15 | 16 | STATUS = { | |
| 16 | 17 | 'passed': Status.PASSED, | |
@@ -114,3 +115,15 @@ def step_table(step): | |||
| 114 | 115 | table = [','.join(step.table.headings)] | |
| 115 | 116 | [table.append(','.join(list(row))) for row in step.table.rows] | |
| 116 | 117 | return '\n'.join(table) | |
| 118 | + | ||
| 119 | + | ||
| 120 | + def is_planned_scenario(scenario, test_plan): | ||
| 121 | + if test_plan: | ||
| 122 | + fullname = get_fullname(scenario) | ||
| 123 | + labels = scenario_labels(scenario) | ||
| 124 | + id_labels = list(filter(lambda label: label.name == LabelType.ID, labels)) | ||
| 125 | + allure_id = id_labels[0].value if id_labels else None | ||
| 126 | + for item in test_plan: | ||
| 127 | + if (allure_id and allure_id == item.get("id")) or fullname == item.get("selector"): | ||
| 128 | + return | ||
| 129 | + scenario.skip(reason=TEST_PLAN_SKIP_REASON) | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,11 +3,10 @@ | |||
| 3 | 3 | import allure | |
| 4 | 4 | import allure_commons | |
| 5 | 5 | import os | |
| 6 | - import json | ||
| 7 | 6 | ||
| 8 | 7 | from allure_commons.types import LabelType | |
| 9 | 8 | from allure_commons.logger import AllureFileLogger | |
| 10 | - | ||
| 9 | + from allure_commons.utils import get_testplan | ||
| 11 | 10 | ||
| 12 | 11 | from allure_pytest.utils import allure_label, allure_labels, allure_full_name | |
| 13 | 12 | from allure_pytest.helper import AllureTestHelper | |
@@ -148,13 +147,7 @@ def select_by_labels(items, config): | |||
| 148 | 147 | ||
| 149 | 148 | ||
| 150 | 149 | def select_by_testcase(items): | |
| 151 | - planned_tests = [] | ||
| 152 | - file_path = os.environ.get("ALLURE_TESTPLAN_PATH") | ||
| 153 | - | ||
| 154 | - if file_path: | ||
| 155 | - with open(file_path, 'r') as plan_file: | ||
| 156 | - plan = json.load(plan_file) | ||
| 157 | - planned_tests = plan.get("tests", []) | ||
| 150 | + planned_tests = get_testplan() | ||
| 158 | 151 | ||
| 159 | 152 | if planned_tests: | |
| 160 | 153 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,13 +5,15 @@ | |||
| 5 | 5 | import six | |
| 6 | 6 | import time | |
| 7 | 7 | import uuid | |
| 8 | + import json | ||
| 8 | 9 | import socket | |
| 9 | 10 | import inspect | |
| 10 | 11 | import hashlib | |
| 11 | 12 | import platform | |
| 12 | 13 | import threading | |
| 13 | 14 | import traceback | |
| 14 | 15 | import collections | |
| 16 | + | ||
| 15 | 17 | from functools import partial | |
| 16 | 18 | ||
| 17 | 19 | ||
@@ -387,3 +389,15 @@ def format_exception(etype, value): | |||
| 387 | 389 | "AssertionError: \\nExpected:...but:..." | |
| 388 | 390 | """ | |
| 389 | 391 | return '\n'.join(format_exception_only(etype, value)) if etype or value else None | |
| 392 | + | ||
| 393 | + | ||
| 394 | + def get_testplan(): | ||
| 395 | + planned_tests = [] | ||
| 396 | + file_path = os.environ.get("ALLURE_TESTPLAN_PATH") | ||
| 397 | + | ||
| 398 | + if file_path: | ||
| 399 | + with open(file_path, 'r') as plan_file: | ||
| 400 | + plan = json.load(plan_file) | ||
| 401 | + planned_tests = plan.get("tests", []) | ||
| 402 | + | ||
| 403 | + return planned_tests | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments