Introdução ao Live Unit Testing

Quando você habilita o Live Unit Testing em uma solução do Visual Studio, ele representa visualmente a cobertura do teste e o status dos testes. O Live Unit Testing também executa testes dinamicamente sempre que você modifica o código e notifica imediatamente quando suas alterações causam falhas de teste.

O Live Unit Testing pode ser usado para testar soluções direcionadas ao .NET Framework, ao .NET Core ou ao .NET 5+. Neste tutorial, você aprenderá a usar o Live Unit Testing, criando uma biblioteca de classes simples direcionada ao .NET e criará um projeto do MSTest direcionado ao .NET para testá-lo.

A solução C# completa pode ser baixada do repositório MicrosoftDocs/visualstudio-docs no GitHub.

Pré-requisitos

Este tutorial exige que você instale o Visual Studio Edição Enterprise com a carga de trabalho de desenvolvimento do .NET desktop.

Criar a solução e o projeto de biblioteca de classes

Comece criando uma solução do Visual Studio chamada UtilityLibraries que consiste em apenas um projeto de biblioteca de classes do .NET, o StringLibrary.

A solução é apenas um contêiner para um ou mais projetos. Para criar uma solução em branco, abra o Visual Studio e faça o seguinte:

  1. Selecione Arquivo>Novo>Projeto no menu de nível superior do Visual Studio.

  2. Digite Solução na caixa de pesquisa de modelo e selecione o modelo Solução em Branco. Nomeie o projeto UtilityLibraries.

  3. Conclua a criação da solução.

Agora que já criou a solução, você criará uma biblioteca de classes chamada StringLibrary que contém vários métodos de extensão para trabalhar com cadeias de caracteres.

  1. Em Gerenciador de Soluções, clique com o botão direito do mouse na solução UtilityLibraries e selecione Adicionar>Novo Projeto.

  2. Digite biblioteca de classes na caixa de pesquisa de modelo e selecione o modelo Biblioteca de Classes direcionado ao .NET ou ao .NET Standard. Clique em Avançar.

  3. Nomeie o projeto StringLibrary.

  4. Clique em Criar para criar o projeto.

  5. Substitua todo o código existente no editor de código pelo seguinte:

    using System;
    
    namespace UtilityLibraries
    {
        public static class StringLibrary
        {
            public static bool StartsWithUpper(this string s)
            {
                if (String.IsNullOrWhiteSpace(s))
                    return false;
    
                return Char.IsUpper(s[0]);
            }
    
            public static bool StartsWithLower(this string s)
            {
                if (String.IsNullOrWhiteSpace(s))
                    return false;
    
                return Char.IsLower(s[0]);
            }
    
            public static bool HasEmbeddedSpaces(this string s)
            {
                foreach (var ch in s.Trim())
                {
                    if (ch == ' ')
                        return true;
                }
                return false;
            }
        }
    }
    

    StringLibrary tem três métodos estáticos:

    • StartsWithUpper retornará true se uma cadeia de caracteres começar com um caractere maiúsculo, caso contrário, retornará false.

    • StartsWithLower retornará true se uma cadeia de caracteres começar com um caractere minúsculo, caso contrário, retornará false.

    • HasEmbeddedSpaces retornará true se uma cadeia de caracteres contiver um caractere de espaço em branco inserido, caso contrário, retornará false.

  6. Selecione Compilar>Compilar Solução no menu de nível superior do Visual Studio. O build será bem-sucedido.

Criar um projeto de teste

A próxima etapa é criar o projeto de teste de unidade para testar a biblioteca StringLibrary. Crie testes de unidade, executando as seguintes etapas:

  1. Em Gerenciador de Soluções, clique com o botão direito do mouse na solução UtilityLibraries e selecione Adicionar>Novo Projeto.

  2. Digite teste de unidade na caixa de pesquisa de modelo, selecione C# como a linguagem de programação e, em seguida, selecione Projeto de Teste de Unidade do MSTest para o modelo do .NET. Clique em Avançar.

    Observação

    No Visual Studio 2019 versão 16.9, o modelo de projeto MSTest é Projeto de Teste de Unidade.

  3. Nomeie o projeto StringLibraryTests e clique em Avançar.

  4. Escolha a estrutura de destino recomendada ou o .NET 8 e escolha Criar.

    Observação

    Este tutorial de introdução usa o Live Unit Testing com o framework de teste do MSTest. Você também pode usar as estruturas de teste xUnit e NUnit.

  5. O projeto de teste de unidade não pode acessar automaticamente a biblioteca de classes que ele está testando. Forneça acesso à biblioteca de teste adicionando uma referência ao projeto de biblioteca de classes. Para fazer isso, clique com o botão direito do mouse no projeto StringLibraryTests e selecione Adicionar>Referência do Projeto. Na caixa de diálogo Gerenciador de Referências, verifique se a guia Solução está selecionada e selecione o projeto StringLibrary, conforme mostrado na ilustração a seguir.

    The Reference Manager dialog

    The Reference Manager dialog

  6. Substitua o código de teste de unidade clichê que o modelo fornece pelo código a seguir:

    using System;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using UtilityLibraries;
    
    namespace StringLibraryTest
    {
        [TestClass]
        public class UnitTest1
        {
            [TestMethod]
            public void TestStartsWithUpper()
            {
                // Tests that we expect to return true.
                string[] words = { "Alphabet", "Zebra", "ABC", "Αθήνα", "Москва" };
                foreach (var word in words)
                {
                    bool result = word.StartsWithUpper();
                    Assert.IsTrue(result,
                                  $"Expected for '{word}': true; Actual: {result}");
                }
            }
    
            [TestMethod]
            public void TestDoesNotStartWithUpper()
            {
                // Tests that we expect to return false.
                string[] words = { "alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                                   "1234", ".", ";", " " };
                foreach (var word in words)
                {
                    bool result = word.StartsWithUpper();
                    Assert.IsFalse(result,
                                   $"Expected for '{word}': false; Actual: {result}");
                }
            }
    
            [TestMethod]
            public void DirectCallWithNullOrEmpty()
            {
                // Tests that we expect to return false.
                string[] words = { String.Empty, null };
                foreach (var word in words)
                {
                    bool result = StringLibrary.StartsWithUpper(word);
                    Assert.IsFalse(result,
                                   $"Expected for '{(word == null ? "<null>" : word)}': " +
                                   $"false; Actual: {result}");
                }
            }
        }
    }
    
  7. Salve o projeto selecionando o ícone Salvar na barra de ferramentas.

    Como o código de teste de unidade inclui alguns caracteres não ASCII, você verá a caixa de diálogo a seguir para avisar que alguns caracteres serão perdidos se você salvar o arquivo no formato ASCII padrão.

  8. Escolha o botão Salvar com Outra Codificação.

    Choose a file encoding

    Choose a file encoding

  9. Na lista suspensa Codificação da caixa de diálogo Opções Avançadas de Salvamento, escolha Unicode (UTF-8 sem assinatura) – página de código 65001, como mostra a seguinte ilustração:

    Choosing the UTF-8 encoding

  10. Compile o projeto de teste de unidade selecionando Compilar>Recompilar Solução no menu de nível superior do Visual Studio.

Você criou uma biblioteca de classes e também alguns testes de unidade para ela. Agora você terminou as etapas preliminares necessárias para usar o Live Unit Testing.

Habilitar o Live Unit Testing

Até agora, embora você já tenha escrito os testes para a biblioteca de classes StringLibrary, eles ainda não foram executados. O Live Unit Testing executa-os automaticamente ao ser habilitado. Para isso, faça o seguinte:

  1. Opcionalmente, selecione a janela de código que contém o código para StringLibrary. O código é Class1.cs para um projeto C# ou Class1.vb para um projeto Visual Basic. (Esta etapa permite inspecionar visualmente o resultado dos testes e a extensão da cobertura de código depois de habilitar o Live Unit Testing.)

  2. Selecione Teste>Live Unit Testing>Iniciar no menu de nível superior do Visual Studio.

  3. Verifique a configuração do Live Unit Testing garantindo que a Raiz do Repositório inclua o caminho para os arquivos de origem para o projeto do utilitário e o projeto de teste. Selecione Avançar e, em seguida, Concluir.

  1. Na janela Live Unit Testing, selecione o link incluir todos os testes (como alternativa, selecione o ícone do botão Playlist e selecione o StringLibraryTest, que seleciona todos os testes abaixo dele. Em seguida, desmarque o botão Playlist para sair do modo de edição).

  2. O Visual Studio recompilará o projeto e iniciará o Live Unit Test, que executa automaticamente todos os testes.

  1. O Visual Studio recompilará o projeto e iniciará o Live Unit Test, que executa automaticamente todos os testes.

Quando ele termina de executar os testes, o Live Unit Testing exibe os resultados gerais e o resultado dos testes individuais. Além disso, a janela do editor de código exibe graficamente a cobertura de código de teste e o resultado dos testes. Como mostra a ilustração a seguir, os três testes foram executados com êxito. Ela também mostra que nossos testes cobriram todos os caminhos de código no método StartsWithUpper e que todos esses testes foram executados com êxito (o que é indicado pela marca de verificação verde "✓"). Finalmente, ela mostra que nenhum dos outros métodos em StringLibrary têm cobertura de código (o que é indicado por uma linha azul, "➖").

The Live Test Explorer and code editor window after starting Live Unit testing

The Live Test Explorer and code editor window after starting Live Unit testing

Você também pode obter informações mais detalhadas sobre a cobertura do teste e os resultados de teste selecionando um ícone de cobertura de código específico na janela do editor de código. Para examinar este detalhe, faça o seguinte:

  1. Clique na marca de verificação verde na linha em que está escrito if (String.IsNullOrWhiteSpace(s)) no método StartsWithUpper. Como mostra a ilustração a seguir, o Live Unit Testing indica que três testes cobrem essa linha de código e que todos foram executados com êxito.

    Code coverage for the if conditional statement

    Code coverage for the if conditional statement

  2. Clique na marca de verificação verde na linha em que está escrito return Char.IsUpper(s[0]) no método StartsWithUpper. Como mostra a ilustração a seguir, o Live Unit Testing indica que apenas dois testes cobrem essa linha de código e que todos foram executados com êxito.

    Code coverage for the return statement

    Code coverage for the return statement

A questão mais importante que o Live Unit Testing identifica é uma cobertura de código incompleta. Isso será abordado na próxima seção.

Expandir a cobertura do teste

Nesta seção, você estenderá os testes de unidade para o método StartsWithLower. Enquanto você estiver fazendo isso, o Live Unit Testing continuará a testar o código dinamicamente.

Para estender a cobertura de código para o método StartsWithLower, faça o seguinte:

  1. Adicione os seguintes métodos TestStartsWithLower e TestDoesNotStartWithLower no arquivo de código-fonte do teste do projeto:

    // Code to add to UnitTest1.cs
    [TestMethod]
    public void TestStartsWithLower()
    {
        // Tests that we expect to return true.
        string[] words = { "alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство" };
        foreach (var word in words)
        {
            bool result = word.StartsWithLower();
            Assert.IsTrue(result,
                          $"Expected for '{word}': true; Actual: {result}");
        }
    }
    
    [TestMethod]
    public void TestDoesNotStartWithLower()
    {
        // Tests that we expect to return false.
        string[] words = { "Alphabet", "Zebra", "ABC", "Αθήνα", "Москва",
                           "1234", ".", ";", " "};
        foreach (var word in words)
        {
            bool result = word.StartsWithLower();
            Assert.IsFalse(result,
                           $"Expected for '{word}': false; Actual: {result}");
        }
    }
    
  2. Modifique o método DirectCallWithNullOrEmpty adicionando o seguinte código imediatamente após a chamada de método Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsFalse.

    // Code to add to UnitTest1.cs
    result = StringLibrary.StartsWithLower(word);
    Assert.IsFalse(result,
                   $"Expected for '{(word == null ? "<null>" : word)}': " +
                   $"false; Actual: {result}");
    
  3. O Live Unit Testing executa automaticamente os testes novos e modificados quando você modifica o código-fonte. Como mostra a ilustração a seguir, todos os testes, incluindo os dois que você adicionou e o que você modificou, tiveram êxito.

    The Live Test Explorer after expanding test coverage

    The Live Test Explorer after expanding test coverage

  4. Alterne para a janela que contém o código-fonte da classe StringLibrary. Agora, o Live Unit Testing mostra que a cobertura de código foi estendida para o método StartsWithLower.

    Code coverage for the StartsWithLower method

    Code coverage for the StartsWithLower method

Em alguns casos, os testes bem-sucedidos no Gerenciador de Testes podem ficar esmaecidos. Isso indica que um teste está em execução no momento ou que o teste não foi executado novamente porque não houve nenhuma alteração no código que pudesse afetá-lo desde sua última execução.

Até agora, todos os nossos testes tiveram êxito. Na próxima seção, vamos examinar como você pode tratar uma falha de teste.

Lidar com uma falha de teste

Nesta seção, você vai explorar como é possível usar o Live Unit Testing para identificar, corrigir e solucionar problemas de falhas de teste. Você fará isso expandindo a cobertura do teste para o método HasEmbeddedSpaces.

  1. Adicione o seguinte método ao arquivo de teste:

    [TestMethod]
    public void TestHasEmbeddedSpaces()
    {
        // Tests that we expect to return true.
        string[] phrases = { "one car", "Name\u0009Description",
                             "Line1\nLine2", "Line3\u000ALine4",
                             "Line5\u000BLine6", "Line7\u000CLine8",
                             "Line0009\u000DLine10", "word1\u00A0word2" };
        foreach (var phrase in phrases)
        {
            bool result = phrase.HasEmbeddedSpaces();
            Assert.IsTrue(result,
                          $"Expected for '{phrase}': true; Actual: {result}");
        }
    }
    
  2. Quando o teste for executado, o Live Unit Testing indicará que o método TestHasEmbeddedSpaces falhou, como mostra a seguinte ilustração:

    The Live Test Explorer reporting a failed test

    The Live Test Explorer reporting a failed test

  3. Selecione a janela que exibe o código da biblioteca. O Live Unit Testing expandiu cobertura de código para o método HasEmbeddedSpaces. Ele também relata uma falha de teste adicionando um "🞩" vermelho nas linhas cobertas por testes com falha.

  4. Passe o mouse sobre a linha com a assinatura do método HasEmbeddedSpaces. O Live Unit Testing exibe uma dica de ferramenta que relata que o método está coberto por um teste, como mostra a seguinte ilustração:

    Live Unit Testing information on a failed test

    Live Unit Testing information on a failed test

  5. Selecione o teste TestHasEmbeddedSpaces. O Live Unit Testing oferece algumas opções, como executar todos os testes e depurar todos os testes, como mostra a seguinte ilustração:

    Live Unit Testing options for a failed test

    Live Unit Testing options for a failed test

  6. Selecione Depurar Tudo para depurar o teste com falha.

  7. O Visual Studio executa o teste no modo de depuração.

    O teste atribui cada cadeia de caracteres em uma matriz a uma variável chamada phrase e passa-a ao método HasEmbeddedSpaces. A execução do programa fica em pausa e invoca o depurador na primeira vez em que a expressão assert é false. A caixa de diálogo de exceção que resulta do valor inesperado na chamada de método Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue é mostrada na ilustração a seguir.

    Live Unit Testing exception dialog

    Live Unit Testing exception dialog

    Além disso, todas as ferramentas de depuração que o Visual Studio fornece estão disponíveis para ajudar a solucionar problemas de testes com falha, como mostra a seguinte ilustração:

    Visual Studio debugging tools

    Visual Studio debugging tools

    Observe que na janela Autos o valor da variável phrase é "Name\tDescription", que é o segundo elemento da matriz. O método de teste espera que HasEmbeddedSpaces retorne true ao receber essa cadeia de caracteres, mas ele retorna false. Evidentemente, ele não reconhece "\t", o caractere de tabulação, como um espaço inserido.

  8. Selecione Depurar>Continuar, pressione F5 ou clique no botão Continuar na barra de ferramentas para continuar executando o programa de teste. Como ocorreu uma exceção sem tratamento, o teste foi encerrado. Isso fornece informações suficientes para uma investigação preliminar do bug. Ou TestHasEmbeddedSpaces (a rotina de teste) fez uma suposição incorreta ou HasEmbeddedSpaces não reconhece corretamente todos os espaços inseridos.

  9. Para diagnosticar e corrigir o problema, comece com o método StringLibrary.HasEmbeddedSpaces. Examine a comparação no método HasEmbeddedSpaces. Ele considera um espaço inserido como U+0020. No entanto, o padrão Unicode inclui vários outros caracteres de espaço. Isso sugere que o código da biblioteca testou um caractere de espaço em branco incorretamente.

  10. Substitua a comparação de igualdade por uma chamada para o método System.Char.IsWhiteSpace:

    if (Char.IsWhiteSpace(ch))
    
  11. O Live Unit Testing reexecuta automaticamente o método de teste com falha.

    O Live Unit Testing mostra os resultados atualizados exibidos, que também aparecem na janela do editor de código.