Introdução ao teste de unidade ao vivo
Quando você habilita o teste de unidade ao vivo em uma solução do Visual Studio, ele mostra visualmente sua cobertura de teste e o status de seus testes. O Teste de Unidade em Tempo Real também executa testes dinamicamente sempre que você modifica seu código e o notifica imediatamente quando as alterações causam falhas nos testes.
O Teste de Unidade em Tempo Real pode ser usado para testar soluções destinadas ao .NET Framework, .NET Core ou .NET 5+. Neste tutorial, você aprenderá a usar o Teste de Unidade ao Vivo criando uma biblioteca de classes simples destinada ao .NET e criará um projeto MSTest direcionado ao .NET para testá-lo.
A solução C# completa pode ser baixada do repositório
Pré-requisitos
Este tutorial requer que você tenha instalado o Visual Studio Enterprise Edition com o o desenvolvimento da área de trabalho .NET a carga de trabalho.
Criar a solução e o projeto de biblioteca de classes
Comece criando uma solução do Visual Studio chamada UtilityLibraries que consiste em um único projeto de biblioteca de classe .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, em seguida, selecione o modelo Solução em Branco. Nomeie o projeto UtilityLibraries.
Termine de criar a solução.
Agora que você 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.
No Gerenciador de Soluções , clique com o botão direito do mouse na solução UtilityLibraries e selecione Adicionar>Novo Projeto.
Digite biblioteca de classes na caixa de pesquisa de modelo e depois escolha o modelo Biblioteca de Classes que tem como alvo o .NET ou o .NET Standard. Clique 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
retornatrue
se uma cadeia de caracteres começar com um caractere maiúsculo; caso contrário, ele retornaráfalse
.StartsWithLower
retornatrue
se uma cadeia de caracteres começar com um caractere minúsculo; caso contrário, ele retornaráfalse
.HasEmbeddedSpaces
retornatrue
se uma cadeia de caracteres contiver um caractere de espaço em branco incorporado; caso contrário, ele retornaráfalse
.
Selecione Build>Build Solution no menu de nível superior do Visual Studio. A construção deve ter sucesso.
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:
No 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 o idioma e, em seguida, selecione o modelo Projeto de Teste de Unidade MSTest para .NET. Clique Avançar.
Observação
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-alvo recomendada ou .NET 8 e, em seguida, selecione Criar.
Observação
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. Você dá 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ências, verifique se a guia Solution 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 seguinte caixa de diálogo para avisar que alguns caracteres serão perdidos se você salvar o arquivo em seu formato ASCII padrão.
Escolha o botão Guardar com Outro tipo de Codificação.
Na lista pendente Codificação da caixa de diálogo Opções de Salvamento Avançado, escolha Unicode (UTF-8 sem assinatura) - Pág. de códigos 65001, como mostra a ilustração a seguir:
de codificação UTF-8
Compile o projeto de teste de unidade selecionando Build>Rebuild Solution no menu de nível superior do Visual Studio.
Você criou uma biblioteca de classes, assim como alguns testes de unidade para ela. Agora você concluiu as preliminares necessárias para usar o Teste de Unidade ao Vivo.
Ativar 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 executa-os automaticamente assim que o ativa. 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 C# ou Class1.vb para um projeto Visual Basic. (Esta etapa permite que você inspecione visualmente o resultado de seus testes e a extensão da cobertura de seu código depois de habilitar o Teste de Unidade em Tempo Real.)
Selecione Test>Live Unit Testing>Start no menu de nível superior do Visual Studio.
Verifique a configuração do Teste de Unidade em Tempo Real garantindo que a Raiz do Repositório inclua o caminho para os arquivos de origem do projeto do utilitário e do 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, depois selecione o StringLibraryTest, que seleciona todos os testes abaixo. Em seguida, desmarque o botão Playlist para sair do modo de edição.)
O Visual Studio reconstruirá o projeto e iniciará o Live Unit Test, que executa automaticamente todos os seus testes.
- O Visual Studio reconstruirá o projeto e iniciará o Live Unit Test, que executa automaticamente todos os seus testes.
Quando terminar de executar os seus testes, o Teste de Unidade ao Vivo exibirá tanto os resultados gerais como 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 esses testes foram executados com êxito (o que é indicado pela marca de seleção verde, "✓"). Finalmente, ele mostra que nenhum dos outros métodos em StringLibrary tem cobertura de código (que é indicado por uma linha azul, "➖").
Você também pode obter informações mais detalhadas sobre a cobertura do 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 esse detalhe, faça o seguinte:
Clique na marca de seleção verde na linha que diz
if (String.IsNullOrWhiteSpace(s))
no métodoStartsWithUpper
. Como mostra a ilustração a seguir, o Teste de Unidade em Tempo Real indica que três testes cobrem essa linha de código e que todos foram executados com êxito.Clique na marca de seleção verde na linha que indica
return Char.IsUpper(s[0])
no métodoStartsWithUpper
. Como mostra a ilustração a seguir, o Teste de Unidade em Tempo Real indica que apenas dois testes cobrem essa linha de código e que todos foram executados com êxito.
O principal problema que o Live Unit Testing identifica é a cobertura incompleta do código. 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 seu 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 seguinte código 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 quando você modifica seu 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. O Teste de Unidade ao Vivo agora mostra que a nossa cobertura de código foi estendida para o método
StartsWithLower
.
Em alguns casos, os testes bem-sucedidos em do Gerenciador de Testes podem estar acinzentados. Isso indica que um teste está em execução no momento ou que o teste não foi executado novamente porque não houve alterações de código que afetariam o teste desde que ele foi executado pela última vez.
Até agora, todos os nossos testes foram bem-sucedidos. Na próxima seção, examinaremos como você pode lidar com falhas de teste.
Lidar com uma falha de teste
Nesta seção, você explorará como pode usar o Teste de Unidade em Tempo Real 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 seu 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 teste de unidade ao vivo indica que o método
TestHasEmbeddedSpaces
falhou, como mostra a ilustração a seguir:Selecione a janela que exibe o código da biblioteca. Live Unit Testing expandiu a cobertura de código para o método
HasEmbeddedSpaces
. Ele também comunica a falha do teste ao adicionar um '🞩' vermelho às linhas cobertas por testes com falha.Passe o cursor sobre a linha com a assinatura do método
HasEmbeddedSpaces
. O Teste de Unidade em Tempo Real exibe uma dica de ferramenta que informa que o método é coberto por um teste, como mostra a ilustração a seguir:Selecione o teste de TestHasEmbeddedSpaces com falha
. O teste de unidade ao vivo 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 falhado.
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 pausa e invoca o depurador na primeira vez que a expressão assert éfalse
. A caixa de diálogo de exceção que resulta do valor inesperado na chamada do 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 é "Name\tDescription", que é o segundo elemento da matriz. O método de teste espera que HasEmbeddedSpaces
retornetrue
quando for passada essa cadeia de caracteres; em vez disso, ele retornafalse
. Evidentemente, ele não reconhece "\t", o caractere de tabulação, como um espaço incorporado.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 não tratada, o teste é encerrado. Isso fornece informações suficientes para uma investigação preliminar do bug. Ou
TestHasEmbeddedSpaces
(a rotina de teste) fez uma suposição incorreta, ouHasEmbeddedSpaces
não reconhece corretamente todos os espaços incorporados.Para diagnosticar e corrigir o problema, comece com o método
StringLibrary.HasEmbeddedSpaces
. Veja a comparação no métodoHasEmbeddedSpaces
. Considera um espaço incorporado 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 foi testado incorretamente para um caractere de espaço em branco.Substitua a comparação de igualdade por uma chamada para o método System.Char.IsWhiteSpace:
if (Char.IsWhiteSpace(ch))
O Teste em Tempo Real de Unidades executa automaticamente o método de teste reprovado.
O Teste de Unidade ao Vivo mostra que os resultados atualizados aparecem, e estes são exibidos na janela do editor de código.