Coverage for lintro / tools / implementations / pytest / pytest_result_processor.py: 100%

22 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2026-04-03 18:53 +0000

1"""Pytest result processing. 

2 

3This module contains the PytestResultProcessor class that handles test result 

4processing, summary generation, and ToolResult building. 

5""" 

6 

7from dataclasses import dataclass, field 

8from typing import Any 

9 

10from lintro.models.core.tool_result import ToolResult 

11from lintro.parsers.pytest.pytest_issue import PytestIssue 

12from lintro.tools.implementations.pytest.pytest_config import PytestConfiguration 

13from lintro.tools.implementations.pytest.pytest_output_processor import ( 

14 build_output_with_failures, 

15 check_total_time_warning, 

16 detect_and_log_flaky_tests, 

17 detect_and_log_slow_tests, 

18 process_test_summary, 

19) 

20 

21 

22@dataclass 

23class PytestResultProcessor: 

24 """Handles pytest result processing and ToolResult building. 

25 

26 This class encapsulates the logic for processing test results, generating 

27 summaries, and building ToolResult objects from pytest execution data. 

28 

29 Attributes: 

30 config: PytestConfiguration instance with result processing options. 

31 tool_name: Name of the tool (e.g., "pytest"). 

32 """ 

33 

34 config: PytestConfiguration = field(default_factory=PytestConfiguration) 

35 tool_name: str = field(default="pytest") 

36 

37 def process_test_results( 

38 self, 

39 output: str, 

40 return_code: int, 

41 issues: list[PytestIssue], 

42 total_available_tests: int, 

43 ) -> tuple[dict[str, Any], list[PytestIssue]]: 

44 """Process test results and generate summary. 

45 

46 Args: 

47 output: Raw output from pytest. 

48 return_code: Return code from pytest. 

49 issues: Parsed test issues. 

50 total_available_tests: Total number of available tests. 

51 

52 Returns: 

53 Tuple[Dict, List]: Tuple of (summary_data, all_issues). 

54 """ 

55 # Process summary 

56 summary_data = process_test_summary( 

57 output=output, 

58 issues=issues, 

59 total_available_tests=total_available_tests, 

60 ) 

61 

62 # Performance warnings (uses all issues including passed for duration info) 

63 detect_and_log_slow_tests(issues, self.config.get_options_dict()) 

64 check_total_time_warning( 

65 summary_data["duration"], 

66 self.config.get_options_dict(), 

67 ) 

68 

69 # Flaky test detection 

70 detect_and_log_flaky_tests(issues, self.config.get_options_dict()) 

71 

72 # Return all issues - filtering for ToolResult.issues happens in build_result 

73 return (summary_data, issues) 

74 

75 def build_result( 

76 self, 

77 success: bool, 

78 summary_data: dict[str, Any], 

79 all_issues: list[PytestIssue], 

80 raw_output: str | None = None, 

81 ) -> ToolResult: 

82 """Build final ToolResult from processed data. 

83 

84 Args: 

85 success: Whether tests passed. 

86 summary_data: Summary data dictionary. 

87 all_issues: List of all test issues (failures, errors, skips). 

88 raw_output: Optional raw pytest output for coverage report extraction. 

89 

90 Returns: 

91 ToolResult: Final result object. 

92 """ 

93 # Filter to only failed/error issues for the ToolResult.issues field 

94 failed_issues = [ 

95 issue for issue in all_issues if issue.test_status in ("FAILED", "ERROR") 

96 ] 

97 

98 output_text = build_output_with_failures(summary_data, all_issues, raw_output) 

99 

100 result = ToolResult( 

101 name=self.tool_name, 

102 success=success, 

103 issues=failed_issues, 

104 output=output_text, 

105 issues_count=len(failed_issues), 

106 ) 

107 

108 # Store summary data for display in Execution Summary table 

109 result.pytest_summary = summary_data 

110 

111 return result