Skip to content

Commit 5ebe2d1

Browse files
authored
Fix behave hooks reporting (via #623)
1 parent 50cb0ec commit 5ebe2d1

File tree

6 files changed

+82
-75
lines changed

6 files changed

+82
-75
lines changed

allure-behave/features/hook.feature

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ Feature: Hook
2121
"""
2222
When I run behave with allure formatter
2323
Then allure report has a scenario with name "Scenario with "<when> <where>" hook"
24-
And this scenario has <when> fixture "<when>_<where>"
24+
And this scenario has <when> fixture "<when> <where>"
2525

2626
Then allure report has a scenario with name "Another scenario with "<when> <where>" hook"
27-
And this scenario has <when> fixture "<when>_<where>"
27+
And this scenario has <when> fixture "<when> <where>"
2828

2929
Examples: fixtures
3030
| when | where |
@@ -55,10 +55,10 @@ Feature: Hook
5555
"""
5656
When I run behave with allure formatter
5757
Then allure report has a scenario with name "Scenario with "<when> <where>" hook"
58-
And this scenario has <when> fixture "<when>_<where>"
58+
And this scenario has <when> fixture "<when> <where> @tag_for_hook"
5959

6060
Then allure report has a scenario with name "Another scenario without "<when> <where>" hook"
61-
And this scenario has not <when> fixture "<when>_<where>"
61+
And this scenario has not <when> fixture "<when> <where> @tag_for_hook"
6262

6363
Examples: fixtures
6464
| when | where |
@@ -89,10 +89,10 @@ Feature: Hook
8989
"""
9090
When I run behave with allure formatter
9191
Then allure report has a scenario with name "Scenario with "<when> <where>" hook"
92-
And this scenario has <when> fixture "<when>_<where>"
92+
And this scenario has <when> fixture "<when> <where> @tag_for_hook"
9393

9494
Then allure report has a scenario with name "Another scenario with "<when> <where>" hook"
95-
And this scenario has <when> fixture "<when>_<where>"
95+
And this scenario has <when> fixture "<when> <where> @tag_for_hook"
9696

9797
Examples: fixtures
9898
| when | where |
@@ -121,10 +121,10 @@ Feature: Hook
121121
"""
122122
When I run behave with allure formatter
123123
Then allure report has a scenario with name "Scenario with "<when> <where>" hook"
124-
And this scenario has <when> fixture "<when>_<where>"
124+
And this scenario has <when> fixture "<when> <where>"
125125

126126
Then allure report has a scenario with name "Another scenario with "<when> <where>" hook"
127-
And this scenario has <when> fixture "<when>_<where>"
127+
And this scenario has <when> fixture "<when> <where>"
128128

129129
Examples: fixtures
130130
| when | where |
@@ -153,10 +153,10 @@ Feature: Hook
153153
"""
154154
When I run behave with allure formatter
155155
Then allure report has a scenario with name "Scenario with "<when> <where>" hook"
156-
And this scenario has <when> fixture "<when>_<where>"
156+
And this scenario has <when> fixture "<when> <where>"
157157

158158
Then allure report has a scenario with name "Another scenario with "<when> <where>" hook"
159-
And this scenario has <when> fixture "<when>_<where>"
159+
And this scenario has <when> fixture "<when> <where>"
160160

161161
Examples: fixtures
162162
| when | where |
@@ -183,7 +183,7 @@ Feature: Hook
183183
"""
184184
When I run behave with allure formatter
185185
Then allure report has a scenario with name "Scenario with "before_feature" hook and attachment"
186-
And this scenario has before fixture "before_feature"
186+
And this scenario has before fixture "before feature"
187187
And this before has attachment
188188

189189

@@ -207,7 +207,7 @@ Feature: Hook
207207
"""
208208
When I run behave with allure formatter
209209
Then allure report has a scenario with name "Scenario with "<when> <where>" hook and step inside"
210-
And this scenario has <when> fixture "<when>_<where>"
210+
And this scenario has <when> fixture "<when> <where>"
211211
And this <when> contains step "Step inside fixture"
212212

213213
Examples: fixtures
@@ -238,7 +238,7 @@ Feature: Hook
238238
"""
239239
When I run behave with allure formatter
240240
Then allure report has a scenario with name "Scenario with "<when> <where>" hook and step as function inside"
241-
And this scenario has <when> fixture "<when>_<where>"
241+
And this scenario has <when> fixture "<when> <where>"
242242
And this <when> contains step "Step function"
243243

244244
Examples: fixtures

allure-behave/features/steps/behave_steps.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,8 @@ def run_behave_with_allure(context, **kwargs):
4949
stream_opener = StreamOpener(filename=result_tmp_dir)
5050
model_runner = ModelRunner(config, context.feature_definition)
5151
model_runner.formatters = make_formatters(config, [stream_opener])
52-
model_runner.formatters[0].listener.fixture_context.enter()
5352
model_runner.hooks = getattr(context, 'globals', dict())
5453
model_runner.run()
55-
model_runner.formatters[0].listener.__del__()
5654
context.allure_report = AllureReport(result_tmp_dir)
5755

5856
os.environ.pop("ALLURE_TESTPLAN_PATH", None)

allure-behave/src/formatter.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ def _wrap_scenario(self, scenarios):
2727
scenario.run = allure_commons.test(scenario.run, context={'scenario': scenario})
2828
is_planned_scenario(scenario, self.testplan)
2929

30+
def uri(self, uri):
31+
self.listener.start_file()
32+
3033
def feature(self, feature):
3134
self._wrap_scenario(feature.scenarios)
32-
self.listener.start_feature()
3335

3436
def step(self, step):
3537
self.listener.schedule_step(step)
@@ -42,3 +44,6 @@ def result(self, result):
4244

4345
def eof(self):
4446
self.listener.stop_feature()
47+
48+
def close_stream(self):
49+
self.listener.stop_session()

allure-behave/src/listener.py

Lines changed: 47 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,7 @@
2323
from allure_behave.utils import scenario_labels
2424
from allure_behave.utils import get_fullname
2525
from allure_behave.utils import TEST_PLAN_SKIP_REASON
26-
27-
28-
BEFORE_FIXTURES = ['before_all', 'before_tag', 'before_feature', 'before_scenario']
29-
AFTER_FIXTURES = ['after_all', 'after_tag', 'after_feature', 'after_scenario']
30-
FIXTURES = BEFORE_FIXTURES + AFTER_FIXTURES
26+
from allure_behave.utils import get_hook_name
3127

3228

3329
class AllureListener(object):
@@ -39,62 +35,46 @@ def __init__(self, behave_config):
3935
self.logger = AllureReporter()
4036
self.current_step_uuid = None
4137
self.current_scenario_uuid = None
42-
self.execution_context = Context()
43-
self.fixture_context = Context()
38+
self.group_context = GroupContext(self.logger)
39+
self.group_context.enter()
4440
self.steps = deque()
4541

46-
def __del__(self):
47-
for group in self.fixture_context.exit():
48-
group.children.extend(self.execution_context)
49-
self.logger.stop_group(group.uuid)
42+
def start_file(self):
43+
self.group_context.enter()
5044

5145
@allure_commons.hookimpl
5246
def start_fixture(self, parent_uuid, uuid, name, parameters):
53-
parameters = [Parameter(name=param_name, value=param_value) for param_name, param_value in parameters.items()]
54-
55-
if name in FIXTURES and not self.fixture_context:
56-
group = TestResultContainer(uuid=uuid4())
57-
self.logger.start_group(group.uuid, group)
58-
self.fixture_context.append(group)
47+
# parameters = [Parameter(name=param_name, value=param_value) for param_name, param_value in parameters.items()]
5948

60-
if name in BEFORE_FIXTURES:
61-
fixture = TestBeforeResult(name=name, start=now(), parameters=parameters)
62-
for group in self.fixture_context:
63-
self.logger.start_before_fixture(group.uuid, uuid, fixture)
49+
if name.startswith("before_"):
50+
name = get_hook_name(name, parameters)
51+
fixture = TestBeforeResult(name=name, start=now(), parameters=None)
52+
group = self.group_context.current_group()
53+
self.logger.start_before_fixture(group.uuid, uuid, fixture)
6454

65-
elif name in AFTER_FIXTURES:
66-
fixture = TestAfterResult(name=name, start=now(), parameters=parameters)
67-
for group in self.fixture_context:
68-
self.logger.start_after_fixture(group.uuid, uuid, fixture)
55+
elif name.startswith("after_"):
56+
name = get_hook_name(name, parameters)
57+
fixture = TestAfterResult(name=name, start=now(), parameters=None)
58+
group = self.group_context.current_group()
59+
self.logger.start_after_fixture(group.uuid, uuid, fixture)
6960

7061
@allure_commons.hookimpl
7162
def stop_fixture(self, parent_uuid, uuid, name, exc_type, exc_val, exc_tb):
72-
if name in FIXTURES:
73-
self.logger.stop_before_fixture(uuid=uuid,
74-
stop=now(),
75-
status=get_status(exc_val),
76-
statusDetails=get_status_details(exc_type, exc_val, exc_tb))
77-
78-
def start_feature(self):
79-
self.execution_context.enter()
80-
self.fixture_context.enter()
63+
self.logger.stop_before_fixture(uuid=uuid,
64+
stop=now(),
65+
status=get_status(exc_val),
66+
statusDetails=get_status_details(exc_type, exc_val, exc_tb))
8167

8268
def stop_feature(self):
83-
uuids = self.execution_context.exit()
84-
for group in self.fixture_context.exit():
85-
group.children.extend(uuids)
86-
self.logger.stop_group(group.uuid)
87-
self.execution_context.extend(uuids)
69+
self.group_context.exit()
8870

8971
@allure_commons.hookimpl
9072
def start_test(self, parent_uuid, uuid, name, parameters, context):
9173
self.start_scenario(context['scenario'])
9274

9375
def start_scenario(self, scenario):
9476
self.current_scenario_uuid = uuid4()
95-
self.fixture_context.enter()
96-
self.execution_context.enter()
97-
self.execution_context.append(self.current_scenario_uuid)
77+
self.group_context.enter()
9878

9979
test_case = TestResult(uuid=self.current_scenario_uuid, start=now())
10080
test_case.name = scenario_name(scenario)
@@ -137,13 +117,9 @@ def stop_scenario(self, scenario):
137117
test_result.statusDetails = status_details
138118
self.logger.close_test(self.current_scenario_uuid)
139119
self.current_step_uuid = None
120+
self.group_context.append_test(self.current_scenario_uuid)
121+
self.group_context.exit()
140122

141-
for group in self.fixture_context.exit():
142-
group.children.append(self.current_scenario_uuid)
143-
self.logger.stop_group(group.uuid)
144-
145-
self.execution_context.exit()
146-
self.execution_context.append(self.current_scenario_uuid)
147123
self.current_scenario_uuid = None
148124

149125
def schedule_step(self, step):
@@ -229,17 +205,30 @@ def add_link(self, url, link_type, name):
229205

230206
test_result.links.append(new_link)
231207

208+
def stop_session(self):
209+
self.group_context.exit()
232210

233-
class Context(list):
234-
def __init__(self, _list=list()):
235-
super(Context, self).__init__(_list)
236-
self._stack = [_list]
237211

238-
def enter(self, _list=list()):
239-
self._stack.append(self[:])
240-
self[:] = _list
241-
return self
212+
class GroupContext(object):
213+
def __init__(self, logger):
214+
self._logger = logger
215+
self._groups = []
216+
217+
def enter(self):
218+
group = TestResultContainer(uuid=uuid4())
219+
self._logger.start_group(group.uuid, group)
220+
self._groups.append(group)
242221

243222
def exit(self):
244-
gone, self[:] = self[:], self._stack.pop()
245-
return gone
223+
group = self._groups.pop()
224+
if group.befores or group.afters:
225+
self._logger.stop_group(group.uuid)
226+
else:
227+
self._logger._items.pop(group.uuid)
228+
229+
def current_group(self):
230+
return self._groups[-1]
231+
232+
def append_test(self, uuid):
233+
for group in self._groups:
234+
group.children.append(uuid)

allure-behave/src/utils.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,21 @@ def get_fullname(scenario):
9898
return "{filename}: {name}".format(filename=scenario.feature.name, name=name)
9999

100100

101+
def get_hook_name(name, parameters):
102+
tag = None
103+
if name in ["before_tag", "after_tag"]:
104+
param_list = list(parameters.items())
105+
if len(param_list) > 1:
106+
tag = param_list[1][1]
107+
else:
108+
tag = param_list[0][1][1]
109+
name = name.replace("_", " ")
110+
if tag:
111+
tag = tag.replace("'", "")
112+
name = f"{name} @{tag}"
113+
return name
114+
115+
101116
def step_status_details(result):
102117
if result.exception:
103118
# workaround for https://github.com/behave/behave/pull/616

allure-behave/tox.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ commands =
2626
# https://github.com/allure-framework/allure-python/issues/321
2727
passenv = HOME
2828

29-
basepython = python3.6
29+
#basepython = python3.6
3030

3131
setenv =
3232
TEST_TMP={envtmpdir}

0 commit comments

Comments
 (0)