Skip to content

Commit 2d26351

Browse files
authored
Now you can use allure steps in behave fixtures (fixes #128) (#160)
now you can use allure steps in behave fixtures
1 parent 55aef68 commit 2d26351

File tree

4 files changed

+99
-22
lines changed

4 files changed

+99
-22
lines changed

allure-behave/features/hook.feature

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,64 @@ Feature: Hook
185185
Then allure report has a scenario with name "Scenario with "before_feature" hook and attachment"
186186
And this scenario has before fixture "before_feature"
187187
And this before has attachment
188+
189+
190+
Scenario Outline: Hook step as context
191+
Given feature definition
192+
"""
193+
Feature: Hook
194+
Scenario: Scenario with "<when> <where>" hook and step inside
195+
Given simple passed step
196+
"""
197+
And hooks implementation
198+
"""
199+
import allure
200+
import allure_commons
201+
202+
203+
@allure_commons.fixture
204+
def <when>_<where>(context, <where>):
205+
with allure.step('Step inside fixture'):
206+
pass
207+
"""
208+
When I run behave with allure formatter
209+
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>"
211+
And this <when> contains step "Step inside fixture"
212+
213+
Examples: fixtures
214+
| when | where |
215+
| before | scenario |
216+
| after | scenario |
217+
218+
219+
Scenario Outline: Hook step as function
220+
Given feature definition
221+
"""
222+
Feature: Hook
223+
Scenario: Scenario with "<when> <where>" hook and step as function inside
224+
Given simple passed step
225+
"""
226+
And hooks implementation
227+
"""
228+
import allure
229+
import allure_commons
230+
231+
@allure.step('Step function')
232+
def step():
233+
pass
234+
235+
@allure_commons.fixture
236+
def <when>_<where>(context):
237+
step()
238+
"""
239+
When I run behave with allure formatter
240+
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>"
242+
And this <when> contains step "Step function"
243+
244+
Examples: fixtures
245+
| when | where |
246+
| before | all |
247+
| after | all |
248+

allure-behave/src/formatter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def match(self, match):
3333
self.listener.match_step(match)
3434

3535
def result(self, result):
36-
self.listener.stop_step(result)
36+
self.listener.stop_behave_step(result)
3737

3838
def eof(self):
3939
self.listener.stop_feature()

allure-behave/src/listener.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@
1919
from allure_behave.utils import scenario_history_id
2020
from allure_behave.utils import step_status, step_status_details
2121
from allure_behave.utils import scenario_status, scenario_status_details
22-
from allure_behave.utils import fixture_status, fixture_status_details
2322
from allure_behave.utils import step_table
23+
from allure_behave.utils import get_status, get_status_details
24+
2425

2526

2627
BEFORE_FIXTURES = ['before_all', 'before_tag', 'before_feature', 'before_scenario']
@@ -63,9 +64,10 @@ def start_fixture(self, parent_uuid, uuid, name, parameters):
6364
@allure_commons.hookimpl
6465
def stop_fixture(self, parent_uuid, uuid, name, exc_type, exc_val, exc_tb):
6566
if name in FIXTURES:
66-
status = fixture_status(exc_val, exc_tb)
67-
status_details = fixture_status_details(exc_val, exc_tb)
68-
self.logger.stop_before_fixture(uuid=uuid, stop=now(), status=status, statusDetails=status_details)
67+
self.logger.stop_before_fixture(uuid=uuid,
68+
stop=now(),
69+
status=get_status(exc_val),
70+
statusDetails=get_status_details(exc_type, exc_val, exc_tb))
6971

7072
def start_feature(self):
7173
self.execution_context.enter()
@@ -120,9 +122,9 @@ def schedule_step(self, step):
120122

121123
def match_step(self, match):
122124
step = self.steps.popleft()
123-
self.start_step(step)
125+
self.start_behave_step(step)
124126

125-
def start_step(self, step):
127+
def start_behave_step(self, step):
126128

127129
self.current_step_uuid = uuid4()
128130
name = u'{keyword} {title}'.format(keyword=step.keyword, title=step.name)
@@ -136,16 +138,30 @@ def start_step(self, step):
136138
if step.table:
137139
self.logger.attach_data(uuid4(), step_table(step), name='.table', attachment_type=AttachmentType.CSV)
138140

139-
def stop_step(self, result):
141+
def stop_behave_step(self, result):
140142
status = step_status(result)
141143
status_details = step_status_details(result)
142144
self.logger.stop_step(self.current_step_uuid, stop=now(), status=status, statusDetails=status_details)
143145

144146
def flush_steps(self):
145147
while self.steps:
146148
step = self.steps.popleft()
147-
self.start_step(step)
148-
self.stop_step(step)
149+
self.start_behave_step(step)
150+
self.stop_behave_step(step)
151+
152+
@allure_commons.hookimpl
153+
def start_step(self, uuid, title, params):
154+
parameters = [Parameter(name=name, value=value) for name, value in params]
155+
step = TestStepResult(name=title, start=now(), parameters=parameters)
156+
self.logger.start_step(None, uuid, step)
157+
158+
@allure_commons.hookimpl
159+
def stop_step(self, uuid, exc_type, exc_val, exc_tb):
160+
self.logger.stop_step(uuid,
161+
stop=now(),
162+
status=get_status(exc_val),
163+
statusDetails=get_status_details(exc_type, exc_val, exc_tb))
164+
149165

150166
@allure_commons.hookimpl
151167
def attach_data(self, body, name, attachment_type, extension):

allure-behave/src/utils.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,27 +64,27 @@ def scenario_status_details(scenario):
6464
return step_status_details(step)
6565

6666

67-
def fixture_status(exception, exc_traceback):
67+
def get_status_details(exc_type, exception, exc_traceback):
6868
if exception:
69-
return Status.FAILED if isinstance(exception, AssertionError) else Status.BROKEN
70-
else:
71-
return Status.BROKEN if exc_traceback else Status.PASSED
72-
73-
74-
def fixture_status_details(exception, exc_traceback):
75-
if exception:
76-
return StatusDetails(message=format_exception(type(exception), exception),
69+
return StatusDetails(message=format_exception(exc_type, exception),
7770
trace=format_traceback(exc_traceback))
78-
return None
7971

8072

8173
def step_status(result):
82-
if result.exception and not isinstance(result.exception, AssertionError):
83-
return Status.BROKEN
74+
if result.exception:
75+
return get_status(result.exception)
8476
else:
8577
return STATUS.get(result.status, None)
8678

8779

80+
def get_status(exception):
81+
if exception and isinstance(exception, AssertionError):
82+
return Status.FAILED
83+
elif exception:
84+
return Status.BROKEN
85+
return Status.PASSED
86+
87+
8888
def step_status_details(result):
8989
if result.exception:
9090
return StatusDetails(message=format_exception(type(result.exception), result.exception),

0 commit comments

Comments
 (0)