aaronontheweb/dotnet-skills/crap-analysis
- community
Checking that the SKILL.md file is still in the repository.
Analyze code coverage and CRAP (Change Risk Anti-Patterns) scores to identify high-risk code. Use OpenCover format with ReportGenerator for Risk Hotspots showing cyclomatic complexity and untested code paths.
Install
npx vskill@latest install aaronontheweb/dotnet-skills/crap-analysisSKILL.md
CRAP Score Analysis
When to Use This Skill
Use this skill when:
- Evaluating code quality and test coverage before changes
- Identifying high-risk code that needs refactoring or testing
- Setting up coverage collection for a .NET project
- Prioritizing which code to test based on risk
- Establishing coverage thresholds for CI/CD pipelines
What is CRAP?
CRAP Score = Complexity x (1 - Coverage)^2
The CRAP (Change Risk Anti-Patterns) score combines cyclomatic complexity with test coverage to identify risky code.
| CRAP Score | Risk Level | Action Required | |
|---|---|---|---|
| < 5 | Low | Well-tested, maintainable code | |
| 5-30 | Medium | Acceptable but watch complexity | |
| > 30 | High | Needs tests or refactoring |
Why CRAP Matters
- High complexity + low coverage = danger: Code that's hard to understand AND untested is risky to modify
- Complexity alone isn't enough: A complex method with 100% coverage is safer than a simple method with 0%
- Focuses effort: Prioritize testing on complex code, not simple getters/setters
CRAP Score Examples
| Method | Complexity | Coverage | Calculation | CRAP | |
|---|---|---|---|---|---|
GetUserId() | 1 | 0% | 1 x (1 - 0)^2 | 1 | |
ParseToken() | 54 | 52% | 54 x (1 - 0.52)^2 | 12.4 | |
ValidateForm() | 20 | 0% | 20 x (1 - 0)^2 | 20 | |
ProcessOrder() | 45 | 20% | 45 x (1 - 0.20)^2 | 28.8 | |
ImportData() | 80 | 10% | 80 x (1 - 0.10)^2 | 64.8 |
Coverage Collection Setup
coverage.runsettings
Create a coverage.runsettings file in your repository root. The OpenCover format is required for CRAP score calculation because it includes cyclomatic complexity metrics.
Key Configuration Options
| Option | Purpose | |
|---|---|---|
Format | Must include opencover for complexity metrics | |
Exclude | Exclude test/benchmark assemblies by pattern | |
ExcludeByAttribute | Skip generated, obsolete, and explicitly excluded code (includes ExcludeFromCodeCoverageAttribute) | |
ExcludeByFile | Skip source-generated files, Blazor components, and migrations | |
SkipAutoProps | Don't count auto-properties as branches |
ReportGenerator Installation
Install ReportGenerator as a local tool for generating HTML reports with Risk Hotspots.
Add to .config/dotnet-tools.json
Then restore:
Or Install Globally
Collecting Coverage
Run Tests with Coverage Collection
Generate HTML Report
Report Types
| Type | Description | Output | |
|---|---|---|---|
Html | Full interactive report | coverage/index.html | |
TextSummary | Plain text summary | coverage/Summary.txt | |
MarkdownSummaryGithub | GitHub-compatible markdown | coverage/SummaryGithub.md | |
Badges | SVG badges for README | coverage/badge_*.svg | |
Cobertura | Merged Cobertura XML | coverage/Cobertura.xml |
Reading the Report
Risk Hotspots Section
The HTML report includes a Risk Hotspots section showing methods sorted by complexity:
- Cyclomatic Complexity: Number of independent paths through code (if/else, switch cases, loops)
- NPath Complexity: Number of acyclic execution paths (exponential growth with nesting)
- Crap Score: Calculated from complexity and coverage
Interpreting Results
Action items:
ValidateToken()has CRAP > 30 with 0% coverage - test immediately or refactorParseRecord()is complex but has decent coverage - acceptableCreateUser()andCalculate()are well-tested - safe to modify
Coverage Thresholds
Recommended Standards
| Coverage Type | Target | Action | |
|---|---|---|---|
| Line Coverage | > 80% | Good for most projects | |
| Branch Coverage | > 60% | Catches conditional logic | |
| CRAP Score | < 30 | Maximum for new code |
Configuring Thresholds
Create coverage.props in your repository:
CI/CD Integration
GitHub Actions
Azure Pipelines
Quick Reference
One-Liner Commands
Project Standards
| Metric | New Code | Legacy Code | |
|---|---|---|---|
| Line Coverage | 80%+ | 60%+ (improve gradually) | |
| Branch Coverage | 60%+ | 40%+ (improve gradually) | |
| Maximum CRAP | 30 | Document exceptions | |
| High-risk methods | Must have tests | Add tests before modifying |
What Gets Excluded
The recommended coverage.runsettings excludes:
| Pattern | Reason | |
|---|---|---|
[*.Tests]* | Test assemblies aren't production code | |
[*.Benchmark]* | Benchmark projects | |
[*.Migrations]* | Database migrations (generated) | |
GeneratedCodeAttribute | Source generators | |
CompilerGeneratedAttribute | Compiler-generated code | |
ExcludeFromCodeCoverageAttribute | Explicit developer opt-out | |
*.g.cs, *.designer.cs | Generated files | |
*.razor.g.cs | Blazor component generated code | |
*.razor.css.g.cs | Blazor CSS isolation generated code | |
**/Migrations/**/* | EF Core migrations (auto-generated) | |
SkipAutoProps | Auto-properties (trivial branches) |
When to Update Thresholds
Lower thresholds temporarily for:
- Legacy codebases being modernized (document in README)
- Generated code that can't be modified
- Third-party wrapper code
Never lower thresholds for:
- "It's too hard to test" - refactor instead
- "We'll add tests later" - add them now
- New features - should meet standards from the start
Additional Resources
- Coverlet Documentation: https://github.com/coverlet-coverage/coverlet
- ReportGenerator: https://github.com/danielpalme/ReportGenerator
- CRAP Score Original Paper: http://www.artima.com/weblogs/viewpost.jsp?thread=215899
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/crap-analysis/SKILL.md
Popularity
- Repository stars
- 1,088
- Repository forks
- 100
- 7-day trend score
- 35
Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 22 Mar 2026, 7 months ago.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/aaronontheweb/dotnet-skills/crap-analysis)