Introdução ao Live Unit Testing
Quando você habilita o Live Unit Testing em uma solução do Visual Studio, ele ilustra visualmente sua cobertura de teste e o status dos testes. O Live Unit Testing também executa testes dinamicamente sempre que você modifica seu código e notifica imediatamente quando suas alterações causam falha nos testes.
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 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 para desktop do .NET.
Criar a solução e o projeto da biblioteca de classes
Comece criando uma solução do Visual Studio chamada UtilityLibraries que consiste em um único projeto de biblioteca de classes do .NET, 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:
Selecione Arquivo>Novo>Projeto no menu de nível superior do Visual Studio.
Digite Solução na caixa de pesquisa de modelo e selecione o modelo Solução em Branco. Nomeie o projeto UtilityLibraries.
Conclua a criação da solução.
Agora que você criou a solução, criará uma biblioteca de classes chamada StringLibrary que contém vários métodos de extensão para trabalhar com cadeias de caracteres.
Em Gerenciador de Soluções, clique com o botão direito do mouse na solução UtilityLibraries e selecione Adicionar>Novo Projeto.
Digite Class Library na caixa de pesquisa de modelos e selecione o modelo Class Library que seja direcionado ao .NET ou .NET Standard. Clique em Avançar.
Nomeie o projeto StringLibrary.
Clique em Criar para criar o projeto.
Substitua todo o código existente no editor de código pelo seguinte código:
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, ele retornaráfalse
.StartsWithLower
retornarátrue
se uma cadeia de caracteres começar com um caractere minúsculo; caso contrário, ele retornaráfalse
.HasEmbeddedSpaces
retornarátrue
se uma cadeia de caracteres contiver um caractere de espaço em branco inserido; caso contrário, ele retornaráfalse
.
Selecione Compilar>Compilar Solução no menu de nível superior do Visual Studio. O build deve ser bem-sucedido.
Criar o projeto de teste
A próxima etapa é criar o projeto de teste de unidade para testar a biblioteca StringLibrary. Crie os testes de unidade executando as seguintes etapas:
Em Gerenciador de Soluções, clique com o botão direito do mouse na solução UtilityLibraries e selecione Adicionar>Novo Projeto.
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.
Nota
No Visual Studio 2019 versão 16.9, o nome do modelo de projeto MSTest é Projeto de Teste de Unidade.
Nomeie o projeto StringLibraryTests e clique em Avançar.
Escolha a estrutura de destino recomendada ou o .NET 8 e escolha Criar.
Nota
Este tutorial de introdução usa o Live Unit Testing com a estrutura de teste MSTest. Você também pode usar as estruturas de teste xUnit e NUnit.
O projeto de teste de unidade não pode acessar automaticamente a biblioteca de classes que 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 de Projeto. Na caixa de diálogo do Gerenciador de Referência, verifique se a guia da Solução está selecionada e selecione o projeto StringLibrary, conforme mostrado na ilustração a seguir.Substitua o código de teste de unidade clichê fornecido pelo modelo pelo seguinte código:
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}"); } } } }
Salve seu 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.
Escolha o botão Salvar com Outra Codificação.
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:
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ê concluiu as preliminares necessárias para usar o Live Unit Testing.
Habilitar o Teste de Unidade ao Vivo
Até agora, embora você tenha escrito os testes para a biblioteca de classes StringLibrary, você não os executou. O Live Unit Testing os executa automaticamente quando você o habilita. Para fazer isso, faça o seguinte:
Opcionalmente, selecione a janela do editor de código que contém o código para StringLibrary. Isso é Class1.cs para um projeto em C# ou Class1.vb para um projeto do Visual Basic. (Esta etapa permite inspecionar visualmente o resultado de seus testes e a extensão da cobertura de código depois de habilitar o Live Unit Testing.)
Selecione Teste>Live Unit Testing>Iniciar no menu de nível superior do Visual Studio.
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.
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. Depois, desmarque o botão Playlist para sair do modo de edição.)
O Visual Studio recriará o projeto e iniciará o Live Unit Test, que executa automaticamente todos os testes.
- O Visual Studio recriará o projeto e iniciará o Live Unit Test, que executa automaticamente todos os testes.
Quando terminar de executar seus testes, Live Unit Testing exibirá os resultados gerais e o resultado de testes individuais. Além disso, a janela do editor de código exibe graficamente a cobertura do código de teste e o resultado dos testes. Como mostra a ilustração a seguir, todos os três testes foram executados com êxito. Ele também mostra que nossos testes cobriram todos os caminhos de código no método StartsWithUpper
e todos os testes foram executados com êxito (o que é indicado pela marca de seleção verde, "✓"). Por fim, ele mostra que nenhum dos outros métodos em StringLibrary tem cobertura de código (que é indicada por uma linha azul, "➖").
Você também pode obter informações mais detalhadas sobre a cobertura de teste e os resultados do 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:
Clique na marca de verificação verde na linha em que está escrito
if (String.IsNullOrWhiteSpace(s))
no métodoStartsWithUpper
. Como mostra a ilustração a seguir, o Live Unit Testing indica que três testes abrangem essa linha de código e que todos foram executados com êxito.cobertura de código
cobertura de código
Clique na marca de seleção verde na linha onde está escrito
return Char.IsUpper(s[0])
no métodoStartsWithUpper
. Como mostra a ilustração a seguir, o Live Unit Testing indica que apenas dois testes abrangem essa linha de código e que todos foram executados com êxito.cobertura de código
Cobertura de código
O principal problema identificado pelo Live Unit Testing é a cobertura de código incompleta. Você abordará isso na próxima seção.
Expandir a cobertura do teste
Nesta seção, você estenderá seus testes de unidade para o método StartsWithLower
. Enquanto você faz isso, o Live Unit Testing continuará a testar dinamicamente seu código.
Para estender a cobertura de código para o método StartsWithLower
, faça o seguinte:
Adicione os seguintes métodos
TestStartsWithLower
eTestDoesNotStartWithLower
ao arquivo de código-fonte de 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}"); } }
Modifique o método
DirectCallWithNullOrEmpty
adicionando o código a seguir imediatamente após a chamada ao métodoMicrosoft.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}");
O Live Unit Testing executa automaticamente testes novos e modificados ao modificar 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, foram bem-sucedidos.
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
.Cobertura de código
Cobertura de código para o método StartsWithLower
Em alguns casos, testes bem-sucedidos em do Gerenciador de Testes podem estar esmaecidos. Isso indica que um teste está sendo executado no momento ou que o teste não foi executado novamente porque não houve nenhuma alteração de código que afetaria o teste desde a última execução.
Até agora, todos os nossos testes foram bem-sucedidos. Na próxima seção, examinaremos como você pode lidar com a falha de teste.
Lidar com uma falha de teste
Nesta seção, você explorará como usar o Live Unit Testing para identificar, solucionar problemas e resolver falhas de teste. Você fará isso expandindo a cobertura do teste para o método HasEmbeddedSpaces
.
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}"); } }
Quando o teste é executado, o Live Unit Testing indica que o método
TestHasEmbeddedSpaces
falhou, como mostra a ilustração a seguir: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.Passe o mouse sobre a linha com a assinatura do método
HasEmbeddedSpaces
. O Live Unit Testing exibe uma dica de ferramenta informando que o método é coberto por um teste, como mostra a ilustração a seguir: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 ilustração a seguir:
Selecione Depurar Tudo para depurar o teste com falha.
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 a passa para o métodoHasEmbeddedSpaces
. 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étodoMicrosoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue
é mostrada na ilustração a seguir.Além disso, todas as ferramentas de depuração que o Visual Studio fornece estão disponíveis para nos ajudar a solucionar problemas de nosso teste com falha, como mostra a ilustração a seguir:
Observe na janela Autos que o valor da variável
phrase
é "Name\tDescription", que é o segundo elemento da matriz. O método de teste espera queHasEmbeddedSpaces
retornetrue
quando esta cadeia de caracteres for passada para ele; em vez disso, ele retornafalse
. Evidentemente, ele não reconhece "\t", o caractere de guia, como um espaço inserido.Selecione Depurar>Continuar, pressione F5ou 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 é encerrado. Isso fornece informações suficientes para uma investigação preliminar do bug.
TestHasEmbeddedSpaces
(a rotina de teste) fez uma suposição incorreta ouHasEmbeddedSpaces
não reconhece corretamente todos os espaços inseridos.Para diagnosticar e corrigir o problema, comece com o método
StringLibrary.HasEmbeddedSpaces
. Examine a comparação no métodoHasEmbeddedSpaces
. 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 incorretamente um caractere de espaço em branco.Substitua a comparação de igualdade por uma chamada ao método System.Char.IsWhiteSpace:
if (Char.IsWhiteSpace(ch))
O Live Unit Testing reexecuta automaticamente o método de teste com falha.
O Live Unit Testing mostra os resultados atualizados, que também aparecem na janela do editor de código.