Skip to content

Commit 7c8496a

Browse files
committed
Implements issue #396
1 parent 0887b2c commit 7c8496a

File tree

4 files changed

+79
-35
lines changed

4 files changed

+79
-35
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## [Unreleased]
44
### Added
55
- Official `Python 3.14` support, by @HardNorth
6+
- Issue [#396](https://github.com/reportportal/agent-python-pytest/issues/396) parametrize marker IDs, by @HardNorth
67
### Removed
78
- `Python 3.8` support, by @HardNorth
89
- Deprecated `retries` parameter, by @HardNorth
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"""A simple example test with Test Case ID decorator and parameters."""
2+
3+
# Copyright (c) 2022 https://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+
# 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+
import pytest
17+
18+
TEST_CASE_ID = "ISSUE-231"
19+
20+
21+
@pytest.mark.parametrize(("param1", "param2"), [("value1", "value2")], ids=[TEST_CASE_ID])
22+
def test_case_id_decorator(param1, param2):
23+
assert True

pytest_reportportal/service.py

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -602,47 +602,32 @@ def _get_code_ref(self, item: Item) -> str:
602602
class_path = ".".join(classes)
603603
return "{0}:{1}".format(path, class_path)
604604

605-
def _get_test_case_id(self, mark, leaf: Dict[str, Any]) -> str:
606-
parameters: Optional[Dict[str, Any]] = leaf.get("parameters", None)
607-
parameters_indices: Optional[Dict[str, Any]] = leaf.get("parameters_indices") or {}
608-
parameterized = True
609-
selected_params: Optional[List[str]] = None
610-
use_index = False
611-
if mark is not None:
612-
parameterized = mark.kwargs.get("parameterized", False)
613-
selected_params: Optional[Union[str, List[str]]] = mark.kwargs.get("params", None)
614-
use_index = mark.kwargs.get("use_index", False)
615-
if selected_params is not None and not isinstance(selected_params, list):
616-
selected_params = [selected_params]
617-
605+
def _get_test_case_id(
606+
self,
607+
base_name: str,
608+
parameterized: bool,
609+
include_params: Optional[List[str]],
610+
use_index: bool,
611+
parameters: Optional[Dict[str, Any]],
612+
parameters_indices: Optional[Dict[str, Any]],
613+
) -> str:
618614
param_str = None
619615
if parameterized and parameters is not None and len(parameters) > 0:
620-
if selected_params is not None and len(selected_params) > 0:
616+
if include_params is not None and len(include_params) > 0:
621617
if use_index:
622-
param_list = [str((param, parameters_indices.get(param, None))) for param in selected_params]
618+
param_list = [str((param, parameters_indices.get(param, None))) for param in include_params]
623619
else:
624-
param_list = [str(parameters.get(param, None)) for param in selected_params]
620+
param_list = [str(parameters.get(param, None)) for param in include_params]
625621
elif use_index:
626622
param_list = [str(param) for param in parameters_indices.items()]
627623
else:
628624
param_list = [str(param) for param in parameters.values()]
629-
param_str = "[{}]".format(",".join(sorted(param_list)))
625+
param_str = f"[{','.join(sorted(param_list))}]"
630626

631-
basic_name_part = leaf["code_ref"]
632-
if mark is None:
633-
if param_str is None:
634-
return basic_name_part
635-
else:
636-
return basic_name_part + param_str
627+
if param_str is None:
628+
return base_name
637629
else:
638-
if mark.args is not None and len(mark.args) > 0:
639-
basic_name_part = str(mark.args[0])
640-
else:
641-
basic_name_part = ""
642-
if param_str is None:
643-
return basic_name_part
644-
else:
645-
return basic_name_part + param_str
630+
return base_name + param_str
646631

647632
def _get_issue_ids(self, mark):
648633
issue_ids = mark.kwargs.get("issue_id", [])
@@ -762,10 +747,40 @@ def _process_test_case_id(self, leaf: Dict[str, Any]) -> str:
762747
:param leaf: item context
763748
:return: Test Case ID string
764749
"""
765-
tc_ids = [m for m in leaf["item"].iter_markers() if m.name == "tc_id"]
766-
if len(tc_ids) > 0:
767-
return self._get_test_case_id(tc_ids[0], leaf)
768-
return self._get_test_case_id(None, leaf)
750+
item = leaf["item"]
751+
base_name = leaf["code_ref"]
752+
parameterized = True
753+
include_params = None
754+
use_index = False
755+
parameters: Optional[Dict[str, Any]] = leaf.get("parameters", None)
756+
parameters_indices: Optional[Dict[str, Any]] = leaf.get("parameters_indices") or {}
757+
758+
parametrize_markers = [m for m in item.iter_markers() if m.name == "parametrize"]
759+
if parametrize_markers:
760+
mark = parametrize_markers[0]
761+
mark_kwargs = getattr(mark, "kwargs", None)
762+
if mark_kwargs and "ids" in mark_kwargs and mark_kwargs["ids"]:
763+
base_name = item.callspec.id
764+
parameterized = False
765+
766+
tc_ids = [m for m in item.iter_markers() if m.name == "tc_id"]
767+
if tc_ids:
768+
mark = tc_ids[0]
769+
parameterized = mark.kwargs.get("parameterized", False)
770+
include_params: Optional[Union[str, List[str]]] = mark.kwargs.get("params", None)
771+
use_index = mark.kwargs.get("use_index", False)
772+
773+
if include_params is not None and not isinstance(include_params, list):
774+
include_params = [include_params]
775+
776+
if mark.args is not None and len(mark.args) > 0:
777+
base_name = str(mark.args[0])
778+
else:
779+
base_name = ""
780+
781+
return self._get_test_case_id(
782+
base_name, parameterized, include_params, use_index, parameters, parameters_indices
783+
)
769784

770785
def _process_issue(self, item: Item) -> Optional[Issue]:
771786
"""

tests/integration/test_case_id_report.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from examples.test_case_id import (
2121
test_case_id_decorator,
2222
test_case_id_decorator_params_false,
23+
test_case_id_decorator_params_mark,
2324
test_case_id_decorator_params_no,
2425
test_case_id_decorator_params_partially,
2526
test_case_id_decorator_params_true,
@@ -55,6 +56,10 @@
5556
("examples/test_case_id/test_case_id_decorator_no_id_params_false.py", ""),
5657
("examples/test_case_id/test_case_id_decorator_no_id_params_true.py", "[value1,value2]"),
5758
("examples/test_case_id/test_case_id_decorator_no_id_partial_params_true.py", "[value2]"),
59+
(
60+
"examples/test_case_id/test_case_id_decorator_params_mark.py",
61+
test_case_id_decorator_params_mark.TEST_CASE_ID,
62+
),
5863
],
5964
)
6065
def test_parameters(mock_client_init, test, expected_id):

0 commit comments

Comments
 (0)