-
Notifications
You must be signed in to change notification settings - Fork 29
Implement LCOV format reporting #70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Implements generating coverage reporting in LCOV format, controlled by the flag `--lcov`. Changes: - Added lcovreport.py module with LcovReporter class for generating LCOV format output - Integrated LCOV reporting into slipcover.py with print_lcov() function - Added --lcov command-line flag to __main__.py for selecting LCOV output - Added --lcov-test-name and --lcov-comment, common in other LCOV tools - Exported print_lcov in __init__.py to make it accessible - Added tests for LCOV reporting (with and without branches) The LCOV format includes: - TN: Test name (optional) - SF: Source file path - BRDA: Branch coverage data (when --branch is used) - BRF/BRH: Branch statistics - DA: Line coverage data - LF/LH: Line statistics - end_of_record marker Usage examples: python -m slipcover --lcov --out coverage.lcov script.py python -m slipcover --branch --lcov --out coverage.lcov script.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements LCOV format coverage reporting for slipcover, enabling output compatible with tools that consume LCOV format. The implementation adds a new LcovReporter class and integrates it into the CLI with --lcov flag support, along with optional test name and comment features.
Changes:
- Added LCOV format reporting with line and branch coverage support
- Integrated LCOV output option into CLI with
--lcov,--lcov-test-name, and--lcov-commentflags - Added comprehensive test coverage for LCOV functionality including branches, test names, and comments
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/slipcover/lcovreport.py | New module implementing LCOV format reporter with line and branch coverage |
| src/slipcover/slipcover.py | Added print_lcov() function to expose LCOV reporting API |
| src/slipcover/main.py | Integrated LCOV CLI flags and output handling in both merge and normal execution modes |
| src/slipcover/init.py | Exported print_lcov in public API |
| tests/test_coverage.py | Added test suite for LCOV reporting covering various scenarios |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| all_lines = sorted(file_data["executed_lines"] + file_data["missing_lines"]) | ||
|
|
||
| # Write branch coverage data if enabled | ||
| if self.with_branches and (file_data["executed_branches"] or file_data["missing_branches"]): |
Copilot
AI
Jan 14, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition directly accesses executed_branches and missing_branches keys which are NotRequired fields in the CoverageFile TypedDict. While this works when branch coverage is enabled (as these keys are always present), it could raise a KeyError if coverage data was generated without branch coverage but LCOV output is requested with --branch. Consider using .get() for safer access: file_data.get(\"executed_branches\", []) or checking key existence first.
|
|
||
| """ | ||
| mba: Dict[int, List[int]] = {} | ||
| for branch in file_data["missing_branches"]: |
Copilot
AI
Jan 14, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Direct key access to missing_branches which is a NotRequired field. This function is only called when branch data exists, but for type safety and defensive programming, consider using .get(\"missing_branches\", []) to handle edge cases where the key might not be present.
| Returns a dict mapping line numbers to a list of (branch_dest, was_taken) tuples. | ||
|
|
||
| """ | ||
| all_branches = sorted(file_data["executed_branches"] + file_data["missing_branches"]) |
Copilot
AI
Jan 14, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Direct key access to NotRequired fields executed_branches and missing_branches. Similar to other functions, this should use .get() for safer access: file_data.get(\"executed_branches\", []) + file_data.get(\"missing_branches\", [])
| total_branches = len(file_data["executed_branches"]) + len(file_data["missing_branches"]) | ||
| outfile.write(f"BRF:{total_branches}\n") | ||
|
|
||
| # BRH: Branches Hit | ||
| branches_hit = len(file_data["executed_branches"]) |
Copilot
AI
Jan 14, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Direct access to executed_branches and missing_branches keys. While protected by the condition on line 94, using .get() would be more defensive: len(file_data.get(\"executed_branches\", [])) and len(file_data.get(\"missing_branches\", []))
|
|
||
| for branch in all_branches: | ||
| src_line, dest_line = branch | ||
| is_taken = branch not in file_data["missing_branches"] |
Copilot
AI
Jan 14, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Direct key access to missing_branches. For consistency and safety, use .get(\"missing_branches\", []) instead.
Implements generating coverage reporting in LCOV format, controlled by the flag
--lcov.Changes:
lcovreport.pymodule withLcovReporterclass for generating LCOV format outputslipcover.pywithprint_lcov()function--lcovcommand-line flag to__main__.pyfor selecting LCOV output--lcov-test-nameand--lcov-comment, common in other LCOV toolsThe LCOV format includes:
Usage examples: