Tutorial: Testar uma biblioteca de classes do .NET com o .NET usando o Visual Studio
Este tutorial mostra como automatizar o teste de unidade adicionando um projeto de teste a uma solução.
Pré-requisitos
- Este tutorial funciona com a solução que você cria em Criar uma biblioteca de classes do .NET usando o Visual Studio.
Criar um projeto de teste de unidade
Os testes de unidade oferecem testes automatizados de software durante o processo de desenvolvimento e publicação. mstest é uma das três estruturas de teste que você pode escolher. Os outros são xUnit e nUnit.
Inicie o Visual Studio.
Abra a solução
ClassLibraryProjects
que você criou no Criar uma biblioteca de classes do .NET usando o Visual Studio.Adicione um novo projeto de teste de unidade chamado "StringLibraryTest" à solução.
Clique com o botão direito do mouse na solução no Gerenciador de Soluções do e selecione Adicionar Novo Projeto>.
Na página Adicionar um novo projeto, insira mstest na caixa de pesquisa. Escolha C# ou Visual Basic na lista de idiomas e então escolha Todas as plataformas na lista de plataformas.
Escolha o modelo do Projeto de Teste MSTest e, em seguida, Avançar.
Na página Configurar seu novo projeto, insira StringLibraryTest na caixa Nome do projeto. Em seguida, escolha Avançar.
Na página Informações adicionais, selecione .NET 8 na caixa Estrutura. Em seguida, escolha Criar.
O Visual Studio cria o projeto e abre o arquivo de classe na janela de código com o código a seguir. Se o idioma que você deseja usar não for mostrado, altere o seletor de idioma na parte superior da página.
namespace StringLibraryTest; [TestClass] public class UnitTest1 { [TestMethod] public void TestMethod1() { } }
Imports Microsoft.VisualStudio.TestTools.UnitTesting Namespace StringLibraryTest <TestClass> Public Class UnitTest1 <TestMethod> Sub TestSub() End Sub End Class End Namespace
O código-fonte criado pelo modelo de teste de unidade faz o seguinte:
- Ele importa o namespace Microsoft.VisualStudio.TestTools.UnitTesting, que contém os tipos usados para teste de unidade. Em C#, o namespace é importado por meio de uma diretiva
global using
em GlobalUsings.cs. - Ele aplica o atributo TestClassAttribute à classe
UnitTest1
. - Ele aplica o atributo TestMethodAttribute para definir
TestMethod1
em C# ouTestSub
no Visual Basic.
Cada método marcado com [TestMethod] em uma classe de teste marcada com [TestClass] é executado automaticamente quando o teste de unidade é executado.
- Ele importa o namespace Microsoft.VisualStudio.TestTools.UnitTesting, que contém os tipos usados para teste de unidade. Em C#, o namespace é importado por meio de uma diretiva
Adicionar uma referência de projeto
Para que o projeto de teste funcione com a classe StringLibrary
, adicione uma referência no projeto StringLibraryTest ao projeto StringLibrary
.
No Gerenciador de Soluções, clique com o botão direito do mouse no nó Dependências do projeto StringLibraryTest e selecione Adicionar Referência do Projeto no menu de contexto.
Na caixa de diálogo Gerenciador de Referências, expanda o nó Projetos e selecione a caixa ao lado de StringLibrary. Adicionar uma referência ao assembly
StringLibrary
permite que o compilador localize os métodos de StringLibrary ao compilar o projeto StringLibraryTest.Selecione OK.
Adicionar e executar métodos de teste de unidade
Quando o Visual Studio executa um teste de unidade, ele executa cada método marcado com o atributo TestMethodAttribute em uma classe marcada com o atributo TestClassAttribute. Um método de teste termina quando a primeira falha é encontrada ou quando todos os testes contidos no método têm êxito.
Os testes mais comuns chamam membros da classe Assert. Muitos métodos de declaração incluem pelo menos dois parâmetros, um dos quais é o resultado esperado do teste e o outro é o resultado real do teste. Alguns dos métodos mais chamados da classe Assert
são mostrados na tabela a seguir:
Métodos assert | Função |
---|---|
Assert.AreEqual |
Verifica se dois valores ou objetos são iguais. A declaração falhará se os valores ou objetos não forem iguais. |
Assert.AreSame |
Verifica se duas variáveis de objeto se referem ao mesmo objeto. A declaração falhará se as variáveis se referirem a objetos diferentes. |
Assert.IsFalse |
Verifica se uma condição é false . O assert falhará se a condição for true . |
Assert.IsNotNull |
Verifica se um objeto não é null . A assert falhará se o objeto for null . |
Você também pode usar o método Assert.ThrowsException em um método de teste para indicar o tipo de exceção que ele deve gerar. O teste falhará se a exceção especificada não for gerada.
Ao testar o método StringLibrary.StartsWithUpper
, você deseja fornecer uma série de cadeias de caracteres que começam com um caractere maiúsculo. Você espera que o método retorne true
nesses casos, para que você possa chamar o método Assert.IsTrue. Da mesma forma, você deseja fornecer uma série de cadeias de caracteres que começam com algo diferente de um caractere maiúsculo. Você espera que o método retorne false
nesses casos, para que você possa chamar o método Assert.IsFalse.
Como o método de biblioteca manipula cadeias de caracteres, você também deseja verificar se ele manipula com êxito uma cadeia de caracteres vazia (String.Empty
), uma cadeia de caracteres válida que não tem caracteres e cuja Length é 0 e uma cadeia de caracteres null
que não foi inicializada. Você pode chamar StartsWithUpper
diretamente como um método estático e passar um único argumento String. Ou você pode chamar StartsWithUpper
como um método de extensão em uma variável de string
atribuída a null
.
Você definirá três métodos, cada um deles chama um método Assert para cada elemento em uma matriz de cadeia de caracteres. Você chamará uma sobrecarga de método que permite especificar uma mensagem de erro a ser exibida em caso de falha no teste. A mensagem identifica a cadeia de caracteres que causou a falha.
Para criar os métodos de teste:
Na janela de código UnitTest1.cs ou UnitTest1.vb, substitua o código pelo seguinte código:
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, string.Format("Expected for '{0}': true; Actual: {1}", word, 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, string.Format("Expected for '{0}': false; Actual: {1}", word, 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, string.Format("Expected for '{0}': false; Actual: {1}", word == null ? "<null>" : word, result)); } } } }
Imports Microsoft.VisualStudio.TestTools.UnitTesting Imports UtilityLibraries Namespace StringLibraryTest <TestClass> Public Class UnitTest1 <TestMethod> Public Sub TestStartsWithUpper() ' Tests that we expect to return true. Dim words() As String = {"Alphabet", "Zebra", "ABC", "Αθήνα", "Москва"} For Each word In words Dim result As Boolean = word.StartsWithUpper() Assert.IsTrue(result, $"Expected for '{word}': true; Actual: {result}") Next End Sub <TestMethod> Public Sub TestDoesNotStartWithUpper() ' Tests that we expect to return false. Dim words() As String = {"alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство", "1234", ".", ";", " "} For Each word In words Dim result As Boolean = word.StartsWithUpper() Assert.IsFalse(result, $"Expected for '{word}': false; Actual: {result}") Next End Sub <TestMethod> Public Sub DirectCallWithNullOrEmpty() ' Tests that we expect to return false. Dim words() As String = {String.Empty, Nothing} For Each word In words Dim result As Boolean = StringLibrary.StartsWithUpper(word) Assert.IsFalse(result, $"Expected for '{If(word Is Nothing, "<null>", word)}': false; Actual: {result}") Next End Sub End Class End Namespace
O teste de caracteres maiúsculos no método
TestStartsWithUpper
inclui a letra grega maiúscula alfa (U+0391) e a letra cirílica maiúscula EM (U+041C). O teste de caracteres minúsculos no métodoTestDoesNotStartWithUpper
inclui a letra pequena grega alfa (U+03B1) e a letra pequena cirílico Ghe (U+0433).Na barra de menu, selecione Arquivo>Salvar UnitTest1.cs Como ou Arquivo>Salvar UnitTest1.vb Como. Na caixa de diálogo Salvar Arquivo Como, selecione a seta ao lado do botão Salvar e selecione Salvar com Codificação.
Na caixa de diálogo Confirmar Salvar Como, selecione o botão Sim para salvar o arquivo.
Na caixa de diálogo Opções Avançadas de Salvamento, selecione Unicode (UTF-8 com assinatura) – página de código 65001 na lista suspensa Codificação e selecione OK.
Se você não salvar o código-fonte como um arquivo codificado em UTF8, o Visual Studio poderá salvá-lo como um arquivo ASCII. Quando isso acontece, o runtime não decodifica com precisão os caracteres UTF8 fora do intervalo ASCII e os resultados do teste não estarão corretos.
Na barra de menus, selecione Testar>Executar Todos os Testes. Se a janela do Gerenciador de Testes
não for aberta, abra-a escolhendo Test Test Explorer . Os três testes são listados na seção Testes Aprovados, e a seção Resumo relata o resultado da execução do teste.
Gerenciar falhas de teste
Se você estiver fazendo o TDD (desenvolvimento controlado por teste), escreva os testes primeiro e eles falharão na primeira vez que você executá-los. Em seguida, você adiciona código ao aplicativo que faz com que o teste seja bem-sucedido. Para este tutorial, você criou o teste depois de escrever o código do aplicativo que ele valida, para que você não tenha visto o teste falhar. Para validar se um teste falha quando você espera que ele falhe, adicione um valor inválido à entrada de teste.
Modifique a matriz
words
no métodoTestDoesNotStartWithUpper
para incluir a cadeia de caracteres "Error". Você não precisa salvar o arquivo porque o Visual Studio salva automaticamente arquivos abertos quando uma solução é criada para executar testes.string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство", "1234", ".", ";", " " };
Dim words() As String = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство", "1234", ".", ";", " " }
Execute o teste selecionando Testar>Executar Todos os Testes na barra de menus. A janela do Gerenciador de Testes
indica que dois testes foram bem-sucedidos e um falhou. Selecione o teste com falha,
TestDoesNotStartWith
.A janela Gerenciador de Testes mostra a mensagem produzida pelo assert: "Assert.IsFalse falhou. Esperado para 'Error': false, real: True". Devido à falha, nenhuma cadeia de caracteres na matriz após "Error" foi testada.
Remova a cadeia de caracteres "Erro" que você adicionou na etapa 1. Execute novamente o teste e os testes são aprovados.
Testar a versão de lançamento da biblioteca
Agora que todos os nossos testes foram aprovados ao executar a compilação de Depuração da biblioteca, execute os testes mais uma vez na compilação de Lançamento da biblioteca. Vários fatores, incluindo otimizações de compilador, podem, às vezes, produzir comportamentos diferentes entre builds de Debug e Release.
Para testar a compilação de Lançamento:
Na barra de ferramentas do Visual Studio, altere a configuração de compilação de Depurar para Lançamento.
No Gerenciador de Soluções, clique com o botão direito do mouse no projeto StringLibrary e selecione Compilar no menu de contexto para recompilar a biblioteca.
Execute os testes de unidade escolhendo Testar>Executar Todos os Testes da barra de menu. Os testes são aprovados.
Depurar testes
Se você estiver usando o Visual Studio como seu IDE, poderá usar o mesmo processo mostrado em Tutorial: Depurar um aplicativo de console do .NET usando o Visual Studio para depurar código usando seu projeto de teste de unidade. Em vez de iniciar o projeto do aplicativo ShowCase, clique com o botão direito do mouse no projeto StringLibraryTests e selecione Testes de Depuração no menu de contexto.
O Visual Studio inicia o projeto de teste com o depurador anexado. A execução será interrompida em qualquer ponto de interrupção que você adicionou ao projeto de teste ou ao código da biblioteca subjacente.
Recursos adicionais
- Noções básicas de teste da Unidade – Visual Studio
- Teste de unidade no .NET
Próximas etapas
Neste tutorial, você testou uma biblioteca de classes. Você pode disponibilizar a biblioteca para outras pessoas publicando-a no NuGet como um pacote. Para saber como, siga um tutorial do NuGet:
Se você publicar uma biblioteca como um pacote NuGet, outras pessoas poderão instalá-la e usá-la. Para saber como, siga um tutorial do NuGet:
Uma biblioteca não precisa ser distribuída como um pacote. Ele pode ser empacotado com um aplicativo de console que o usa. Para saber como publicar um aplicativo de console, consulte o tutorial anterior nesta série: