Bestimmen des Umfangs des zu testenden Codes mithilfe von Code Coverage
Wenn Sie den Anteil des Projektcodes ermitteln möchten, der in codierten Tests wie Komponententests tatsächlich getestet wird, verwenden Sie das Code-Coverage-Feature von Visual Studio. Um sich effektiv vor Fehlern zu schützen, sollten Sie die Tests für den Großteil Ihres Codes ausführen.
Die Code-Coverage-Analyse ist sowohl in verwaltetem (CLR) als auch in nicht verwaltetem (nativem) Code möglich. Sowohl die statische als auch die dynamische Instrumentierung werden unterstützt. Um Code Coverage in Befehlszeilenszenarien anzuwenden, verwenden Sie entweder vstest.console.exe oder das Tool Microsoft.CodeCoverage.Console, das eine Erweiterung für dotnet-coverage ist, die auch nativen Code unterstützt.
Die Option „Code Coverage“ ist im Menü „Test“ verfügbar, wenn Sie Testmethoden mithilfe des Test-Explorers ausführen. In der Ergebnistabelle wird der Prozentsatz des Codes angegeben, der in den einzelnen Assemblys, Klassen und Prozeduren ausgeführt wurde. Der Quell-Editor hebt den getesteten Code hervor. Sie können die Ergebnisse in gängigen Formaten wie Cobertura exportieren.
Requirements (Anforderungen)
Das Code Coverage-Feature ist nur in der Visual Studio Enterprise-Edition verfügbar.
Hinweis
Für .NET-Code Coverage können Sie alternativ das Befehlszeilentool dotnet-coverage verwenden.
Analysieren von Code Coverage
Wählen Sie im Menü Test die Option Code Coverage für alle Tests analysieren aus.
Tipp
Sie können die Code Coverage auch über das Toolfenster Test-Explorer ausführen.
Nachdem der Test ausgeführt wurde, können Sie anzeigen, welche Zeilen ausgeführt wurden, indem Sie die Option Code Coverage-Färbung anzeigen im Fenster Code Coverage-Ergebnisse auswählen. Der von Tests abgedeckte Code wird standardmäßig hellblau hervorgehoben.
In der Dropdownliste für die Option Code Coverage-Färbung anzeigen können Sie auswählen, ob die Färbung auf Codezeilen, Glyphen im linken Bereich oder beides angewandt wird.
Zum Ändern der Farben oder zum Verwenden von Fettdruck wählen Sie Extras>Optionen>Umgebung>Schriftarten und Farben>Einstellungen anzeigen für: Text-Editor aus. Passen Sie unter Elemente anzeigen die Einstellungen der Elemente für „Coverage“ an, z. B. Von Code Coverage nicht verwendeter Bereich.
Wenn die Ergebnisse auf eine niedrige Abdeckung hindeuten, untersuchen Sie, welche Teile des Codes nicht ausgeführt werden, und schreiben Sie weitere Tests, um diese abzudecken. Entwicklungsteams streben normalerweise eine Codeabdeckung von ca. 80 % an. In einigen Situationen ist eine geringere Abdeckung akzeptabel. Beispielsweise ist eine geringere Abdeckung akzeptabel, wenn ein Teil des Codes aus einer Standardvorlage generiert wird.
Tipp
So optimieren Sie die Code Coverage:
- Deaktivieren Sie die Compileroptimierung.
- Verwenden Sie ein Debugbuild, wenn Sie mit nicht verwaltetem (nativem) Code arbeiten.
- Erstellen Sie PDB-Dateien (Symboldateien) für jede Assembly.
Sollten Sie nicht die erwarteten Ergebnisse erhalten, finden Sie weitere Informationen unter Problembehandlung bei der Code Coverage.
Vergessen Sie nicht, die Code Coverage nach Aktualisierung des Codes erneut auszuführen. Code-Coverage-Ergebnisse und Codefarbe werden nach Änderung des Codes oder der Ausführung von Tests nicht automatisch aktualisiert.
Tipp
Ab Visual Studio 2022 Update 2 können Sie schnellere Code Coverage-Testergebnisse aktivieren, indem Sie Extras > Optionen > Umgebung > Features in der Vorschau auswählen und dann Verbesserungen des Code Coverage-Erlebnisses auswählen und dann Visual Studio neu starten.
Berichterstellung in Blöcken oder in Zeilen
Die Codeabdeckung wird in Blöcken gezählt. Ein Block ist ein Codeabschnitt mit genau einem Ein- und Ausstiegspunkt. Wenn die Ablaufsteuerung des Programms einen Block während eines Testlaufs durchläuft, wird dieser Block als abgedeckt gezählt. Es wirkt sich nicht auf die Ergebnisse aus, wie oft der Block verwendet wird.
Die Ergebnisse können auch nach Zeile angezeigt werden, wenn Sie in der Tabellenkopfzeile Spalten hinzufügen/entfernen auswählen. Manche Benutzer bevorzugen die Zählung in Zeilen, da die Prozentsätze genauer der Größe der Fragmente entsprechen, die im Quellcode angezeigt werden. Ein langer Block mit Berechnungen zählt als ein einzelner Block, selbst wenn er viele Zeilen einnimmt.
Tipp
Eine Codezeile kann mehr als einen Codeblock enthalten. Wenn dies der Fall ist und der Testlauf alle Codeblöcke in der Zeile trainiert, wird sie als eine Zeile gezählt. Wenn nur manche Codeblöcke in der Zeile ausgeführt werden, wird sie als Teilzeile gezählt.
Filtern von Code Coverage-Ergebnissen
Im Fenster Code Coverage-Ergebnisse wird normalerweise das Ergebnis der gesamten Lösung angezeigt. Die Ergebnisse können gefiltert werden, um nur die Ergebnisse für die Dateien anzuzeigen, die im aktuellen Branch aktualisiert wurden.
- Um den Changeset-Bericht anzuzeigen, wählen Sie im Fenster Code Coverage-Ergebnisse das Symbol Code Coverage-Ansichten konfigurieren aus. Wählen Sie dann in der Dropdownliste Berichtsinhalt die Option Changeset-Bericht aus. Aktualisieren Sie das aktive Repository und den Basisbranch, um den Vergleichsbericht bereitzustellen.
Im Suchfeld im Fenster Code Coverage-Ergebnisse stehen Ihnen mehrere Möglichkeiten zum Filtern des Berichts zur Verfügung.
- Geben Sie die Suchzeichenfolge in das Suchfeld ein, um die Option Nach Namen suchen zu verwenden (es werden nur die Ergebnisse angezeigt, die der Suchzeichenfolge im Fenster entsprechen).
- Geben Sie zum Verwenden der Option Nach Typ filtern den Namen des Typs in das Suchfeld ein.
- Für die Option Alle anzeigen leeren Sie das Suchfeld.
- Für Vollständig abgedeckt (100 %) anzeigen geben Sie „abgedeckt (%Lines)“:„100“ in das Suchfeld ein.
- Für Teilweise abgedeckt (>0% && < 100%) anzeigen geben Sie „teilweise abgedeckt (%Lines)“:„<##“ ein und ersetzen dabei „##“ durch den abgedeckten Prozentsatz.
- Für 0 % abgedeckt anzeigen geben Sie „nicht abgedeckt (%Lines)“:„0“ in das Suchfeld ein.
Verwalten von Code Coverage-Ergebnissen
Im Fenster Code Coverage-Ergebnisse wird normalerweise das Ergebnis der letzten Ausführung angezeigt. Die Ergebnisse ändern sich, wenn Sie die Testdaten ändern oder jeweils nur einige Tests ausführen.
Das Fenster Code Coverage-Ergebnisse kann auch zur Anzeige von vorherigen Ergebnissen oder von Ergebnissen verwendet werden, die über andere Computer erzielt wurden.
Sie können die Ergebnisse aus mehreren Testläufen zusammenführen, zum Beispiel aus Testläufen, in denen unterschiedliche Testdaten verwendet werden.
Um ein vorheriges Resultset aufzurufen, wählen Sie dieses aus dem Dropdownmenü aus. Das Menü enthält eine temporäre Liste, die gelöscht wird, wenn Sie eine neue Projektmappe öffnen.
Zum Aufrufen von Ergebnissen aus einer vorherigen Sitzung müssen Sie auf Code Coverage-Ergebnisse importieren klicken, zum Ordner TestResults in Ihrer Projektmappe navigieren und eine COVERAGE-Datei importieren.
Die Code Coverage-Färbung ist möglicherweise falsch, wenn der Quellcode nach Generieren der COVERAGE-Datei geändert wurde.
Um die Ergebnisse als Text lesbar zu machen, wählen Sie Codeabdeckungsergebnisse exportieren aus. Dadurch wird eine lesbare COVERAGEXML-Datei generiert, die mit anderen Tools verarbeitet oder problemlos in einer E-Mail gesendet werden kann. Sie können auch Exportformate wie Cobertura auswählen.
Wenn Sie Ergebnisse an eine andere Person senden möchten, müssen Sie entweder eine COVERAGE-Datei oder eine exportierte COVERAGEXML-Datei senden. Die Datei kann dann importiert werden. Verfügt die andere Person über dieselbe Version des Quellcodes, kann sie die Abdeckungsfärbung sehen.
Zusammenführen von Ergebnissen aus verschiedenen Ausführungen
In einigen Situationen werden abhängig von den Testdaten andere Blöcke im Code verwendet. Daher sollten Sie die Ergebnisse aus verschiedenen Testläufen kombinieren.
Bei einem Test mit der Eingabe "2 " stellen Sie beispielsweise fest, dass 50 % einer bestimmten Funktion abgedeckt werden. Wenn Sie den Test ein zweites Mal mit der Eingabe „-2“ ausführen, sehen Sie in der Ansicht der Code Coverage-Färbung, dass die anderen 50 % der Funktion abgedeckt werden. Führen Sie nun die Ergebnisse aus den zwei Testläufen zusammen. Der Bericht und die Code-Coverage-Färbung geben nun an, dass alle Funktionen abgedeckt werden.
Verwenden Sie dazu Code Coverage-Ergebnisse zusammenführen. Sie können eine beliebige Kombinationen aus den letzten Testläufen oder aus importierten Ergebnissen auswählen. Wenn Sie exportierte Ergebnisse kombinieren möchten, müssen Sie diese zuerst importieren.
Speichern Sie die Ergebnisse eines Zusammenführungsvorgangs mithilfe der Option Export Code Coverage Results (Codeabdeckungsergebnisse exportieren).
Einschränkungen beim Zusammenführen
Wenn Sie Code-Coverage-Daten aus verschiedenen Versionen desselben Codes zusammenführen, werden die Ergebnisse separat dargestellt und sind nicht kombiniert. Um vollständig kombinierte Ergebnisse zu erhalten, verwenden Sie denselben Build des Codes, und ändern Sie nur die Testdaten.
Wenn Sie eine Ergebnisdatei zusammenführen, die exportiert und anschließend importiert wurde, können Sie die Ergebnisse nur nach Zeilen und nicht nach Blöcken anzeigen. Verwenden Sie den Befehl Spalten hinzufügen/entfernen, um die Zeilendaten anzuzeigen.
Wenn Sie Ergebnisse aus Tests für ein ASP.NET-Projekt zusammenführen, werden die Ergebnisse für die separaten Tests angezeigt und sind nicht kombiniert. Dieses Verhalten gilt nur für ASP.NET-Artefakte selbst. Die Ergebnisse für alle anderen Assemblys werden kombiniert dargestellt.
Ausschließen von Elementen aus den Code Coverage-Ergebnissen
Sie können bestimmte Elemente im Code aus den Abdeckungsergebnissen ausschließen, zum Beispiel, wenn der Code aus einer Textvorlage generiert wird. Fügen Sie das System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute-Attribut zu einem der folgenden Codeelemente hinzu: Klasse, Struktur, Methode, Eigenschaft-Setter oder -Getter oder Ereignis.
Tipp
Durch das Ausschließen einer Klasse werden deren abgeleitete Klassen nicht ausgeschlossen.
Beispiel:
using System.Diagnostics.CodeAnalysis;
...
public class ExampleClass1
{
[ExcludeFromCodeCoverage]
void ExampleMethod() {...}
[ExcludeFromCodeCoverage] // exclude property
int ExampleProperty1
{ get {...} set{...}}
int ExampleProperty2
{
get
{
...
}
[ExcludeFromCodeCoverage] // exclude setter
set
{
...
}
}
}
[ExcludeFromCodeCoverage]
class ExampleClass2 { ... }
Verwenden Sie folgende Makros:
ExcludeFromCodeCoverage(
ExclusionName , L"
FunctionName ");
ExcludeSourceFromCodeCoverage(
ExclusionName , L"
SourceFilePath ");
ExclusionName ist ein eindeutiger Name.
FunctionName ist ein vollqualifizierter Funktionsname. Er enthält möglicherweise Platzhalter. Um beispielsweise alle Funktionen einer Klasse auszuschließen, schreiben Sie
MyNamespace::MyClass::*
SourceFilePath ist der lokale oder UNC-Pfad einer CPP-Datei. Er enthält möglicherweise Platzhalter. Im folgenden Beispiel werden alle Dateien in einem bestimmten Verzeichnis ausgeschlossen:
\\MyComputer\Source\UnitTests\*.cpp
#include <CodeCoverage\CodeCoverage.h>
Platzaufrufe zu den Ausschlussmakros im globalen Namespace, nicht innerhalb eines Namespace oder einer Klasse.
Sie können die Ausschlüsse entweder in der Komponententestcodedatei oder in der Anwendungscodedatei platzieren.
Die Ausschlüsse müssen als nicht verwalteter (systemeigener) Code kompiliert werden, indem Sie entweder die Compileroption festlegen oder
#pragma managed(off)
verwenden.
Hinweis
Um Funktionen in C++/CLI-Code auszuschließen, wenden Sie das Attribut [System::Diagnostics::CodeAnalysis::ExcludeFromCodeCoverage]
auf die Funktion an. Dasselbe gilt für C#.
Ein- oder Ausschließen von zusätzlichen Elementen
Die Code Coverage-Analyse wird nur in Assemblys durchgeführt, die geladen wurden und für die im selben Verzeichnis eine PDB-Datei verfügbar ist, in dem auch die DLL- oder EXE-Datei enthalten ist. Daher können Sie in bestimmten Fällen die enthaltenen Assemblys erweitern, indem Sie Kopien der entsprechenden PDB-Dateien abrufen.
Sie können besser steuern, welche Assemblys und Elemente für die Code Coverage-Analyse ausgewählt werden, indem Sie eine RUNSETTINGS-Datei schreiben. Beispielsweise können Sie Assemblys bestimmter Arten ausschließen, ohne deren Klassen Attribute hinzuzufügen. Weitere Informationen finden Sie unter Anpassen der Code Coverage-Analyse.
Analysieren von Code Coverage in Azure Pipelines
Wenn Sie Code einchecken, werden Ihre Tests zusammen mit Tests von anderen Teammitgliedern auf dem Buildserver ausgeführt. Es ist hilfreich, die Code Coverage in Azure Pipelines zu analysieren, um das aktuellste und umfassendste Bild der Code Coverage für das gesamte Projekt zu erhalten. Zur Code Coverage in Azure Pipelines gehören auch automatisierte Systemtests und andere codierte Tests, die Sie normalerweise nicht auf Entwicklungscomputern ausführen.
Analysieren von Code Coverage über die Befehlszeile
Verwenden Sie das Hilfsprogramm vstest.console.exe, um Tests über die Befehlszeile auszuführen. Code Coverage ist eine Option des Hilfsprogramms vstest.console.exe, die über die Option /EnableCodeCoverage
aufgerufen wird.
Starten Sie die Developer-Eingabeaufforderung für Visual Studio:
Suchen Sie im Windows-Startmenü nach
Developer Command Prompt for VS
, und wählen Sie die App aus den Ergebnissen aus, die Ihrem Suchbegriff entspricht.Führen Sie an der Eingabeaufforderung den folgenden Befehl aus:
vstest.console.exe MyTestAssembly.dll /EnableCodeCoverage
Tipp
Für Developer PowerShell ist das Startverzeichnis der Shell der Projektspeicherort von Visual Studio. Ersetzen Sie MyTestAssembly.dll durch den Pfad und den Namen der Testdatei. Weitere Informationen finden Sie unter Befehlszeilenoptionen von „VSTest.Console.exe“.
Problembehandlung
Wenn keine Code-Coverage-Ergebnisse angezeigt werden, lesen Sie den Artikel Problembehandlung bei der Code Coverage.