Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/reportportal/reportportal_client_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ def start_test_case(self, name: str, start_time: str, parent_id: str,
attributes: Optional[List[Dict]] = None,
description: Optional[str] = None,
code_ref: Optional[str] = None,
test_case_id: Optional[str] = None,
retry: bool = False,
retry_of: Optional[str] = None) -> str:
"""
Expand All @@ -260,6 +261,7 @@ def start_test_case(self, name: str, start_time: str, parent_id: str,
attributes: Test case attributes
description: Test case description
code_ref: Code reference for the test (e.g., "path/to/test.py::test_name")
test_case_id: Explicit test case identifier for RP history matching
retry: If True, marks this test case as a retry of a previous attempt
retry_of: UUID of the original test item this retry references (RP 25.x)

Expand All @@ -269,7 +271,7 @@ def start_test_case(self, name: str, start_time: str, parent_id: str,
if self.dry_run:
mock_id = self._generate_mock_id()
logger.info(f"[DRY-RUN] Would start test case '{name}' with ID: {mock_id}")
logger.info(f"[DRY-RUN] Parent: {parent_id}, Code ref: {code_ref}, Retry: {retry}, Retry of: {retry_of}")
logger.info(f"[DRY-RUN] Parent: {parent_id}, Code ref: {code_ref}, Test case id: {test_case_id}, Retry: {retry}, Retry of: {retry_of}")
return mock_id

if not self.client:
Expand All @@ -284,11 +286,12 @@ def start_test_case(self, name: str, start_time: str, parent_id: str,
description=description,
parent_item_id=parent_id,
code_ref=code_ref,
test_case_id=test_case_id,
retry=retry,
retry_of=retry_of
)
logger.debug(f"Started test case '{name}' with ID: {case_id}")
logger.debug(f"Parent: {parent_id}, Code ref: {code_ref}, Retry: {retry}, Retry of: {retry_of}")
logger.debug(f"Parent: {parent_id}, Code ref: {code_ref}, Test case id: {test_case_id}, Retry: {retry}, Retry of: {retry_of}")
return case_id
except Exception as e:
logger.error(f"Failed to start test case '{name}': {e}")
Expand Down
22 changes: 16 additions & 6 deletions src/reportportal/writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,8 @@ def _process_test_suite(self, suite_data: dict, suite_properties: list,
# Process all test cases in the suite
for case_data, case_result in zip(suite_data['test_cases'], case_results):
case_runtime = self._process_test_case(
case_data, case_result, suite_id, suite_timestamp + suite_runtime
case_data, case_result, suite_id, suite_timestamp + suite_runtime,
suite_name=suite_data['name']
)
# Disabling suite_runtime tally, due to Interrupted test cases
# because of parallel run, total runtime is larger than actual time
Expand All @@ -248,7 +249,8 @@ def _process_test_suite(self, suite_data: dict, suite_properties: list,
attributes=suite_attrs
)

def _create_failed_attempts(self, test_name: str, case_result,
def _create_failed_attempts(self, test_name: str, test_case_id: str,
case_result,
suite_id: str, start_time: int, rerun_duration: int) -> str:
"""
Create all failed rerun attempts before the final test result.
Expand All @@ -257,7 +259,8 @@ def _create_failed_attempts(self, test_name: str, case_result,
are retries referencing the original via retry_of (RP 25.x).

Args:
test_name: Full test case name
test_name: Test display name and code reference (e.g. "tests/foo.py::test_bar")
test_case_id: Suite-qualified identifier for RP history matching (e.g. "smoke: tests/foo.py::test_bar")
case_result: Filtered case property result
suite_id: Parent suite ID
start_time: Test case start time
Expand All @@ -277,6 +280,7 @@ def _create_failed_attempts(self, test_name: str, case_result,
attributes=case_result.properties,
description=case_result.description,
code_ref=test_name,
test_case_id=test_case_id,
retry=not is_original,
retry_of=None if is_original else original_id
)
Expand All @@ -297,7 +301,8 @@ def _create_failed_attempts(self, test_name: str, case_result,
return original_id

def _process_test_case(self, case_data: dict, case_result,
suite_id: str, start_time: int) -> int:
suite_id: str, start_time: int,
suite_name: str = "") -> int:
"""
Process a single test case.

Expand All @@ -306,21 +311,25 @@ def _process_test_case(self, case_data: dict, case_result,
case_result: Pre-filtered case property result
suite_id: Parent suite ID
start_time: Test case start time
suite_name: Parent suite name, used to qualify code_ref

Returns:
Test case runtime in milliseconds
"""

# Generate test case name (pytest-style)
# Generate test name (pytest-style)
test_name = f"{case_data['converted_classname']}::{case_data['name']}"

# Suite-qualified test_case_id for RP history matching
test_case_id = f"{suite_name}: {test_name}" if suite_name else test_name

# Create failed rerun attempts before the final result
original_id = None
final_start_time = start_time
if case_result.reruns > 0:
rerun_duration = case_data['time'] // (case_result.reruns + 1)
original_id = self._create_failed_attempts(
test_name, case_result, suite_id, start_time, rerun_duration
test_name, test_case_id, case_result, suite_id, start_time, rerun_duration
)
final_start_time = start_time + (case_result.reruns * rerun_duration)

Expand All @@ -332,6 +341,7 @@ def _process_test_case(self, case_data: dict, case_result,
attributes=case_result.properties,
description=case_result.description,
code_ref=test_name,
test_case_id=test_case_id,
retry=original_id is not None,
retry_of=original_id
)
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/test_reportportal_client_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ def test_start_test_case_success(self):
description="Case description",
parent_item_id="suite_456",
code_ref=None,
test_case_id=None,
retry=False,
retry_of=None
)
Expand Down Expand Up @@ -258,6 +259,7 @@ def test_start_test_case_with_code_ref(self):
description="Case description",
parent_item_id="suite_456",
code_ref="path/to/test.py::test_name",
test_case_id=None,
retry=False,
retry_of=None
)
Expand Down
Loading