Personalizar a análise de cobertura de código
Por padrão, a cobertura de código analisa todos os assemblies da solução que são carregados durante testes de unidade. Recomendamos que você use esse comportamento padrão, porque ele funciona bem na maioria das vezes. Para obter mais informações, consulte Use cobertura de código para determinar quanto código é testado.
Para excluir o código de teste dos resultados da cobertura de código e incluir apenas o código do aplicativo, adicione o atributo ExcludeFromCodeCoverageAttribute à sua classe de teste.
Para incluir assemblies que não fazem parte da sua solução, obtenha os arquivos .pdb para esses assemblies e copie-os para a mesma pasta que os arquivos de assembly .dll.
Executar arquivo de configurações
O ficheiro de definições é o ficheiro de configuração usado pelas ferramentas de testes de unidade. As configurações avançadas de cobertura de código são especificadas num ficheiro .runsettings
Para personalizar a cobertura de código, siga estas etapas:
Adicione um arquivo de configurações de execução à sua solução. No Gerenciador de Soluções , no menu de atalho da sua solução, escolha Adicionar>Novo Iteme selecione Arquivo XML. Salve o arquivo com um nome como CodeCoverage.runsettings.
Se não vir todos os modelos de item, escolha Mostrar Todos os Modelose, em seguida, escolha o modelo de item.
Adicione o conteúdo do arquivo de exemplo no final deste artigo e personalize-o de acordo com suas necessidades, conforme descrito nas seções a seguir.
Selecione um arquivo de configurações de execução.
A partir do Visual Studio 2019 versão 16.4, você pode detetar automaticamente um arquivo de configurações de execução na raiz do projeto. Caso contrário, no menu Teste, escolha Configurar definições de execuçãoe, em seguida, escolha Selecionar ficheiro de definições de execução geral para a solução. Para especificar um arquivo de configurações de execução para executar testes a partir da linha de comando, consulte Configurar testes de unidade.
Quando se seleciona Analisar cobertura de código, as informações de configuração são lidas do ficheiro de definições de execução.
Dica
Quaisquer resultados de cobertura de código anteriores e coloração de código não são automaticamente ocultos quando você executa testes ou atualiza seu código.
Para desativar e ativar as configurações personalizadas, desmarque ou selecione o arquivo no menu Test.
Para selecionar o ficheiro de definições de execução, no menu de teste , escolha Selecionar ficheiro de definições. Para especificar um arquivo de configurações de execução para executar testes a partir da linha de comando, consulte Configurar testes de unidade.
Ao selecionar Analisar Cobertura de Código, as informações de configuração são lidas a partir do ficheiro de definições de execução.
Dica
Quaisquer resultados de cobertura de código anteriores e coloração de código não são ocultados automaticamente quando executas testes ou atualizas o teu código.
Para ativar ou desativar as configurações personalizadas, escolha Testar, Configurar Definições de Execução, e desmarque ou selecione o nome do ficheiro.
Caminhos de pesquisa de símbolos
A cobertura de código requer ficheiros de símbolos (ficheiros .pdb) para assemblagens. Para conjuntos criados pela sua solução, os ficheiros de símbolo geralmente estão presentes ao lado dos ficheiros binários e a cobertura de código funciona automaticamente. Em alguns casos, poderá querer incluir compilações referenciadas na sua análise de cobertura de código. Nesses casos, os arquivos de .pdb
<SymbolSearchPaths>
<Path>\\mybuildshare\builds\ProjectX</Path>
<!--More paths if required-->
</SymbolSearchPaths>
Observação
A resolução de símbolos pode levar tempo, especialmente ao usar uma localização de ficheiro remoto com muitos conjuntos. Portanto, considere copiar os ficheiros .pdb para o mesmo local que os ficheiros binários (.dll e .exe).
Incluir ou excluir assembleias e membros
Você pode incluir ou excluir assemblies ou tipos e membros específicos da análise de cobertura de código. Se a seção Incluir estiver vazia ou omitida, todos os assemblies carregados e com arquivos PDB associados serão incluídos. Se um assembly ou membro corresponder a uma cláusula na seção Excluir, ele será excluído da cobertura de código. A secção Excluir tem precedência sobre a secção Incluir: se um assembly estiver simultaneamente listado nas secções Incluir e Excluir, ele não será incluído na cobertura de código.
Por exemplo, o XML a seguir exclui um único assembly especificando seu nome:
<ModulePaths>
<Exclude>
<ModulePath>.*Fabrikam.Math.UnitTest.dll</ModulePath>
<!-- Add more ModulePath nodes here. -->
</Exclude>
</ModulePaths>
O exemplo a seguir especifica que apenas um conjunto deve ser incluído na cobertura de código.
<ModulePaths>
<Include>
<ModulePath>.*Fabrikam.Math.dll</ModulePath>
<!-- Add more ModulePath nodes here. -->
</Include>
</ModulePaths>
A tabela a seguir mostra as várias maneiras pelas quais assemblies e membros podem ser combinados para inclusão ou exclusão da cobertura de código.
Elemento XML | O que corresponde |
---|---|
ModulePath | Corresponde aos assemblies especificados pelo nome do assembly ou caminho do arquivo. |
Nome da Empresa | Associa montagens pelo atributo Company. |
PublicKeyToken | Corresponde a assemblies assinados pelo token de chave pública. |
Fonte | Corresponde aos elementos pelo nome do caminho do arquivo de origem no qual eles estão definidos. |
Atributo | Corresponde aos elementos que têm o atributo especificado. Especifique o nome completo do atributo, por exemplo, <Attribute>^System\.Diagnostics\.DebuggerHiddenAttribute$</Attribute> .Se você excluir o atributo CompilerGeneratedAttribute, o código que usa recursos de linguagem como async , await , yield return e propriedades auto-implementadas será excluído da análise de cobertura de código. Para excluir o código verdadeiramente gerado, exclua apenas o atributo GeneratedCodeAttribute. |
Função | Corresponde procedimentos, funções ou métodos por nome totalmente qualificado, incluindo a lista de parâmetros. Você também pode corresponder parte do nome usando uma expressão regular . Exemplos: Fabrikam.Math.LocalMath.SquareRoot(double); (C#)Fabrikam::Math::LocalMath::SquareRoot(double) (C++) |
Formatos de cobertura de código
Por predefinição, a cobertura de código é coletada e salva em um ficheiro .coverage
. Você também pode coletar cobertura usando outros formatos, incluindo Xml e Cobertura. Diferentes formatos podem ser úteis em diferentes editores e pipelines. Você pode habilitar isso em runsettings adicionando <Format>Cobertura</Format>
ou <Format>Xml</Format>
na seção de configuração DataCollector em seu arquivo runsettings. Esse formato pode ser exibido na janela de resultados de cobertura de código no Visual Studio Enterprise.
Você também pode especificar formatos diferentes da linha de comando especificando-os no arquivo runsettings ou especificando-os em um parâmetro. Por exemplo, a utilização do comando dotnet na linha de comando dotnet test --collect:"Code Coverage;Format=Cobertura"
. Para o uso de vstest com vstest.console.exe /collect:"Code Coverage;Format=Cobertura"
. O parâmetro collect substituirá o formato especificado em runsettings.
Instrumentação nativa estática e dinâmica
No Visual Studio 2022 versão 17.2, adicionamos a opção de instrumentar binário nativo estaticamente (no disco). Nas versões anteriores, suportamos apenas instrumentação dinâmica, que muitas vezes não era capaz de instrumentar métodos. A instrumentação nativa estática é mais estável e é recomendada. A instrumentação nativa estática requer a ativação da opção de link de /PROFILE para todos os projetos nativos para os quais necessita de coleta de cobertura de código.
Você também pode habilitar a instrumentação estática nativa em runsettings adicionando a tag <EnableStaticNativeInstrumentation>True</EnableStaticNativeInstrumentation>
sob a tag <CodeCoverage>
. Use esse método para cenários de linha de comando.
Por padrão, a instrumentação nativa dinâmica está sempre ativada. Se a instrumentação estática e dinâmica estiver habilitada, o Visual Studio tentará instrumentar seu código C++ estaticamente, mas se isso não for possível (por exemplo, quando a opção de link /PROFILE
não estiver habilitada), a instrumentação dinâmica será usada. Você pode desativar totalmente a instrumentação nativa dinâmica em runsettings adicionando <EnableDynamicNativeInstrumentation>False</EnableDynamicNativeInstrumentation>
em <CodeCoverage>
.
Quando a instrumentação nativa estática estiver habilitada, os binários nativos serão instrumentados e substituídos no disco antes da execução do teste. Os binários originais serão restaurados após a execução do teste. Você pode desativar a restauração de arquivos originais em runsettings adicionando <EnableStaticNativeInstrumentationRestore>False</EnableStaticNativeInstrumentationRestore>
sob a tag <CodeCoverage>
. Isso pode ser especialmente útil em cenários de IC.
Quando a instrumentação nativa estática está habilitada, o Visual Studio pesquisará e instrumentará todos os binários nativos no diretório onde o binário de teste está localizado. Você pode especificar diretórios adicionais onde os binários devem ser pesquisados. O exemplo a seguir especifica que todos os binários nativos do C:\temp
e seus subdiretórios devem ser instrumentados, exceto arquivos que terminam com Fabrikam.Math.dll
.
<ModulePaths>
<IncludeDirectories>
<Directory Recursive="true">C:\temp</Directory>
</IncludeDirectories>
<Exclude>
<ModulePath>.*Fabrikam.Math.dll</ModulePath>
</Exclude>
</ModulePaths>
Expressões regulares
Os nós de inclusão e exclusão usam expressões regulares, que são diferentes de curingas. Todas as correspondências não diferenciam maiúsculas de minúsculas. Alguns exemplos são:
.* corresponde a uma cadeia de quaisquer caracteres
\. corresponde a um ponto "."
\( \) corresponde aos parênteses "( )"
\\ corresponde a um delimitador de caminho de arquivo "\"
^ corresponde ao início da cadeia de caracteres
$ corresponde ao final da cadeia de caracteres
O XML a seguir mostra como incluir e excluir assemblies específicos usando expressões regulares:
<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>
O XML a seguir mostra como incluir e excluir funções específicas usando expressões regulares:
<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>
Advertência
Se houver um erro em uma expressão regular, como um parêntese sem escape ou incomparável, a análise de cobertura de código não será executada.
Para obter mais informações sobre expressões regulares, consulte Usar expressões regulares no Visual Studio.
Exemplo de arquivo .runsettings
Copie este código e edite-o de acordo com as suas necessidades.
<?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>