crap-analysis

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.

By aaronontheweb · 501 installs

npx skills add aaronontheweb/dotnet-skills --skill crap-analysis

Source repository · Upstream listing

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 refactor ParseRecord() is complex but has decent coverage acceptable CreateUser() and Calculate() 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