Skip to content

Commit f7e20f9

Browse files
authored
Merge pull request #360 from reportportal/pytest_8_support
Pytest 8 support
2 parents 2e82503 + 7366cec commit f7e20f9

File tree

9 files changed

+64
-52
lines changed

9 files changed

+64
-52
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
# Changelog
22

33
## [Unreleased]
4+
### Added
5+
- Pytest version >= 8 support, by @HardNorth
6+
### Removed
7+
- `Packege` and `Dir` item types processing on test collection. This is done to preserve backward compatibility and improve name consistency, by @HardNorth
8+
### Changed
9+
- `rp_issue_system_url` renamed to `rp_bts_issue_url` to be consistent with other agents, by @HardNorth
410

511
## [5.3.2]
612
### Changed

pytest_reportportal/config.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class AgentConfig:
4444
rp_ignore_attributes: set
4545
rp_is_skipped_an_issue: bool
4646
rp_issue_id_marks: bool
47-
rp_issue_system_url: str
47+
rp_bts_issue_url: str
4848
rp_bts_project: str
4949
rp_bts_url: str
5050
rp_launch: str
@@ -88,8 +88,16 @@ def __init__(self, pytest_config: Config) -> None:
8888
)
8989
self.rp_issue_id_marks = self.find_option(pytest_config,
9090
'rp_issue_id_marks')
91-
self.rp_issue_system_url = self.find_option(pytest_config,
92-
'rp_issue_system_url')
91+
self.rp_bts_issue_url = self.find_option(pytest_config, 'rp_bts_issue_url')
92+
if not self.rp_bts_issue_url:
93+
self.rp_bts_issue_url = self.find_option(pytest_config, 'rp_issue_system_url')
94+
if self.rp_bts_issue_url:
95+
warnings.warn(
96+
'Parameter `rp_issue_system_url` is deprecated since 5.4.0 and will be subject for removing'
97+
'in the next major version. Use `rp_bts_issue_url` argument instead.',
98+
DeprecationWarning,
99+
2
100+
)
93101
self.rp_bts_project = self.find_option(pytest_config, 'rp_bts_project')
94102
self.rp_bts_url = self.find_option(pytest_config, 'rp_bts_url')
95103
self.rp_launch = self.find_option(pytest_config, 'rp_launch')

pytest_reportportal/plugin.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -452,8 +452,13 @@ def add_shared_option(name, help_str, default=None, action='store'):
452452
parser.addini(
453453
'rp_issue_system_url',
454454
default='',
455-
help='URL to get issue description. Issue id '
456-
'from pytest mark will be added to this URL')
455+
help='URL to get issue description. Issue id from pytest mark will be added to this URL. '
456+
'Deprecated: use "rp_bts_issue_url".')
457+
parser.addini(
458+
'rp_bts_issue_url',
459+
default='',
460+
help='URL to get issue description. Issue ID from pytest mark will be added to this URL by replacing '
461+
'"{issue_id}" placeholder.')
457462
parser.addini(
458463
'rp_bts_project',
459464
default='',

pytest_reportportal/service.py

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@
3636
except ImportError:
3737
# in pytest >= 7.0 this type was removed
3838
Instance = type('dummy', (), {})
39+
try:
40+
from pytest import Dir
41+
except ImportError:
42+
# in pytest < 8.0 there is no such type
43+
Dir = type('dummy', (), {})
3944
from reportportal_client import RP, create_client
4045
from reportportal_client.helpers import (
4146
dict_to_payload,
@@ -233,7 +238,7 @@ def _get_tree_path(self, item):
233238
path = [item]
234239
parent = item.parent
235240
while parent is not None and not isinstance(parent, Session):
236-
if not isinstance(parent, Instance):
241+
if not isinstance(parent, Instance) and not isinstance(parent, Dir) and not isinstance(parent, Package):
237242
path.append(parent)
238243
parent = parent.parent
239244

@@ -282,22 +287,6 @@ def _build_test_tree(self, session):
282287
current_leaf = children_leafs[leaf]
283288
return test_tree
284289

285-
def _remove_root_package(self, test_tree):
286-
if test_tree['type'] == LeafType.ROOT or \
287-
test_tree['type'] == LeafType.DIR:
288-
for item, child_leaf in test_tree['children'].items():
289-
self._remove_root_package(child_leaf)
290-
return
291-
if test_tree['type'] == LeafType.CODE and \
292-
isinstance(test_tree['item'], Package) and \
293-
test_tree['parent']['type'] == LeafType.DIR:
294-
parent_leaf = test_tree['parent']
295-
current_item = test_tree['item']
296-
del parent_leaf['children'][current_item]
297-
for item, child_leaf in test_tree['children'].items():
298-
parent_leaf['children'][item] = child_leaf
299-
child_leaf['parent'] = parent_leaf
300-
301290
def _remove_root_dirs(self, test_tree, max_dir_level, dir_level=0):
302291
if test_tree['type'] == LeafType.ROOT:
303292
for item, child_leaf in test_tree['children'].items():
@@ -323,10 +312,7 @@ def _generate_names(self, test_tree):
323312

324313
if test_tree['type'] == LeafType.CODE:
325314
item = test_tree['item']
326-
if isinstance(item, Package):
327-
test_tree['name'] = \
328-
os.path.split(os.path.split(str(item.fspath))[0])[1]
329-
elif isinstance(item, Module):
315+
if isinstance(item, Module):
330316
test_tree['name'] = os.path.split(str(item.fspath))[1]
331317
else:
332318
test_tree['name'] = item.name
@@ -376,7 +362,6 @@ def collect_tests(self, session):
376362
"""
377363
# Create a test tree to be able to apply mutations
378364
test_tree = self._build_test_tree(session)
379-
self._remove_root_package(test_tree)
380365
self._remove_root_dirs(test_tree, self._config.rp_dir_level)
381366
self._generate_names(test_tree)
382367
if not self._config.rp_hierarchy_dirs:
@@ -554,7 +539,7 @@ def _get_issue(self, mark):
554539
:param mark: pytest mark
555540
:return: Issue object
556541
"""
557-
default_url = self._config.rp_issue_system_url
542+
default_url = self._config.rp_bts_issue_url
558543

559544
issue_description_line = \
560545
self._get_issue_description_line(mark, default_url)

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
dill>=0.3.6
2-
pytest>=3.8.0,<8.0.0
2+
pytest>=3.8.0
33
reportportal-client~=5.5.4
44
aenum>=3.1.0
55
requests>=2.28.0

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from setuptools import setup
1919

2020

21-
__version__ = '5.3.3'
21+
__version__ = '5.4.0'
2222

2323

2424
def read_file(fname):

tests/integration/test_config_handling.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,21 @@ def test_retries(mock_client_init):
258258
assert_expectations()
259259

260260

261+
@mock.patch(REPORT_PORTAL_SERVICE)
262+
def test_rp_issue_system_url_warning(mock_client_init):
263+
url = 'https://bugzilla.some.com/show_bug.cgi?id={issue_id}'
264+
variables = utils.DEFAULT_VARIABLES.copy()
265+
variables.update({'rp_issue_system_url': str(url)}.items())
266+
267+
with warnings.catch_warnings(record=True) as w:
268+
result = utils.run_pytest_tests(['examples/test_issue_id.py'], variables=variables)
269+
assert int(result) == 1, 'Exit code should be 1 (test failure)'
270+
271+
expect(mock_client_init.call_count == 1)
272+
expect(len(filter_agent_calls(w)) == 1)
273+
assert_expectations()
274+
275+
261276
@mock.patch(REPORT_PORTAL_SERVICE)
262277
def test_launch_uuid_print(mock_client_init):
263278
print_uuid = True

tests/integration/test_issue_report.py

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@
2424
from tests.helpers import utils
2525

2626
ISSUE_PLACEHOLDER = '{issue_id}'
27-
ISSUE_URL_PATTERN = 'https://bugzilla.some.com/show_bug.cgi?id=' + \
28-
ISSUE_PLACEHOLDER
27+
ISSUE_URL_PATTERN = f'https://bugzilla.some.com/show_bug.cgi?id={ISSUE_PLACEHOLDER}'
2928
BTS_PROJECT = 'RP-TEST'
3029
BTS_URL = 'https://bugzilla.some.com'
3130

@@ -42,11 +41,9 @@ def test_issue_id_attribute(mock_client_init, issue_id_mark):
4241
mock_client.start_test_item.side_effect = utils.item_id_gen
4342
mock_client.get_project_settings.side_effect = utils.project_settings
4443

45-
variables = dict()
46-
variables['rp_issue_id_marks'] = issue_id_mark
44+
variables = {'rp_issue_id_marks': issue_id_mark}
4745
variables.update(utils.DEFAULT_VARIABLES.items())
48-
result = utils.run_pytest_tests(tests=['examples/test_issue_id.py'],
49-
variables=variables)
46+
result = utils.run_pytest_tests(tests=['examples/test_issue_id.py'], variables=variables)
5047
assert int(result) == 1, 'Exit code should be 1 (test failed)'
5148

5249
call_args = mock_client.start_test_item.call_args_list
@@ -73,8 +70,7 @@ def test_issue_report(mock_client_init):
7370
mock_client.start_test_item.side_effect = utils.item_id_gen
7471
mock_client.get_project_settings.side_effect = utils.project_settings
7572

76-
variables = dict()
77-
variables['rp_issue_system_url'] = ISSUE_URL_PATTERN
73+
variables = {'rp_issue_system_url': ISSUE_URL_PATTERN}
7874
variables.update(utils.DEFAULT_VARIABLES.items())
7975
result = utils.run_pytest_tests(tests=['examples/test_issue_id.py'],
8076
variables=variables)
@@ -106,11 +102,9 @@ def test_passed_no_issue_report(mock_client_init):
106102
mock_client.start_test_item.side_effect = utils.item_id_gen
107103
mock_client.get_project_settings.side_effect = utils.project_settings
108104

109-
variables = dict()
110-
variables['rp_issue_system_url'] = ISSUE_URL_PATTERN
105+
variables = {'rp_issue_system_url': ISSUE_URL_PATTERN}
111106
variables.update(utils.DEFAULT_VARIABLES.items())
112-
result = utils.run_pytest_tests(tests=['examples/test_issue_id_pass.py'],
113-
variables=variables)
107+
result = utils.run_pytest_tests(tests=['examples/test_issue_id_pass.py'], variables=variables)
114108
assert int(result) == 0, 'Exit code should be 0 (no failures)'
115109

116110
call_args = mock_client.finish_test_item.call_args_list
@@ -164,8 +158,7 @@ def test_skipped_custom_issue(mock_client_init):
164158
variables['rp_issue_system_url'] = ISSUE_URL_PATTERN
165159
variables.update(utils.DEFAULT_VARIABLES.items())
166160

167-
result = utils.run_pytest_tests(tests=['examples/skip/test_skip_issue.py'],
168-
variables=variables)
161+
result = utils.run_pytest_tests(tests=['examples/skip/test_skip_issue.py'], variables=variables)
169162

170163
assert int(result) == 0, 'Exit code should be 0 (no failures)'
171164
call_args = mock_client.finish_test_item.call_args_list
@@ -187,14 +180,14 @@ def test_external_issue(mock_client_init):
187180
mock_client.start_test_item.side_effect = utils.item_id_gen
188181
mock_client.get_project_settings.side_effect = utils.project_settings
189182

190-
variables = dict()
191-
variables['rp_bts_project'] = BTS_PROJECT
192-
variables['rp_bts_url'] = BTS_URL
193-
variables['rp_issue_system_url'] = ISSUE_URL_PATTERN
183+
variables = {
184+
'rp_bts_project': BTS_PROJECT,
185+
'rp_bts_url': BTS_URL,
186+
'rp_bts_issue_url': ISSUE_URL_PATTERN
187+
}
194188
variables.update(utils.DEFAULT_VARIABLES.items())
195189

196-
result = utils.run_pytest_tests(tests=['examples/test_issue_id.py'],
197-
variables=variables)
190+
result = utils.run_pytest_tests(tests=['examples/test_issue_id.py'], variables=variables)
198191

199192
assert int(result) == 1, 'Exit code should be 1 (test failed)'
200193
call_args = mock_client.finish_test_item.call_args_list
@@ -210,6 +203,5 @@ def test_external_issue(mock_client_init):
210203
expect(external_issue['btsUrl'] == BTS_URL)
211204
expect(external_issue['btsProject'] == BTS_PROJECT)
212205
expect(external_issue['ticketId'] == test_issue_id.ID)
213-
expect(external_issue['url'] ==
214-
ISSUE_URL_PATTERN.replace(ISSUE_PLACEHOLDER, test_issue_id.ID))
206+
expect(external_issue['url'] == ISSUE_URL_PATTERN.replace(ISSUE_PLACEHOLDER, test_issue_id.ID))
215207
assert_expectations()

tests/unit/test_plugin.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ def test_pytest_addoption_adds_correct_ini_file_arguments():
355355
'rp_hierarchy_dirs',
356356
'rp_hierarchy_dir_path_separator',
357357
'rp_issue_system_url',
358+
'rp_bts_issue_url',
358359
'rp_bts_project',
359360
'rp_bts_url',
360361
'rp_verify_ssl',

0 commit comments

Comments
 (0)