Utilitário de cobertura de código de cobertura dotnet

Este artigo se aplica ao: ✔️ .NET Core 3.1 SDK e às versões posteriores

Sinopse

dotnet-coverage [-h, --help] [--version] <command>

Descrição

A ferramenta dotnet-coverage:

  • Permite a coleta de plataforma cruzada de dados de cobertura de código de um processo em execução.
  • Fornece a mesclagem multiplataforma de relatórios de cobertura de código.

Opções

  • -h|--help

    Mostra a ajuda da linha de comando.

  • --version

    Exibe a versão do utilitário de cobertura dotnet.

Instalar

Para instalar a versão de versão mais recente do dotnet-coveragepacote NuGet, use o comando de instalação da ferramenta dotnet :

dotnet tool install --global dotnet-coverage

Comandos

Comando
dotnet-coverage merge
dotnet-coverage collect
dotnet-coverage connect
dotnet-coverage snapshot
dotnet-coverage shutdown
dotnet-coverage instrument

dotnet-coverage merge

O comando merge é usado para mesclar vários relatórios de cobertura de código em um. Esse comando está disponível em todas as plataformas. Esse comando dá suporte aos seguintes formatos de relatório de cobertura de código:

  • coverage
  • cobertura
  • xml

Sinopse

dotnet-coverage merge
    [--remove-input-files]
    [-o|--output <output>] [-f|--output-format <output-format>]
    [-l|--log-file <log-file>] [-ll|--log-level <log-level>] [-?|-h|--help]
    <files>

Argumentos

  • <files>

    Os relatórios de cobertura de código de entrada.

Opções

  • --remove-input-files

    Remove todos os relatórios de cobertura de entrada que foram mesclados.

  • -r, --recursive

    O SDK do .NET 7 e versões anteriores pesquisam relatórios de cobertura somente em subdiretórios.

  • -o|--output <output>

    Define o arquivo de saída do relatório de cobertura de código.

  • -f|--output-format <output-format>

    O formato do arquivo de saída. Os valores compatíveis são: coverage, xml e cobertura. O padrão é coverage (formato binário que pode ser aberto no Visual Studio).

  • -l|--log-file <log-file>

    Define o caminho do arquivo de log. Quando você fornece um diretório (com um separador de caminho no final), um novo arquivo de log é gerado para cada processo em análise.

  • -ll|--log-level <log-level>

    Define o nível do log. Os valores compatíveis são: Error, Info e Verbose.

dotnet-coverage collect

O comando collect é usado para coletar dados de cobertura de código para qualquer processo .NET e seus subprocessos. Por exemplo, você pode coletar dados de cobertura de código para um aplicativo de console ou um aplicativo Blazor. Esse comando dá suporte à instrumentação dinâmica e estática. A instrumentação estática está disponível em todas as plataformas. Você pode especificar os arquivos que deseja instrumentar estaticamente usando a opção include-files. A instrumentação dinâmica está disponível no Windows (x86, x64 e Arm64), Linux (x64) e macOS (x64). O comando é compatível apenas com módulos .NET. Não há suporte a módulos nativos.

Sinopse

O comando collect pode ser executado em dois modos.

Modo de comando

O comando collect coletará cobertura de código para o determinado processo executado pelo argumento command.

dotnet-coverage collect
    [-s|--settings <settings>] [-id|--session-id <session-id>]
    [-if|--include-files <include-files>] [-o|--output <output>]
    [-f|--output-format <output-format>] [-l|--log-file <log-file>]
    [-ll|--log-level <log-level>] [-?|-h|--help]
    <command> <args>

Modo do Servidor

O comando collect hospeda um servidor para a coleção de cobertura de código. Os clientes podem se conectar ao servidor por meio do comando connect.

dotnet-coverage collect
    [-s|--settings <settings>] [-id|--session-id <session-id>]
    [-sv|--server-mode] [-b|--background] [-t|--timeout]
    [-if|--include-files <include-files>] [-o|--output <output>]
    [-f|--output-format <output-format>] [-l|--log-file <log-file>]
    [-ll|--log-level <log-level>] [-?|-h|--help]

Argumentos

  • <command>

    O comando para o qual coletar dados de cobertura de código.

  • <args>

    Argumentos de linha de comando para o argumento de comando.

Opções

  • -s|--settings <settings>

    Define o caminho para as configurações de cobertura de código XML.

  • -id|--session-id <session-id>

    Especifica a ID da sessão de cobertura de código. Se não for fornecida, a ferramenta gerará um GUID aleatório.

  • -sv|--server-mode

    Inicia o coletor no modo de servidor. Os clientes podem se conectar ao servidor com o comando connect.

  • -b|--background

    Inicia o servidor de coleta de cobertura de código em um novo processo em segundo plano. Os clientes podem se conectar ao servidor com o comando connect.

  • -t|--timeout

    Tempo limite (em milissegundos) para comunicação entre clientes e o servidor.

  • -if|--include-files <include-files>

    Especifica a lista de arquivos que serão instrumentados estaticamente.

  • -o|--output <output>

    Define o arquivo de saída do relatório de cobertura de código.

  • -f|--output-format <output-format>

    O formato do arquivo de saída. Os valores compatíveis são: coverage, xml e cobertura. O padrão é coverage (formato binário que pode ser aberto no Visual Studio).

  • -l|--log-file <log-file>

    Define o caminho do arquivo de log. Quando você fornece um diretório (com um separador de caminho no final), um novo arquivo de log é gerado para cada processo em análise.

  • -ll|--log-level <log-level>

    Define o nível do log. Os valores compatíveis são: Error, Info e Verbose.

dotnet-coverage connect

O comando connect é usado para se conectar ao servidor existente e coleta dados de cobertura de código para qualquer processo .NET e seus subprocessos. Por exemplo, você pode coletar dados de cobertura de código para um aplicativo de console ou um aplicativo Blazor. O comando é compatível apenas com módulos .NET. Não há suporte a módulos nativos.

Observação

O comando usará instrumentação dinâmica para todos os subprocessos disponíveis no Windows (x86, x64 e Arm64), Linux (x64) e macOS (x64). Se você precisar instrumentar estaticamente qualquer módulo .NET, use o comando instrument (com a opção de ID de sessão correspondente) antes de executar o comando connect.

Sinopse

dotnet-coverage connect
    [-b|--background] [-t|--timeout]
    [-l|--log-file <log-file>] [-ll|--log-level <log-level>] [-?|-h|--help]
    <session>
    <command> <args>

Argumentos

  • <session>

    A ID da sessão do servidor hospedado pelo comando collect.

  • <command>

    O comando para o qual coletar dados de cobertura de código.

  • <args>

    Argumentos de linha de comando para o argumento de comando.

Opções

  • -b|--background

    Inicia o cliente em um novo processo em segundo plano.

  • -t|--timeout

    Tempo limite (em milissegundos) para comunicação entre processos entre clientes e o servidor.* -l|--log-file <log-file>

  • -l|--log-file <log-file>

    Define o caminho do arquivo de log. Quando você fornece um diretório (com um separador de caminho no final), um novo arquivo de log é gerado para cada processo em análise.

  • -ll|--log-level <log-level>

    Define o nível do log. Os valores compatíveis são: Error, Info e Verbose.

dotnet-coverage snapshot

Cria um arquivo de cobertura para a coleção de cobertura de código existente.

Sinopse

dotnet-coverage snapshot
    [-r|--reset]
    [-o|--output <output>]
    [-tn|--tag-name <tag-name>] [-tid|--tag-identifier <tag-identifier>]
    [-t|--timeout]
    [-l|--log-file <log-file>] [-ll|--log-level <log-level>] [-?|-h|--help]
    <session>

Argumentos

  • <session>

    A ID da sessão da coleção para a qual um arquivo de cobertura deve ser gerada.

Opções

  • -r|--reset <reset>

    Limpa as informações de cobertura existentes depois que um arquivo de cobertura é criado.

  • -o|--output <output>

    Define o arquivo de saída do relatório de cobertura de código. Se não for fornecido, ele será gerado automaticamente com um carimbo de data/hora.

  • -tn|--tag-name <tag-name>

    Cria um nome de marca de instantâneo no arquivo de cobertura com informações de cobertura atuais. Identificador de marca e nome são mutuamente inclusivos.

  • -tid|--tag-identifier <tag-identifier>

    Cria um identificador de marca de instantâneo no arquivo de cobertura com as informações de cobertura atuais. Identificador de marca e nome são mutuamente inclusivos.

  • -t|--timeout

    Tempo limite (em milissegundos) para comunicação entre processos entre clientes e o servidor.

  • -l|--log-file <log-file>

    Define o caminho do arquivo de log. Quando você fornece um diretório (com um separador de caminho no final), um novo arquivo de log é gerado para cada processo em análise.

  • -ll|--log-level <log-level>

    Define o nível do log. Os valores compatíveis são: Error, Info e Verbose.

dotnet-coverage shutdown

Fecha a coleção de cobertura de código existente.

Sinopse

dotnet-coverage shutdown
    [-t|--timeout]
    [-l|--log-file <log-file>] [-ll|--log-level <log-level>] [-?|-h|--help]
    <session>

Argumentos

  • <session>

    A ID da sessão da coleção a ser fechada.

Opções

  • -t|--timeout

    Tempo limite (em milissegundos) para comunicação entre processos com o servidor.

  • -l|--log-file <log-file>

    Define o caminho do arquivo de log. Quando você fornece um diretório (com um separador de caminho no final), um novo arquivo de log é gerado para cada processo em análise.

  • -ll|--log-level <log-level>

    Define o nível do log. Os valores compatíveis são: Error, Info e Verbose.

dotnet-coverage instrument

O comando instrument é usado para instrumentar o binário no disco.

Sinopse

dotnet-coverage instrument
    [-s|--settings <settings>] [-id|--session-id <session-id>]
    [-o|--output <output>] [-l|--log-file <log-file>]
    [-ll|--log-level <log-level>] [-?|-h|--help]
    <input-file>

Argumentos

  • <input-file>

    O binário de entrada.

Opções

  • -s|--settings <settings>

    Define o caminho para as configurações de cobertura de código XML.

  • -id|--session-id <session-id>

    Especifica a ID da sessão de cobertura de código. Se não for fornecida, a ferramenta gerará um GUID aleatório.

  • -o|--output <output>

    Define o caminho para o binário do arquivo de saída. Se ele não for fornecido, a instrumentação será executada in-loco.

  • -l|--log-file <log-file>

    Define o caminho do arquivo de log. Quando você fornece um diretório (com um separador de caminho no final), um novo arquivo de log é gerado para cada processo em análise.

  • -ll|--log-level <log-level>

    Define o nível do log. Os valores compatíveis são: Error, Info e Verbose.

Exemplo de cenários

Coletando cobertura de código

Colete dados de cobertura de código para qualquer aplicativo .NET (como console ou Blazor) usando o seguinte comando:

dotnet-coverage collect dotnet run

No caso de um aplicativo que exija que um sinal seja encerrado, você pode usar Ctrl+C, que ainda permitirá coletar dados de cobertura de código. Para o argumento, você pode fornecer qualquer comando que eventualmente inicie um aplicativo .NET. Por exemplo, pode ser um script do PowerShell.

Sessões

Quando você está executando a análise de cobertura de código em um servidor .NET que apenas aguarda mensagens e envia respostas, você precisa de uma maneira de parar o servidor para obter resultados finais de cobertura de código. Você pode usar Ctrl+C localmente, mas não no Azure Pipelines. Nesses cenários, você pode usar sessões. Você pode especificar uma ID de sessão ao iniciar a coleção e, em seguida, usar o comando shutdown para interromper a coleta e o servidor.

Por exemplo, suponha que você tenha um servidor no diretório D:\serverexample\server e um projeto de teste no diretório D:\serverexample\tests. Os testes estão se comunicando com o servidor por meio da rede. Você pode iniciar a coleta de cobertura de código para o servidor da seguinte maneira:

D:\serverexample\server> dotnet-coverage collect --session-id serverdemo "dotnet run"

A ID da sessão foi especificada como serverdemo. Em seguida, você pode executar testes da seguinte maneira:

D:\serverexample\tests> dotnet test

Um arquivo de cobertura de código para sessão serverdemo pode ser gerado com a cobertura atual da seguinte maneira:

dotnet-coverage snapshot --output after_first_test.coverage serverdemo

Além disso, uma marca de instantâneo pode ser adicionada ao arquivo de cobertura usando as seguintes opções de marca:

dotnet-coverage snapshot --tag-name after_first_test --tag-identifier after_first_test serverdemo

Por fim, a sessão serverdemo e o servidor podem ser fechados da seguinte maneira:

dotnet-coverage shutdown serverdemo

Veja a seguir um exemplo de saída completa no lado do servidor:

D:\serverexample\server> dotnet-coverage collect --session-id serverdemo "dotnet run"
SessionId: serverdemo
Waiting for a connection... Connected!
Received: Hello!
Sent: HELLO!
Waiting for a connection... Code coverage results: output.coverage.
D:\serverexample\server>

Modo servidor e cliente

A coleta de cobertura de código também pode ser feita no modo servidor-cliente. Nesse cenário, um servidor de coleção de cobertura de código é iniciado e vários clientes podem se conectar com o servidor. A cobertura de código é coletada para todos os clientes coletivamente.

Inicie o servidor de cobertura de código usando o seguinte comando:

dotnet-coverage collect --session-id serverdemo --server-mode

Neste exemplo, a ID da sessão foi especificada como serverdemo para o servidor. Um cliente pode se conectar ao servidor usando essa ID de sessão usando o seguinte comando:

dotnet-coverage connect serverdemo dotnet run

Por fim, você pode fechar a sessão serverdemo e o servidor usando o seguinte comando:

dotnet-coverage shutdown serverdemo

O processo do servidor cria um relatório de cobertura de código coletivo para todos os clientes e sai.

Veja a seguir um exemplo de saída completa no lado do servidor:

D:\serverexample\server> dotnet-coverage collect --session-id serverdemo --server-mode
SessionId: serverdemo
// Server will be in idle state and wait for connect and shutdown commands
Code coverage results: output.coverage.
D:\serverexample\server>

Veja a seguir um exemplo de saída completa no lado do cliente:

D:\serverexample\server> dotnet-coverage connect serverdemo ConsoleApplication.exe World
Hello World!!
D:\serverexample\server> dotnet-coverage connect serverdemo WpfApplication.exe
D:\serverexample\server> dotnet-coverage shutdown serverdemo
D:\serverexample\server>

Você também pode iniciar o servidor e o cliente no modo de segundo plano. Outro processo começa em segundo plano e retorna o controle de volta para o usuário.

Veja a seguir um exemplo de saída completa no modo de cliente do servidor em segundo plano:

D:\serverexample\server> dotnet-coverage collect --session-id serverdemo --server-mode --background
D:\serverexample\server> dotnet-coverage connect --background serverdemo ConsoleApplication.exe World
D:\serverexample\server> dotnet-coverage connect --background serverdemo WpfApplication.exe
D:\serverexample\server> dotnet-coverage shutdown serverdemo
D:\serverexample\server>

Cobertura de código estático para assemblies gerenciados

A ferramenta dotnet-coverage pode ser usada para coletar cobertura de código para assemblies gerenciados usando instrumentação estática. Há três métodos diferentes disponíveis que você pode usar. Para demonstrar, vamos supor que temos um aplicativo de console C# simples:

D:\examples\ConsoleApp> dotnet run
Hello, World!

Use o comando collect com a opção ou configuração de inclusão de arquivos

Se você não quiser usar o comando instrument, os arquivos a serem instrumentados podem ser especificados usando a opção --include-files conforme demonstrado abaixo:

D:\examples\ConsoleApp> dotnet-coverage collect --include-files .\bin\Debug\net7.0\*.dll dotnet run
Microsoft (R) Code Coverage Command Line Tool (x64)
Copyright (c) Microsoft Corporation. All rights reserved.

SessionId: 57862ec0-e512-49a5-8b66-2804174680fc
Hello, World!
Code coverage results: output.coverage.

Você também pode especificar arquivos a serem instrumentados usando a configuração a seguir:

<ModulePaths>
  <IncludeDirectories>
    <Directory>D:\examples\ConsoleApp\bin\Debug\net7.0</Directory>
  </IncludeDirectories>
</ModulePaths>

Uso dos comandos instrument e collect

Nesse caso, o primeiro binário precisa ser instrumentado da seguinte maneira:

D:\examples\ConsoleApp> dotnet-coverage instrument .\bin\Debug\net7.0\ConsoleApp.dll
Microsoft (R) Code Coverage Command Line Tool (x64)
Copyright (c) Microsoft Corporation. All rights reserved.

Input file successfully instrumented.

Em seguida, você pode coletar a cobertura de código da seguinte maneira:

D:\examples\ConsoleApp> dotnet-coverage collect .\bin\Debug\net7.0\ConsoleApp.exe
Microsoft (R) Code Coverage Command Line Tool (x64)
Copyright (c) Microsoft Corporation. All rights reserved.

SessionId: a09e6bef-ff64-4b5f-8bb8-fc495ebb50ba
Hello, World!
Code coverage results: output.coverage.

Usar o instrumento e colete comandos no modo servidor

Nesse caso, você pode separar completamente a coleta de cobertura da execução de seu aplicativo. Primeiro, instrumente o binário da seguinte maneira:

D:\examples\ConsoleApp> dotnet-coverage instrument --session-id 73c34ce5-501c-4369-a4cb-04d31427d1a4 .\bin\Debug\net7.0\ConsoleApp.dll
Microsoft (R) Code Coverage Command Line Tool (x64)
Copyright (c) Microsoft Corporation. All rights reserved.

Input file successfully instrumented.

Observação

A ID da sessão precisa ser usada nesse cenário para garantir que o aplicativo possa se conectar e fornecer dados ao coletor externo.

Na segunda etapa, você precisa iniciar o coletor de cobertura da seguinte maneira:

D:\examples\ConsoleApp> dotnet-coverage collect --session-id 73c34ce5-501c-4369-a4cb-04d31427d1a4 --server-mode
Microsoft (R) Code Coverage Command Line Tool (x64)
Copyright (c) Microsoft Corporation. All rights reserved.

SessionId: 73c34ce5-501c-4369-a4cb-04d31427d1a4

Em seguida, o aplicativo pode ser iniciado da seguinte maneira:

D:\examples\ConsoleApp> .\bin\Debug\net7.0\ConsoleApp.exe
Hello, World!

Por fim, o coletor pode ser fechado da seguinte maneira:

D:\examples\ConsoleApp> dotnet-coverage shutdown 73c34ce5-501c-4369-a4cb-04d31427d1a4
Microsoft (R) Code Coverage Command Line Tool (x64)
Copyright (c) Microsoft Corporation. All rights reserved.

Configurações

Você pode especificar um arquivo com configurações ao usar o comando collect. O arquivo de configurações pode ser usado para excluir alguns módulos ou métodos da análise de cobertura de código. O formato é o mesmo que a configuração do coletor de dados dentro de um arquivo runsettings. Para obter mais informações, confira Personalizar a análise de cobertura de código. Aqui está um exemplo:

<?xml version="1.0" encoding="utf-8"?>
<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 run time. So keep this small and local.
        -->
        <SymbolSearchPaths>
            <Path>C:\Users\User\Documents\Visual Studio 2012\Projects\ProjectX\bin\Debug</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>
            <!-- Additional directories from .NET assemblies should be statically instrumented: -->
            <IncludeDirectories>
                <Directory Recursive="true">C:\temp</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>

        <EnableStaticManagedInstrumentation>True</EnableStaticManagedInstrumentation>
        <EnableDynamicManagedInstrumentation>True</EnableDynamicManagedInstrumentation>

    </CodeCoverage>
</Configuration>

Mesclar relatórios de cobertura

Você pode mesclar a.coverage e b.coverage e armazenar os dados em merged.coverage da seguinte maneira:

dotnet-coverage merge -o merged.coverage a.coverage b.coverage

Por exemplo, se você executar um comando como dotnet test --collect "Code Coverage", o relatório de cobertura será armazenado em uma pasta chamada GUID aleatório. Essas pastas são difíceis de localizar e mesclar. Ao usar essa ferramenta, você pode mesclar todos os relatórios de cobertura de código para todos os seus projetos da seguinte maneira:

dotnet-coverage merge -o merged.cobertura.xml -f cobertura **\*.coverage

O comando anterior mescla todos os relatórios de cobertura do diretório atual e todos os subdiretórios e armazena o resultado em um arquivo cobertura. No Azure Pipelines, você pode usar a tarefa Publicar Resultados da Cobertura de Código para publicar um relatório de cobertura mesclado.

Você pode usar o comando merge para converter um relatório de cobertura de código em outro formato. Por exemplo, o comando a seguir converte um relatório de cobertura de código binário em formato XML.

dotnet-coverage merge -o output.xml -f xml input.coverage

Confira também