Skip to content
Development
Skill

/dotnet-techne-crap-analysis

Use when you need CRAP score and coverage risk analysis to find high-risk code before refactoring or release. Keywords: CRAP score, risk hotspots, cyclomatic complexity, test coverage gaps, coverage threshold.

From plugin
dotnet-episteme-skills
1214 skills13 agents3 commands3 hooks
+1
Install
$ npx -y skills add Metalnib/dotnet-episteme-skills --skill dotnet-techne-crap-analysis --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/dotnet-techne-crap-analysis

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use when you need CRAP score and coverage risk analysis to find high-risk code before refactoring or release. Keywords: CRAP score, risk hotspots, cyclomatic complexity, test coverage gaps, coverage threshold.

SKILL.md

dotnet-techne-crap-analysis.SKILL.md
name: dotnet-techne-crap-analysis
description: "Use when you need CRAP score and coverage risk analysis to find high-risk code before refactoring or release. Keywords: CRAP score, risk hotspots, cyclomatic complexity, test coverage gaps, coverage threshold."
disable-model-invocation: false
user-invocable: true
metadata:
  author: Metalnib
  version: "1.0.0"
  trigger_keywords:
    - crap score
    - risk hotspots
    - cyclomatic complexity
    - test coverage gaps
    - coverage threshold

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.

<?xml version="1.0" encoding="utf-8" ?>
<RunSettings>
  <DataCollectionRunSettings>
    <DataCollectors>
      <DataCollector friendlyName="XPlat code coverage">
        <Configuration>
          <!-- OpenCover format includes cyclomatic complexity for CRAP scores -->
          <Format>cobertura,opencover</Format>

          <!-- Exclude test and benchmark assemblies -->
          <Exclude>[*.Tests]*,[*.Benchmark]*,[*.Migrations]*</Exclude>

          <!-- Exclude generated code, obsolete members, and explicit exclusions -->
          <ExcludeByAttribute>Obsolete,GeneratedCodeAttribute,CompilerGeneratedAttribute,ExcludeFromCodeCoverageAttribute</ExcludeByAttribute>

          <!-- Exclude source-generated files, Blazor generated code, and migrations -->
          <ExcludeByFile>**/obj/**/*,**/*.g.cs,**/*.designer.cs,**/*.razor.g.cs,**/*.razor.css.g.cs,**/Migrations/**/*</ExcludeByFile>

          <!-- Exclude test projects -->
          <IncludeTestAssembly>false</IncludeTestAssembly>

          <!-- Optimization flags -->
          <SingleHit>false</SingleHit>
          <UseSourceLink>true</UseSourceLink>
          <SkipAutoProps>true</SkipAutoProps>
        </Configuration>
      </DataCollector>
    </DataCollectors>
  </DataCollectionRunSettings>
</RunSettings>

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

{
  "version": 1,
  "isRoot": true,
  "tools": {
    "dotnet-reportgenerator-globaltool": {
      "version": "5.4.5",
      "commands": ["reportgenerator"],
      "rollForward": false
    }
  }
}

Then restore:

dotnet tool restore

Or Install Globally

dotnet tool install --global dotnet-reportgenerator-globaltool

---

Collecting Coverage

Run Tests with Coverage Collection

# Clean previous results
rm -rf coverage/ TestResults/

# Run unit tests with coverage
dotnet test tests/MyApp.Tests.Unit \
  --settings coverage.runsettings \
  --collect:"XPlat Code Coverage" \
  --results-directory ./TestResults

# Run integration tests (optional, adds to coverage)
dotnet test tests/MyApp.Tests.Integration \
  --settings coverage.runsettings \
  --collect:"XPlat Code Coverage" \
  --results-directory ./TestResults

Generate HTML Report

dotnet reportgenerator \
  -reports:"TestResults/**/coverage.opencover.xml" \
  -targetdir:"coverage" \
  -reporttypes:"Html;TextSummary;MarkdownSummaryGithub"

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**: Nu
Read more
Ships withdotnet-episteme-skills

DotNet Episteme Skills - a curated, manual-first .NET AI skills library rooted in systematic knowledge (episteme) and shaped by disciplined craft (techne), designed for engineers who prioritise precision over hype.

Get the whole plugin

Other skills on dotnet-episteme-skills.