Skip to content

Commit 3cd731a

Browse files
authored
fix(behave): add cleanup; fix invalid call from AllureHooks (allure-framework#860)
1 parent 68bbafe commit 3cd731a

File tree

4 files changed

+93
-29
lines changed

4 files changed

+93
-29
lines changed

allure-behave/src/formatter.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ def __init__(self, stream_opener, config):
1212
super(AllureFormatter, self).__init__(stream_opener, config)
1313

1414
self.listener = AllureListener(config)
15-
file_logger = AllureFileLogger(self.stream_opener.name)
15+
self.file_logger = AllureFileLogger(self.stream_opener.name)
1616

1717
allure_commons.plugin_manager.register(self.listener)
18-
allure_commons.plugin_manager.register(file_logger)
18+
allure_commons.plugin_manager.register(self.file_logger)
1919

2020
self.testplan = get_testplan()
2121

@@ -45,5 +45,14 @@ def result(self, result):
4545
def eof(self):
4646
self.listener.stop_feature()
4747

48+
def close(self):
49+
try:
50+
super().close()
51+
finally:
52+
for plugin in [self.file_logger, self.listener]:
53+
name = allure_commons.plugin_manager.get_name(plugin)
54+
if allure_commons.plugin_manager.has_plugin(name):
55+
allure_commons.plugin_manager.unregister(name=name)
56+
4857
def close_stream(self):
4958
self.listener.stop_session()

allure-behave/src/hooks.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from behave.configuration import Configuration
77

88
HOOKS = [
9+
"after_all",
910
"before_feature",
1011
"after_feature",
1112
"before_scenario",
@@ -42,15 +43,25 @@ def allure_report(result_dir="allure_results"):
4243
class AllureHooks:
4344
def __init__(self, result_dir):
4445
self.listener = AllureListener(Configuration())
46+
self.plugins = []
4547

4648
if not hasattr(_storage, 'file_logger'):
47-
_storage.file_logger = AllureFileLogger(result_dir)
48-
allure_commons.plugin_manager.register(_storage.file_logger)
49+
logger = AllureFileLogger(result_dir)
50+
_storage.file_logger = logger
51+
allure_commons.plugin_manager.register(logger)
52+
self.plugins.append(logger)
4953

5054
allure_commons.plugin_manager.register(self.listener)
55+
self.plugins.append(self.listener)
56+
57+
def after_all(self, context):
58+
for plugin in self.plugins:
59+
name = allure_commons.plugin_manager.get_name(plugin)
60+
if allure_commons.plugin_manager.has_plugin(name):
61+
allure_commons.plugin_manager.unregister(name=name)
5162

5263
def before_feature(self, context, feature):
53-
self.listener.start_feature()
64+
self.listener.start_file()
5465

5566
def after_feature(self, context, feature):
5667
self.listener.stop_feature()

tests/allure_behave/behave_runner.py

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from contextlib import contextmanager
12
import behave.step_registry
23
import sys
34

@@ -16,7 +17,8 @@
1617
from allure_behave.formatter import AllureFormatter
1718

1819

19-
def __fix_behave_in_memory_run():
20+
@contextmanager
21+
def _fixed_in_memory_run():
2022
# Behave has poor support for consecutive prigrammatic runs. This is due to
2123
# how step decorators are cached.
2224
# There are three ways to introduce behave step decorators (i.e., @given)
@@ -50,6 +52,10 @@ def __fixed_add_step_definition(self, *args, **kwargs):
5052

5153
StepRegistry.add_step_definition = __fixed_add_step_definition
5254

55+
yield
56+
57+
StepRegistry.add_step_definition = original_add_step_definition
58+
5359

5460
class _InMemoryBehaveRunner(Runner):
5561
def __init__(self, features, steps, environment, args=None):
@@ -159,32 +165,32 @@ def run_behave(
159165
:attr:`allure_results` attribute.
160166
161167
"""
162-
return self._run(
163-
self._get_all_content(
164-
paths=feature_paths,
165-
literals=feature_literals,
166-
rst_ids=feature_rst_ids
167-
),
168-
self._get_all_content(
169-
paths=step_paths,
170-
literals=step_literals,
171-
rst_ids=step_rst_ids
172-
),
173-
self._resolve_content(
174-
path=environment_path,
175-
literal=environment_literal,
176-
rst_id=environment_rst_id
177-
),
178-
testplan_content=testplan_content,
179-
testplan_path=testplan_path,
180-
testplan_rst_id=testplan_rst_id,
181-
options=options
182-
)
168+
169+
with _fixed_in_memory_run():
170+
return self._run(
171+
self._get_all_content(
172+
paths=feature_paths,
173+
literals=feature_literals,
174+
rst_ids=feature_rst_ids
175+
),
176+
self._get_all_content(
177+
paths=step_paths,
178+
literals=step_literals,
179+
rst_ids=step_rst_ids
180+
),
181+
self._resolve_content(
182+
path=environment_path,
183+
literal=environment_literal,
184+
rst_id=environment_rst_id
185+
),
186+
testplan_content=testplan_content,
187+
testplan_path=testplan_path,
188+
testplan_rst_id=testplan_rst_id,
189+
options=options
190+
)
183191

184192
def _run_framework(self, features, steps, environment, options):
185193
_InMemoryBehaveRunner(features, steps, environment, options).run()
186194

187195

188-
__fix_behave_in_memory_run()
189-
190196
__all__ = ["AllureBehaveRunner"]
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import allure
2+
import shlex
3+
4+
from tests.allure_behave.behave_runner import AllureBehaveRunner
5+
from ...e2e import allure_file_context
6+
7+
from behave import __main__ as runner
8+
9+
10+
@allure.issue("858")
11+
def test_test_results_leak(behave_runner: AllureBehaveRunner):
12+
feature_path = behave_runner.pytester.makefile(
13+
".feature",
14+
(
15+
"""
16+
Feature: Foo
17+
Scenario: Bar
18+
Given baz
19+
"""
20+
),
21+
)
22+
behave_runner.pytester.makefile(
23+
".py",
24+
**{"steps/steps": "given('baz')(lambda *_: None)"},
25+
)
26+
27+
args = shlex.join([
28+
feature_path.name,
29+
"-f", "allure_behave.formatter:AllureFormatter",
30+
"-o", "allure-results",
31+
"--no-summary",
32+
])
33+
34+
with allure_file_context("allure-results") as context:
35+
runner.main(args)
36+
runner.main(args)
37+
38+
assert len(context.allure_results.test_cases) == 2

0 commit comments

Comments
 (0)