Skip to content

Commit e381df5

Browse files
authored
Merge pull request #200 from reportportal/EPMRPP-95894_set_test_case_id_in_runtime
[EPMRPP-95894] Add setting Test Case ID in runtime
2 parents ce6eef4 + 382603b commit e381df5

File tree

9 files changed

+114
-22
lines changed

9 files changed

+114
-22
lines changed

CHANGELOG.md

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

33
## [Unreleased]
4+
### Added
5+
- `Test Case ID` reporting on Item Finish, by @HardNorth
6+
### Changed
7+
- Client version updated on [5.5.8](https://github.com/reportportal/client-Python/releases/tag/5.5.8), by @HardNorth
48

59
## [5.5.6]
610
### Added
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
*** Settings ***
2+
Documentation Example of setting Test Case ID in runtime
3+
Library library/TestCaseId.py
4+
5+
*** Test Cases ***
6+
Test set dynamic Test Case ID
7+
Case Id dynamic_tags.robot[{scope_var}]

examples/library/Log.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
"""Logging library for Robot Framework.
2-
3-
Copyright (c) 2021 http://reportportal.io .
4-
Licensed under the Apache License, Version 2.0 (the "License");
5-
you may not use this file except in compliance with the License.
6-
You may obtain a copy of the License at
7-
8-
http://www.apache.org/licenses/LICENSE-2.0
9-
10-
Unless required by applicable law or agreed to in writing, software
11-
distributed under the License is distributed on an "AS IS" BASIS,
12-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
See the License for the specific language governing permissions and
14-
limitations under the License
15-
"""
1+
"""Logging library for Robot Framework."""
2+
3+
# Copyright 2024 EPAM Systems
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
1616

1717
import os
1818

examples/library/TestCaseId.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""Test Case ID library for Robot Framework."""
2+
# Copyright 2024 EPAM Systems
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# https://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
from typing import Optional
17+
18+
from robot.libraries.BuiltIn import BuiltIn
19+
20+
21+
def case_id(test_case_id_pattern: Optional[str]) -> None:
22+
"""
23+
Set test case ID based on suite metadata.
24+
25+
:param test_case_id_pattern: Test Case ID pattern
26+
"""
27+
built_in = BuiltIn()
28+
if not test_case_id_pattern:
29+
return
30+
suite_metadata = built_in.get_variable_value('${suitemetadata}')
31+
scope = None
32+
for key in suite_metadata:
33+
if key.lower() == 'scope':
34+
scope = suite_metadata[key]
35+
break
36+
if not scope:
37+
return
38+
built_in.set_tags('test_case_id:' + test_case_id_pattern.format(scope_var=scope))

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# Basic dependencies
22
python-dateutil~=2.8.1
3-
reportportal-client~=5.5.7
3+
reportportal-client~=5.5.8
44
robotframework

robotframework_reportportal/model.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
from robotframework_reportportal.helpers import robot_markup_to_markdown
2121
from reportportal_client.helpers import gen_attributes
2222

23+
TEST_CASE_ID_SIGN = 'test_case_id:'
24+
2325

2426
class Suite:
2527
"""Class represents Robot Framework test suite."""
@@ -167,7 +169,7 @@ def critical(self) -> bool:
167169
@property
168170
def tags(self) -> List[str]:
169171
"""Get list of test tags excluding test_case_id."""
170-
return [tag for tag in self._tags if not tag.startswith('test_case_id')]
172+
return [tag for tag in self._tags if not tag.startswith(TEST_CASE_ID_SIGN)]
171173

172174
@property
173175
def attributes(self) -> Optional[List[Dict[str, str]]]:
@@ -196,7 +198,7 @@ def test_case_id(self) -> Optional[str]:
196198
"""Get test case ID through the tags."""
197199
# use test case id from tags if specified
198200
for tag in self._tags:
199-
if tag.startswith('test_case_id:'):
201+
if tag.startswith(TEST_CASE_ID_SIGN):
200202
return tag.split(':')[1]
201203
# generate it if not
202204
return '{0}:{1}'.format(self.source, self.name)

robotframework_reportportal/service.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def to_epoch(date: Optional[str]) -> Optional[str]:
5050
return str(int(epoch_time * 1000))
5151

5252

53-
class RobotService(object):
53+
class RobotService:
5454
"""Class represents service that sends Robot items to ReportPortal."""
5555

5656
agent_name: str
@@ -212,7 +212,8 @@ def finish_test(self, test: Test, issue: Optional[str] = None, ts: Optional[str]
212212
'end_time': ts or to_epoch(test.end_time) or timestamp(),
213213
'issue': issue,
214214
'item_id': test.rp_item_id,
215-
'status': STATUS_MAPPING[test.status]
215+
'status': STATUS_MAPPING[test.status],
216+
'test_case_id': test.test_case_id
216217
}
217218
logger.debug('ReportPortal - Finish test: request_body={0}'.format(fta_rq))
218219
self.rp.finish_test_item(**fta_rq)

tests/integration/test_case_id.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,10 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from tests.helpers import utils
1615
from unittest import mock
1716

1817
from tests import REPORT_PORTAL_SERVICE
19-
18+
from tests.helpers import utils
2019

2120
SIMPLE_TEST = 'examples/simple.robot'
2221

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Copyright 2024 EPAM Systems
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from unittest import mock
16+
17+
from tests import REPORT_PORTAL_SERVICE
18+
from tests.helpers import utils
19+
20+
EXAMPLE_TEST = 'examples/dynamic_test_case_id.robot'
21+
22+
23+
@mock.patch(REPORT_PORTAL_SERVICE)
24+
def test_case_id_simple(mock_client_init):
25+
result = utils.run_robot_tests([EXAMPLE_TEST], arguments={'--metadata': 'Scope:Smoke'})
26+
assert result == 0 # the test successfully passed
27+
28+
mock_client = mock_client_init.return_value
29+
launch_start = mock_client.start_launch.call_args_list
30+
launch_finish = mock_client.finish_launch.call_args_list
31+
assert len(launch_start) == len(launch_finish) == 1
32+
33+
item_start_calls = mock_client.start_test_item.call_args_list
34+
item_finish_calls = mock_client.finish_test_item.call_args_list
35+
assert len(item_start_calls) == len(item_finish_calls) == 3
36+
37+
test_item_start = item_start_calls[-2]
38+
assert test_item_start[1]['test_case_id'] == f'{EXAMPLE_TEST}:Test set dynamic Test Case ID'
39+
40+
test_item_finish = item_finish_calls[-2]
41+
assert test_item_finish[1]['test_case_id'] == 'dynamic_tags.robot[Smoke]'

0 commit comments

Comments
 (0)