Code-Abdeckung in C#: Von Metriken zur Qualität

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Warum „grüne“ Tests noch kein Sieg sind?

\n\n

Stellen Sie sich vor: Sie haben hundert Unit-Tests geschrieben, alle bestehen mit einem grünen Häkchen, die CI-Pipeline ist glücklich, der Manager zufrieden. Aber einen Monat später fällt eine kritische Funktion in der Produktion aus. Eine bekannte Geschichte? Meistens liegt das Problem darin, dass wir die falschen Szenarien testen oder ganze Codezweige überspringen.

\n\n

Code-Abdeckung (Code Coverage) ist nicht nur eine modische Metrik für den Bericht. Sie ist Ihre Taschenlampe im dunklen Raum der Unsicherheit. Als ich anfing, mit C# zu arbeiten, dachte ich, 80% Abdeckung seien das Ideal. Aber dann wurde mir klar: Man kann 100% Zeilenabdeckung haben und dennoch einen Fehler in der Verzweigungslogik übersehen. Deshalb schauen wir uns heute an, wie man die Abdeckung in C# richtig misst, welche Tools wirklich helfen und welche Metriken man verfolgen sollte.

\n\n

Was ist Code-Abdeckung und warum ist sie für C#-Entwickler wichtig?

\n\n

Einfach ausgedrückt zeigt die Code-Abdeckung, wie viel Prozent des Quellcodes Ihrer Anwendung während der Testausführung ausgeführt wurden. Wenn Sie einen Test geschrieben haben, der die Methode CalculateDiscount() aufruft, aber den Zweig if (isPremiumUser) nicht prüft, bleibt dieser Zweig „unabgedeckt“.

\n\n

Für einen C#-Entwickler ist die Abdeckung ein Indikator für zwei Dinge:

\n
    \n
  • Vertrauen in Refactoring — Kann man Code ändern, ohne Angst zu haben, etwas zu beschädigen?
  • \n
  • Vollständigkeit der Tests — Haben wir Grenzfälle vergessen?
  • \n
\n\n

Aber es gibt eine wichtige Nuance: Code-Abdeckung in C# garantiert nicht die Abwesenheit von Fehlern. Sie sagt lediglich, dass bestimmte Zeilen ausgeführt wurden. Deshalb schauen wir nicht nur auf den Prozentsatz, sondern auf die spezifischen Metriken.

\n\n

Wichtige Metriken der Code-Abdeckung in .NET

\n\n

Wenn Sie eine Abdeckungsanalyse in C# durchführen, stoßen Sie auf verschiedene Arten von Metriken. Lassen Sie uns jede anhand eines realen Codebeispiels durchgehen.

\n\n

Line Coverage (Zeilenabdeckung)

\n

Die einfachste Metrik. Sie zählt, wie viele Codezeilen von Tests berührt wurden. Beispiel:

\n\n
public int Add(int a, int b)\n{\n    if (a < 0)          // Zeile 1\n        return 0;       // Zeile 2\n    return a + b;        // Zeile 3\n}
\n\n

Wenn Ihr Test Add(5, 3) aufruft, werden die Zeilen 1 und 3 ausgeführt. Zeile 2 bleibt unabgedeckt. Die Line Coverage zeigt 66% (2 von 3 Zeilen).

\n\n

Branch Coverage (Zweigabdeckung)

\n

Eine ehrlichere Metrik. Sie berücksichtigt alle möglichen Ausführungspfade. In unserem Beispiel gibt es zwei Pfade: wenn a < 0 und wenn nicht. Wenn Sie nur den Fall mit einer positiven Zahl geprüft haben, beträgt die Branch Coverage 50%.

\n\n

Gerade die Branch Coverage deckt oft „Lücken“ in Tests auf. Ich empfehle, bei dieser Metrik 80%+ anzustreben.

\n\n

Cyclomatic Complexity und ihr Zusammenhang mit der Abdeckung

\n

Obwohl dies keine direkte Abdeckungsmetrik ist, zeigt die zyklomatische Komplexität, wie viele Tests für eine vollständige Abdeckung erforderlich sind. Je höher die Komplexität einer Methode, desto mehr Tests werden benötigt. Wenn Sie eine Methode mit einer zyklomatischen Komplexität von 15 und einer Abdeckung von 90% sehen, testen Sie wahrscheinlich nicht alle Szenarien.

\n\n

Tools zur Messung der Code-Abdeckung in C#

\n\n

Im .NET-Ökosystem gibt es mehrere leistungsstarke Tools. Ich stelle die drei bekanntesten vor, mit denen ich selbst gearbeitet habe.

\n\n

Coverlet — Kostenlos und in .NET integriert

\n

Wenn Sie .NET 6+ verwenden, ist Coverlet bereits über NuGet verfügbar. Es ist mein Lieblingstool für CI/CD, da es keine Installation zusätzlicher Programme erfordert.

\n\n

Installation:

\n
dotnet add package coverlet.msbuild\ndotnet add package coverlet.collector
\n\n

Ausführung mit Bericht:

\n
dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
\n\n

Sie erhalten eine Datei coverage.opencover.xml, die Sie mit ReportGenerator visualisieren können:

\n
dotnet tool install -g dotnet-reportgenerator-globaltool\nreportgenerat                

Blogs

Buchempfehlungen