Přizpůsobte analýzu pokrytí kódu
Pokrytí kódu ve výchozím nastavení analyzuje všechna sestavení řešení načtená během jednotkových testů. Doporučujeme použít toto výchozí chování, protože ve většině případů funguje dobře. Další informace najdete v části Využití pokrytí kódu k určení rozsahu testovaného kódu.
Pokud chcete vyloučit testovací kód z výsledků pokrytí kódu a zahrnout pouze kód aplikace, přidejte do testovací třídy atribut ExcludeFromCodeCoverageAttribute.
Pokud chcete zahrnout sestavení, která nejsou součástí vašeho řešení, získejte soubory .pdb pro tato sestavení a zkopírujte je do stejné složky jako soubory .dll sestavení.
Spustit soubor nastavení
Soubor nastavení spuštění je konfigurační soubor používaný nástroji pro jednotkové testování. Pokročilé nastavení pokrytí kódu se zadává v souboru .runsettings.
Pokud chcete přizpůsobit pokrytí kódu, postupujte takto:
Přidejte do svého řešení soubor nastavení spuštění. V Průzkumník řešenív místní nabídce vašeho řešení zvolte Přidat>Nová položkaa vyberte Soubor XML. Uložte soubor s názvem, například CodeCoverage.runsettings.
Pokud nevidíte všechny šablony položek, zvolte Zobrazit všechny šablonya pak zvolte šablonu položky.
Přidejte obsah z ukázkového souboru na konec tohoto článku a pak ho upravte podle svých potřeb, jak je popsáno v následujících částech.
Vyberte soubor nastavení spuštění.
Počínaje verzí 16.4 sady Visual Studio 2019 můžete v kořenovém adresáři projektu automaticky detekovat soubor s nastavením spuštění. V opačném případě v nabídce Test zvolte Konfigurovat nastavení spuštěnía pak zvolte Vybrat soubor runsettings pro celé řešení. Pokud chcete zadat soubor nastavení spuštění pro spouštění testů z příkazového řádku, přečtěte si Konfigurace testů jednotek.
Když vyberete Analyzovat pokrytí kódu, informace o konfiguraci se načtou ze souboru nastavení spuštění.
Spropitné
Žádné předchozí výsledky pokrytí kódu a zvýraznění kódu se při spuštění testů nebo aktualizaci kódu automaticky neskryjí.
Pokud chcete vlastní nastavení vypnout a zapnout, zrušte výběr nebo vyberte soubor v nabídce Test.
Chcete-li vybrat soubor spouštěcího nastavení, v nabídce Test zvolte Vybrat soubor s nastavením. Pokud chcete zadat soubor nastavení spuštění pro spouštění testů z příkazového řádku, přečtěte si Konfigurace testů jednotek.
Když vyberete Analyzovat pokrytí kódu, informace o konfiguraci se načtou ze souboru nastavení spuštění.
Spropitné
Předchozí výsledky pokrytí kódu a zbarvení kódu se při spuštění testů nebo aktualizaci kódu nebudou automaticky skryty.
Pokud chcete vlastní nastavení vypnout a zapnout, zvolte Test, Konfigurovat nastavení spuštěnía zrušte výběr nebo vyberte název souboru.
Cesty hledání symbolů
Pokrytí kódu vyžaduje soubory symbolů (.pdb soubory) pro sestavení. Pro sestavení sestavená vaším řešením se soubory symbolů obvykle nacházejí společně s binárními soubory a pokrytí kódu funguje automaticky. V některých případech můžete chtít do analýzy pokrytí kódu zahrnout odkazovaná sestavení. V takových případech nemusí soubory .pdb sousedit s binárními soubory, ale můžete zadat cestu hledání symbolů v souboru .runsettings.
<SymbolSearchPaths>
<Path>\\mybuildshare\builds\ProjectX</Path>
<!--More paths if required-->
</SymbolSearchPaths>
Poznámka
Řešení symbolů může trvat delší dobu, zejména při použití vzdáleného umístění souboru s mnoha sestaveními. Proto zvažte kopírování souborů .pdb do stejného místního umístění jako binární soubory (.dll a .exe).
Zahrnutí nebo vyloučení sestavení a členů
Do analýzy pokrytí kódu můžete zahrnout nebo vyloučit sestavení nebo konkrétní typy a členy. Pokud je oddíl Zahrnout prázdný nebo vynechán, jsou zahrnuta všechna sestavení, která jsou načtena a mají přidružené soubory PDB. Pokud sestavení nebo člen odpovídá klauzuli v oddílu Exclude, je vyloučena z pokrytí kódu. Oddíl Vyloučit má přednost před oddílem Zahrnout: pokud je sestavení uvedeno v Zahrnout i Vyloučit, nebude zahrnuta do pokrytí kódu.
Například následující xml vylučuje jedno sestavení zadáním jeho názvu:
<ModulePaths>
<Exclude>
<ModulePath>.*Fabrikam.Math.UnitTest.dll</ModulePath>
<!-- Add more ModulePath nodes here. -->
</Exclude>
</ModulePaths>
Následující příklad určuje, že do pokrytí kódu by mělo být zahrnuto pouze jedno sestavení:
<ModulePaths>
<Include>
<ModulePath>.*Fabrikam.Math.dll</ModulePath>
<!-- Add more ModulePath nodes here. -->
</Include>
</ModulePaths>
Následující tabulka ukazuje různé způsoby, jak lze sestavení a členy spárovat s zahrnutím nebo vyloučením z pokrytí kódu.
XML element | Co tomu odpovídá |
---|---|
ModulePath | Odpovídá sestavením, které jsou určeny názvem sestavení nebo cestou k souboru. |
Název společnosti | Odpovídá sestavení podle atributu Společnost. |
PublicKeyToken | Sestavení podepsaná tokenem veřejného klíče odpovídají. |
Zdroj | Odpovídá prvkům podle názvu cesty zdrojového souboru, ve kterém jsou definované. |
Vlastnost | Odpovídá prvkům, které mají zadaný atribut. Zadejte úplný název atributu, například <Attribute>^System\.Diagnostics\.DebuggerHiddenAttribute$</Attribute> .Pokud vyloučíte atribut CompilerGeneratedAttribute, kód, který používá jazykové funkce, jako jsou async , await , yield return a automaticky implementované vlastnosti, se z analýzy pokrytí kódu vyloučil. Chcete-li vyloučit skutečně vygenerovaný kód, vylučte pouze atribut GeneratedCodeAttribute. |
Funkce | Odpovídá procedurám, funkcím nebo metodám podle plně kvalifikovaného názvu, včetně seznamu parametrů. Část názvu můžete také spárovat pomocí regulárního výrazu. Příklady: Fabrikam.Math.LocalMath.SquareRoot(double); (C#)Fabrikam::Math::LocalMath::SquareRoot(double) (C++) |
Formáty pokrytí kódu
Ve výchozím nastavení se shromažďuje a ukládá pokrytí kódu do souboru .coverage
. Pokrytí můžete také shromažďovat pomocí jiných formátů, včetně Xml a Cobertura. Různé formáty můžou být užitečné v různých editorech a kanálech. Můžete to povolit v runsettings přidáním <Format>Cobertura</Format>
nebo <Format>Xml</Format>
v části konfigurace DataCollector v souboru runsettings. Tento formát lze zobrazit v okně výsledků pokrytí kódu v sadě Visual Studio Enterprise.
Můžete také zadat různé formáty z příkazového řádku tak, že ho zadáte do souboru runsettings nebo ho zadáte v parametru. Například příkazový řádek dotnet používá dotnet test --collect:"Code Coverage;Format=Cobertura"
. Pro vstest použijte vstest.console.exe /collect:"Code Coverage;Format=Cobertura"
. Parametr collect přepíše formát zadaný v runsettings.
Statická a dynamická nativní instrumentace
V sadě Visual Studio 2022 verze 17.2 jsme přidali možnost instrumentace nativního binárního souboru staticky (na disku). V předchozích verzích jsme podporovali pouze dynamickou instrumentaci, která často nebyla schopna instrumentovat metody. Statická nativní instrumentace je stabilnější a doporučuje se. Statická nativní instrumentace vyžaduje povolení možnosti /PROFILE propojení pro všechny nativní projekty, pro které potřebujete kolekci pokrytí kódu.
Nativní statickou instrumentaci můžete také povolit v souborech runsettings přidáním <EnableStaticNativeInstrumentation>True</EnableStaticNativeInstrumentation>
pod značku <CodeCoverage>
. Tuto metodu použijte pro scénáře příkazového řádku.
Ve výchozím nastavení je dynamické nativní instrumentace vždy povolená. Pokud je povolená statická i dynamická instrumentace, Visual Studio se pokusí instrumentovat váš kód C++ staticky, ale pokud to není možné (například pokud není povolená možnost propojování /PROFILE
), použije se dynamická instrumentace. Dynamické nativní instrumentace můžete v souboru runsettings plně zakázat přidáním <EnableDynamicNativeInstrumentation>False</EnableDynamicNativeInstrumentation>
pod <CodeCoverage>
.
Pokud je povolena statická nativní instrumentace, budou nativní binární soubory instrumentovány a nahrazeny na disku před provedením testu. Po provedení testu se obnoví původní binární soubory. Můžete zakázat obnovení původních souborů v runsettings přidáním <EnableStaticNativeInstrumentationRestore>False</EnableStaticNativeInstrumentationRestore>
pod značku <CodeCoverage>
. To může být užitečné zejména ve scénářích CI.
Pokud je povolená statická nativní instrumentace, Visual Studio vyhledá a instrumentuje všechny nativní binární soubory v adresáři, kde se nachází testovací binární soubor. Můžete zadat další adresáře, ve kterých se mají prohledávat binární soubory. Následující příklad určuje, že všechny nativní binární soubory z C:\temp
a jeho podadresáře by měly být instrumentovány s výjimkou souborů končících Fabrikam.Math.dll
.
<ModulePaths>
<IncludeDirectories>
<Directory Recursive="true">C:\temp</Directory>
</IncludeDirectories>
<Exclude>
<ModulePath>.*Fabrikam.Math.dll</ModulePath>
</Exclude>
</ModulePaths>
Regulární výrazy
Zahrnující a vylučující uzly používají regulární výrazy, které nejsou totéž jako zástupné znaky. Všechny shody jsou case-insensitive, nerozlišují malá a velká písmena. Mezi příklady patří:
.* odpovídá řetězci libovolných znaků.
\. odpovídá tečkě "."
\( \) odpovídá závorkám "( )"
\\ odpovídá oddělovači cesty k souboru \.
^ odpovídá začátku řetězce.
$ odpovídá konci řetězce.
Následující xml ukazuje, jak zahrnout a vyloučit konkrétní sestavení pomocí regulárních výrazů:
<ModulePaths>
<Include>
<!-- Include all loaded .dll assemblies (but not .exe assemblies): -->
<ModulePath>.*\.dll$</ModulePath>
</Include>
<Exclude>
<!-- But exclude some assemblies: -->
<ModulePath>.*\\Fabrikam\.MyTests1\.dll$</ModulePath>
<!-- Exclude all file paths that contain "Temp": -->
<ModulePath>.*Temp.*</ModulePath>
</Exclude>
</ModulePaths>
Následující kód XML ukazuje, jak pomocí regulárních výrazů zahrnout a vyloučit konkrétní funkce:
<Functions>
<Include>
<!-- Include methods in the Fabrikam namespace: -->
<Function>^Fabrikam\..*</Function>
<!-- Include all methods named EqualTo: -->
<Function>.*\.EqualTo\(.*</Function>
</Include>
<Exclude>
<!-- Exclude methods in a class or namespace named UnitTest: -->
<Function>.*\.UnitTest\..*</Function>
</Exclude>
</Functions>
Varování
Pokud v regulárním výrazu dojde k chybě, například pokud je závorka neuniknutá nebo nespárovaná, analýza pokrytí kódu se nespustí.
Další informace o regulárních výrazech najdete v tématu Použití regulárních výrazů v sadě Visual Studio.
Ukázkový soubor .runsettings
Zkopírujte tento kód a upravte ho tak, aby vyhovoval vašim potřebám.
<?xml version="1.0" encoding="utf-8"?>
<!-- File name extension must be .runsettings -->
<RunSettings>
<DataCollectionRunSettings>
<DataCollectors>
<DataCollector friendlyName="Code Coverage" uri="datacollector://Microsoft/CodeCoverage/2.0" assemblyQualifiedName="Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector, Microsoft.VisualStudio.TraceCollector, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Configuration>
<CodeCoverage>
<Format>coverage</Format>
<!--
Additional paths to search for .pdb (symbol) files. Symbols must be found for modules to be instrumented.
If .pdb files are in the same folder as the .dll or .exe files, they are automatically found. Otherwise, specify them here.
Note that searching for symbols increases code coverage runtime. So keep this small and local.
-->
<!--
<SymbolSearchPaths>
<Path>C:\Users\username\source\repos\ProjectX</Path>
<Path>\\mybuildshare\builds\ProjectX</Path>
</SymbolSearchPaths>
-->
<!--
About include/exclude lists:
Empty "Include" clauses imply all; empty "Exclude" clauses imply none.
Each element in the list is a regular expression (ECMAScript syntax). See /visualstudio/ide/using-regular-expressions-in-visual-studio.
An item must first match at least one entry in the include list to be included.
Included items must then not match any entries in the exclude list to remain included.
-->
<!-- Match assembly file paths: -->
<ModulePaths>
<Include>
<ModulePath>.*\.dll$</ModulePath>
<ModulePath>.*\.exe$</ModulePath>
</Include>
<Exclude>
<ModulePath>.*CPPUnitTestFramework.*</ModulePath>
</Exclude>
<!-- Specifies additional list of directories where binaries static native instrumentation should be searched. -->
<IncludeDirectories>
<Directory Recursive="true">C:\b59fb11c-1611-4562-9a2b-c35719da65d3</Directory>
</IncludeDirectories>
</ModulePaths>
<!-- Match fully qualified names of functions: -->
<!-- (Use "\." to delimit namespaces in C# or Visual Basic, "::" in C++.) -->
<Functions>
<Exclude>
<Function>^Fabrikam\.UnitTest\..*</Function>
<Function>^std::.*</Function>
<Function>^ATL::.*</Function>
<Function>.*::__GetTestMethodInfo.*</Function>
<Function>^Microsoft::VisualStudio::CppCodeCoverageFramework::.*</Function>
<Function>^Microsoft::VisualStudio::CppUnitTestFramework::.*</Function>
</Exclude>
</Functions>
<!-- Match attributes on any code element: -->
<Attributes>
<Exclude>
<!-- Don't forget "Attribute" at the end of the name -->
<Attribute>^System\.Diagnostics\.DebuggerHiddenAttribute$</Attribute>
<Attribute>^System\.Diagnostics\.DebuggerNonUserCodeAttribute$</Attribute>
<Attribute>^System\.CodeDom\.Compiler\.GeneratedCodeAttribute$</Attribute>
<Attribute>^System\.Diagnostics\.CodeAnalysis\.ExcludeFromCodeCoverageAttribute$</Attribute>
</Exclude>
</Attributes>
<!-- Match the path of the source files in which each method is defined: -->
<Sources>
<Exclude>
<Source>.*\\atlmfc\\.*</Source>
<Source>.*\\vctools\\.*</Source>
<Source>.*\\public\\sdk\\.*</Source>
<Source>.*\\microsoft sdks\\.*</Source>
<Source>.*\\vc\\include\\.*</Source>
</Exclude>
</Sources>
<!-- Match the company name property in the assembly: -->
<CompanyNames>
<Exclude>
<CompanyName>.*microsoft.*</CompanyName>
</Exclude>
</CompanyNames>
<!-- Match the public key token of a signed assembly: -->
<PublicKeyTokens>
<!-- Exclude Visual Studio extensions: -->
<Exclude>
<PublicKeyToken>^B77A5C561934E089$</PublicKeyToken>
<PublicKeyToken>^B03F5F7F11D50A3A$</PublicKeyToken>
<PublicKeyToken>^31BF3856AD364E35$</PublicKeyToken>
<PublicKeyToken>^89845DCD8080CC91$</PublicKeyToken>
<PublicKeyToken>^71E9BCE111E9429C$</PublicKeyToken>
<PublicKeyToken>^8F50407C4E9E73B6$</PublicKeyToken>
<PublicKeyToken>^E361AF139669C375$</PublicKeyToken>
</Exclude>
</PublicKeyTokens>
<!-- We recommend you do not change the following values: -->
<!-- Set this to True to collect coverage information for functions marked with the "SecuritySafeCritical" attribute. Instead of writing directly into a memory location from such functions, code coverage inserts a probe that redirects to another function, which in turns writes into memory. -->
<UseVerifiableInstrumentation>True</UseVerifiableInstrumentation>
<!-- When set to True, collects coverage information from child processes that are launched with low-level ACLs, for example, UWP apps. -->
<AllowLowIntegrityProcesses>True</AllowLowIntegrityProcesses>
<!-- When set to True, collects coverage information from child processes that are launched by test or production code. -->
<CollectFromChildProcesses>True</CollectFromChildProcesses>
<!-- When set to True, restarts the IIS process and collects coverage information from it. -->
<CollectAspDotNet>False</CollectAspDotNet>
<!-- When set to True, static native instrumentation will be enabled. -->
<EnableStaticNativeInstrumentation>True</EnableStaticNativeInstrumentation>
<!-- When set to True, dynamic native instrumentation will be enabled. -->
<EnableDynamicNativeInstrumentation>True</EnableDynamicNativeInstrumentation>
<!-- When set to True, instrumented binaries on disk are removed and original files are restored. -->
<EnableStaticNativeInstrumentationRestore>True</EnableStaticNativeInstrumentationRestore>
</CodeCoverage>
</Configuration>
</DataCollector>
</DataCollectors>
</DataCollectionRunSettings>
</RunSettings>
<?xml version="1.0" encoding="utf-8"?>
<!-- File name extension must be .runsettings -->
<RunSettings>
<DataCollectionRunSettings>
<DataCollectors>
<DataCollector friendlyName="Code Coverage" uri="datacollector://Microsoft/CodeCoverage/2.0" assemblyQualifiedName="Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector, Microsoft.VisualStudio.TraceCollector, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Configuration>
<CodeCoverage>
<!--
Additional paths to search for .pdb (symbol) files. Symbols must be found for modules to be instrumented.
If .pdb files are in the same folder as the .dll or .exe files, they are automatically found. Otherwise, specify them here.
Note that searching for symbols increases code coverage runtime. So keep this small and local.
-->
<!--
<SymbolSearchPaths>
<Path>C:\Users\username\source\repos\ProjectX</Path>
<Path>\\mybuildshare\builds\ProjectX</Path>
</SymbolSearchPaths>
-->
<!--
About include/exclude lists:
Empty "Include" clauses imply all; empty "Exclude" clauses imply none.
Each element in the list is a regular expression (ECMAScript syntax). See /visualstudio/ide/using-regular-expressions-in-visual-studio.
An item must first match at least one entry in the include list to be included.
Included items must then not match any entries in the exclude list to remain included.
-->
<!-- Match assembly file paths: -->
<ModulePaths>
<Include>
<ModulePath>.*\.dll$</ModulePath>
<ModulePath>.*\.exe$</ModulePath>
</Include>
<Exclude>
<ModulePath>.*CPPUnitTestFramework.*</ModulePath>
</Exclude>
<!-- Specifies additional list of directories where binaries static native instrumentation should be searched. -->
<IncludeDirectories>
<Directory Recursive="true">C:\b59fb11c-1611-4562-9a2b-c35719da65d3</Directory>
</IncludeDirectories>
</ModulePaths>
<!-- Match fully qualified names of functions: -->
<!-- (Use "\." to delimit namespaces in C# or Visual Basic, "::" in C++.) -->
<Functions>
<Exclude>
<Function>^Fabrikam\.UnitTest\..*</Function>
<Function>^std::.*</Function>
<Function>^ATL::.*</Function>
<Function>.*::__GetTestMethodInfo.*</Function>
<Function>^Microsoft::VisualStudio::CppCodeCoverageFramework::.*</Function>
<Function>^Microsoft::VisualStudio::CppUnitTestFramework::.*</Function>
</Exclude>
</Functions>
<!-- Match attributes on any code element: -->
<Attributes>
<Exclude>
<!-- Don't forget "Attribute" at the end of the name -->
<Attribute>^System\.Diagnostics\.DebuggerHiddenAttribute$</Attribute>
<Attribute>^System\.Diagnostics\.DebuggerNonUserCodeAttribute$</Attribute>
<Attribute>^System\.CodeDom\.Compiler\.GeneratedCodeAttribute$</Attribute>
<Attribute>^System\.Diagnostics\.CodeAnalysis\.ExcludeFromCodeCoverageAttribute$</Attribute>
</Exclude>
</Attributes>
<!-- Match the path of the source files in which each method is defined: -->
<Sources>
<Exclude>
<Source>.*\\atlmfc\\.*</Source>
<Source>.*\\vctools\\.*</Source>
<Source>.*\\public\\sdk\\.*</Source>
<Source>.*\\microsoft sdks\\.*</Source>
<Source>.*\\vc\\include\\.*</Source>
</Exclude>
</Sources>
<!-- Match the company name property in the assembly: -->
<CompanyNames>
<Exclude>
<CompanyName>.*microsoft.*</CompanyName>
</Exclude>
</CompanyNames>
<!-- Match the public key token of a signed assembly: -->
<PublicKeyTokens>
<!-- Exclude Visual Studio extensions: -->
<Exclude>
<PublicKeyToken>^B77A5C561934E089$</PublicKeyToken>
<PublicKeyToken>^B03F5F7F11D50A3A$</PublicKeyToken>
<PublicKeyToken>^31BF3856AD364E35$</PublicKeyToken>
<PublicKeyToken>^89845DCD8080CC91$</PublicKeyToken>
<PublicKeyToken>^71E9BCE111E9429C$</PublicKeyToken>
<PublicKeyToken>^8F50407C4E9E73B6$</PublicKeyToken>
<PublicKeyToken>^E361AF139669C375$</PublicKeyToken>
</Exclude>
</PublicKeyTokens>
<!-- We recommend you do not change the following values: -->
<!-- Set this to True to collect coverage information for functions marked with the "SecuritySafeCritical" attribute. Instead of writing directly into a memory location from such functions, code coverage inserts a probe that redirects to another function, which in turns writes into memory. -->
<UseVerifiableInstrumentation>True</UseVerifiableInstrumentation>
<!-- When set to True, collects coverage information from child processes that are launched with low-level ACLs, for example, UWP apps. -->
<AllowLowIntegrityProcesses>True</AllowLowIntegrityProcesses>
<!-- When set to True, collects coverage information from child processes that are launched by test or production code. -->
<CollectFromChildProcesses>True</CollectFromChildProcesses>
<!-- When set to True, restarts the IIS process and collects coverage information from it. -->
<CollectAspDotNet>False</CollectAspDotNet>
</CodeCoverage>
</Configuration>
</DataCollector>
</DataCollectors>
</DataCollectionRunSettings>
</RunSettings>