Skip to content

Commit 70c51c2

Browse files
authored
Add test coverage analysis tools with multi-format support (#4)
* feat: Add test coverage analysis tools and services Implements coverage report analysis for .NET projects with support for: - Multiple coverage formats (Coverlet JSON, LCOV, Cobertura XML) - File-level coverage statistics and uncovered line detection - Branch coverage tracking and coverage percentage calculation - Integration with existing MCP tools architecture New components: - CoverageAnalysisService for parsing coverage reports - coverage_analysis and coverage_summary MCP tools - Coverage-specific models and test suite
1 parent a0b577f commit 70c51c2

File tree

12 files changed

+1617
-3
lines changed

12 files changed

+1617
-3
lines changed

README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ NetContextServer empowers AI coding assistants like Cursor AI to deeply understa
2525
- 🔍 **Deep Dependency Visualization**: See transitive dependencies with interactive, color-coded graphs
2626
- 🧩 **Smart Grouping**: Visually group related packages for easier navigation
2727
- 📊 **Update Recommendations**: Identify outdated packages and security issues
28+
- 📊 **Test Coverage Analysis**: Deep insights into your test coverage
29+
- 🎯 **Multi-Format Support**: Parse coverage data from Coverlet, LCOV, and Cobertura XML
30+
- 📈 **Detailed Reports**: File-level coverage percentages and uncovered line tracking
31+
- 🔄 **Branch Coverage**: Track method-level branch coverage where available
32+
- 💡 **Smart Recommendations**: Get suggestions for improving test coverage
2833
-**Fast & Efficient**: Quick indexing and response times for large codebases
2934

3035
## 🚀 Quick Start
@@ -78,6 +83,10 @@ Now Cursor AI can understand your codebase! Try asking it questions like:
7883
- "What's the current base directory for file operations?"
7984
- "Help me think through the authentication system design"
8085
- "Document my reasoning about this architectural decision"
86+
- "Analyze test coverage for MyService.cs"
87+
- "Show me uncovered lines in the authentication module"
88+
- "What's the overall test coverage percentage?"
89+
- "Which files have the lowest test coverage?"
8190

8291
## 📚 Documentation
8392

@@ -95,6 +104,11 @@ Now Cursor AI can understand your codebase! Try asking it questions like:
95104
- 📖 **File Content Access**: Read source files with safety checks and size limits
96105
- 🛡️ **Security**: Built-in safeguards for sensitive files and directory access
97106
- 🎯 **Pattern Management**: Flexible ignore patterns for controlling file access
107+
- 📊 **Coverage Analysis**: Parse and analyze test coverage data
108+
- 📈 **Coverage Reports**: Support for Coverlet JSON, LCOV, and Cobertura XML formats
109+
- 🎯 **Line Coverage**: Track which lines are covered by tests
110+
- 🌳 **Branch Coverage**: Monitor method-level branch coverage
111+
- 💡 **Recommendations**: Get actionable suggestions to improve coverage
98112
- 💭 **Structured Thinking**: Document and validate reasoning about complex operations
99113
- 🧩 **AI-Optimized Reasoning**: Based on [Anthropic's research](https://www.anthropic.com/engineering/claude-think-tool) on improving LLM problem-solving
100114
- 📋 **Task Planning**: Break down complex problems into manageable steps
@@ -187,6 +201,34 @@ Project: MyProject.csproj
187201
└─ Microsoft.Extensions.DependencyInjection.Abstractions
188202
```
189203

204+
6. **Analyze Test Coverage**:
205+
```bash
206+
# Set your base directory first
207+
dotnet run --project src/NetContextClient/NetContextClient.csproj -- set-base-dir --directory "path/to/your/project"
208+
209+
# Analyze coverage from a Coverlet JSON report
210+
dotnet run --project src/NetContextClient/NetContextClient.csproj -- coverage-analysis --report-path "TestResults/coverage.json"
211+
212+
# Get a coverage summary
213+
dotnet run --project src/NetContextClient/NetContextClient.csproj -- coverage-summary --report-path "TestResults/coverage.json"
214+
```
215+
216+
Example coverage analysis output:
217+
```json
218+
[
219+
{
220+
"filePath": "src/MyProject/Services/UserService.cs",
221+
"coveragePercentage": 85.3,
222+
"uncoveredLines": [42, 43, 88],
223+
"branchCoverage": {
224+
"ValidateUser()": 75.0,
225+
"GetUserById()": 100.0
226+
},
227+
"recommendation": "Consider adding tests for the user validation error paths"
228+
}
229+
]
230+
```
231+
190232
### Search Commands
191233

192234
1. **Text Search**:

docs/getting-started.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,57 @@ dotnet run --project src/NetContextClient/NetContextClient.csproj -- add-ignore-
122122
dotnet run --project src/NetContextClient/NetContextClient.csproj -- get-ignore-patterns
123123
```
124124

125+
## Using Coverage Analysis
126+
127+
NetContextServer includes powerful test coverage analysis capabilities that help you understand and improve your test coverage. Here's how to get started:
128+
129+
### 1. Generate Coverage Reports
130+
131+
First, you'll need to generate a coverage report. NetContextServer supports multiple formats:
132+
133+
**Using Coverlet (recommended):**
134+
```bash
135+
dotnet test --collect:"XPlat Code Coverage"
136+
```
137+
This will generate a coverage report in the `TestResults` directory.
138+
139+
**Using LCOV:**
140+
If you're using LCOV, make sure your test runner is configured to output LCOV format (`.info` files).
141+
142+
**Using Cobertura:**
143+
For Cobertura XML format, configure your test runner to output `.cobertura.xml` files.
144+
145+
### 2. Analyze Coverage
146+
147+
Once you have a coverage report, you can analyze it using NetContextServer:
148+
149+
```bash
150+
# Analyze coverage for detailed per-file information
151+
dotnet run --project src/NetContextClient/NetContextClient.csproj -- coverage-analysis --report-path "TestResults/coverage.json"
152+
153+
# Get a summary of overall coverage
154+
dotnet run --project src/NetContextClient/NetContextClient.csproj -- coverage-summary --report-path "TestResults/coverage.json"
155+
```
156+
157+
### 3. Interpret Results
158+
159+
The coverage analysis provides several key insights:
160+
161+
- **Coverage Percentage**: The percentage of lines covered by tests
162+
- **Uncovered Lines**: Specific line numbers that aren't covered by tests
163+
- **Branch Coverage**: For methods with conditional logic, shows how many branches are covered
164+
- **Recommendations**: Suggestions for improving coverage in specific areas
165+
166+
### 4. Improve Coverage
167+
168+
Use the analysis results to:
169+
1. Identify files with low coverage
170+
2. Focus on uncovered lines in critical code paths
171+
3. Add tests for uncovered branches in complex methods
172+
4. Track coverage trends over time
173+
174+
For more details on coverage analysis commands and options, see the [Tool Reference](tool-reference.md#coverage-analysis-tools).
175+
125176
## Troubleshooting
126177

127178
### Common Issues

docs/tool-reference.md

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,4 +422,59 @@ The server provides clear error messages for common scenarios:
422422
- Invalid patterns
423423
- File size limits exceeded
424424
- Restricted file types
425-
- Missing environment variables for semantic search
425+
- Missing environment variables for semantic search
426+
427+
## Coverage Analysis Tools
428+
429+
### `coverage-analysis`
430+
431+
Analyzes test coverage data from various formats and provides detailed insights.
432+
433+
```bash
434+
dotnet run --project src/NetContextClient/NetContextClient.csproj -- coverage-analysis --report-path <path> [--format <format>]
435+
```
436+
437+
**Parameters:**
438+
- `--report-path`: Path to the coverage report file
439+
- `--format` (optional): Coverage report format. Supported values:
440+
- `coverlet-json` (default): Coverlet JSON format
441+
- `lcov`: LCOV format
442+
- `cobertura`: Cobertura XML format
443+
444+
**Output:**
445+
Returns a list of coverage reports for each file, including:
446+
- File path
447+
- Coverage percentage
448+
- List of uncovered lines
449+
- Branch coverage data (where available)
450+
- Recommendations for improving coverage
451+
452+
**Example:**
453+
```bash
454+
dotnet run --project src/NetContextClient/NetContextClient.csproj -- coverage-analysis --report-path "TestResults/coverage.json"
455+
```
456+
457+
### `coverage-summary`
458+
459+
Generates a summary of test coverage across all files.
460+
461+
```bash
462+
dotnet run --project src/NetContextClient/NetContextClient.csproj -- coverage-summary --report-path <path> [--format <format>]
463+
```
464+
465+
**Parameters:**
466+
- `--report-path`: Path to the coverage report file
467+
- `--format` (optional): Coverage report format (same as coverage-analysis)
468+
469+
**Output:**
470+
Returns a summary object containing:
471+
- Total number of files
472+
- Overall coverage percentage
473+
- Total number of uncovered lines
474+
- List of files with coverage below threshold
475+
- List of files with lowest coverage
476+
477+
**Example:**
478+
```bash
479+
dotnet run --project src/NetContextClient/NetContextClient.csproj -- coverage-summary --report-path "TestResults/coverage.json"
480+
```
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
namespace NetContextClient.Models;
2+
3+
/// <summary>
4+
/// Represents a code coverage report for a single file or class.
5+
/// </summary>
6+
public class CoverageReport
7+
{
8+
/// <summary>
9+
/// Gets or sets the path to the source file, relative to the project root.
10+
/// </summary>
11+
public string FilePath { get; set; } = string.Empty;
12+
13+
/// <summary>
14+
/// Gets or sets the overall coverage percentage for the file (0-100).
15+
/// </summary>
16+
public float CoveragePercentage { get; set; }
17+
18+
/// <summary>
19+
/// Gets or sets the list of line numbers that are not covered by tests.
20+
/// </summary>
21+
public List<int> UncoveredLines { get; set; } = [];
22+
23+
/// <summary>
24+
/// Gets or sets the total number of executable lines in the file.
25+
/// </summary>
26+
public int TotalLines { get; set; }
27+
28+
/// <summary>
29+
/// Gets or sets the branch coverage information, mapping method names to their coverage percentage.
30+
/// </summary>
31+
public Dictionary<string, float> BranchCoverage { get; set; } = [];
32+
33+
/// <summary>
34+
/// Gets or sets the list of test files that provide coverage for this file.
35+
/// </summary>
36+
public List<string> TestFiles { get; set; } = [];
37+
38+
/// <summary>
39+
/// Gets or sets a suggested action to improve coverage, if applicable.
40+
/// </summary>
41+
public string? Recommendation { get; set; }
42+
43+
/// <summary>
44+
/// The type of file being analyzed (Production, Test, Generated, or Unknown)
45+
/// </summary>
46+
public CoverageFileType FileType { get; set; } = CoverageFileType.Unknown;
47+
}
48+
49+
/// <summary>
50+
/// Represents the type of file being analyzed for code coverage
51+
/// </summary>
52+
public enum CoverageFileType
53+
{
54+
/// <summary>
55+
/// Production code file
56+
/// </summary>
57+
Production,
58+
59+
/// <summary>
60+
/// Test code file
61+
/// </summary>
62+
Test,
63+
64+
/// <summary>
65+
/// Generated code file
66+
/// </summary>
67+
Generated,
68+
69+
/// <summary>
70+
/// Unknown file type
71+
/// </summary>
72+
Unknown
73+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
namespace NetContextClient.Models;
2+
3+
/// <summary>
4+
/// Represents a summary of code coverage across multiple files.
5+
/// </summary>
6+
public class CoverageSummary
7+
{
8+
/// <summary>
9+
/// Gets or sets the overall coverage percentage across all files.
10+
/// </summary>
11+
public float TotalCoveragePercentage { get; set; }
12+
13+
/// <summary>
14+
/// Gets or sets the total number of files analyzed.
15+
/// </summary>
16+
public int TotalFiles { get; set; }
17+
18+
/// <summary>
19+
/// Gets or sets the number of files with coverage below a warning threshold.
20+
/// </summary>
21+
public int FilesWithLowCoverage { get; set; }
22+
23+
/// <summary>
24+
/// Gets or sets the total number of uncovered lines across all files.
25+
/// </summary>
26+
public int TotalUncoveredLines { get; set; }
27+
28+
/// <summary>
29+
/// Gets or sets a list of files with the lowest coverage percentages.
30+
/// </summary>
31+
public List<CoverageReport> LowestCoverageFiles { get; set; } = [];
32+
33+
/// <summary>
34+
/// Number of production files analyzed
35+
/// </summary>
36+
public int ProductionFiles { get; set; }
37+
38+
/// <summary>
39+
/// Number of test files analyzed
40+
/// </summary>
41+
public int TestFiles { get; set; }
42+
43+
/// <summary>
44+
/// Average coverage percentage for production files
45+
/// </summary>
46+
public float ProductionCoveragePercentage { get; set; }
47+
48+
/// <summary>
49+
/// Average coverage percentage for test files
50+
/// </summary>
51+
public float TestCoveragePercentage { get; set; }
52+
}

0 commit comments

Comments
 (0)