Instruções passo a passo: criando e executando testes de unidade para código gerenciado

Essa explicação passo a passo você irá através da criação, executando, e personalizando uma série de testes de unidade que usam a unidade Microsoft testar a estrutura para código gerenciado e testar Explorer Visual Studio.Você inicia com um C# que o projeto que é desenvolvido, cria os testes que exercitam seu código, execute teste, e examine os resultados.Em seguida você pode alterar o código de projeto e executar novamente os testes.

Este tópico contém as seções a seguir:

Prepare a explicação passo a passo

Crie um projeto de teste de unidade

Crie a classe de teste

Crie o primeiro método de teste

Compilar e executar o teste

Corrigir o seu código e executar novamente seus testes

Use testes de unidade para melhorar seu código

ObservaçãoObservação

Essa explicação passo a passo usa a estrutura de testes de unidade da Microsoft para código gerenciado.O teste Explorer também pode executar um teste de estruturas de testes de unidade de terceiros que têm adaptadores para teste Explorer.Para obter mais informações, consulte Como: instalar estruturas de teste de unidade de terceiros

ObservaçãoObservação

Para obter informações sobre como executar testes de uma linha de comando, consulte Passo a passo: Usando o utilitário de teste de linha de comando.

Pré-requisitos

Prepare a explicação passo a passo

Para preparar a explicação passo a passo

  1. Abra Visual Studio 2012.

  2. No menu File, aponte para New e clique Project.

    A caixa de diálogo Novo Projeto é exibida.

  3. Em Modelos Instalados, clique em Visual C#.

  4. Na lista de tipos de aplicativos, clique Biblioteca de Classes.

  5. Na caixa de Nome , o tipo Banco e clique em OK.

    ObservaçãoObservação

    Se o banco” nome “já é usado, escolha outro nome do projeto.

    O novo banco do projeto é criado e exibido no solution Explorer com o arquivo Class1.cs de aberto no editor de códigos.

    ObservaçãoObservação

    Se o arquivo Class1.cs de não estiver aberto no editor de códigos, clique duas vezes no arquivo Class1.cs no solution Explorer para abri-lo.

  6. Copie o código-fonte de Projeto de exemplo para criação de testes de unidade.

  7. Substitua o conteúdo originais de Class1.cs com o código de Projeto de exemplo para criação de testes de unidade.

  8. Salve o arquivo como BankAccount.cs

  9. No menu Build, clique em Build Solution.

Agora você tem um Banco projeto chamado.Contém código-fonte para testar e ferramentas para testá-lo com.O namespace para o banco, BankAccountNS, contém a classe pública BankAccount, cujos métodos você testará os procedimentos a seguir.

Nesse início rápido, nós centramo-nos sobre o método de Debit . O método de débito é chamado quando dinheiro é retirado uma conta e contém o código a seguir:

// method under test
public void Debit(double amount)
{
    if(amount > m_balance)
    {
        throw new ArgumentOutOfRangeException("amount");
    }
    if (amount < 0)
    {
        throw new ArgumentOutOfRangeException("amount");
    }
    m_balance += amount;
}

Crie um projeto de teste de unidade

Pré-requisitos: Siga as etapas no procedimento, Prepare a explicação passo a passo.

Para criar um projeto de teste de unidade

  1. No menu de ArquivoAdicionar, escolha, e escolha Novo Projeto...

  2. Na caixa de diálogo O, expanda, expanda InstaladoVisual C#, e então escolha Testar.

  3. Na lista de modelos, Projeto de Teste unitárioselecione.

  4. Na caixa de Nome , entre em BankTest, e então escolha OK.

    O projeto de BankTests é adicionado à solução de Banco .

  5. No projeto de BankTests , adicione uma referência à solução de Banco .

    No solution Explorer, selecione Referências no projeto de BankTests e clique em Adicionar Referência... do menu de contexto.

  6. Na caixa de diálogo do gerenciador de referência, expanda Solução e especificando o item de Banco .

Crie a classe de teste

Nós precisamos uma classe de teste para verificar a classe de BankAccount .Podemos usar o UnitTest1.cs que foi gerado pelo modelo de projeto, mas nós devemos dar o arquivo e classificar mais nomes descritivos.Podemos fazer isso em uma etapa renomear o arquivo no solution Explorer.

Renomear um arquivo de classe

No solution Explorer, selecione o arquivo de UnitTest1.cs no projeto de BankTests.No menu de contexto, escolha Renomear, e renomear o arquivo a BankAccountTests.cs.Escolha Sim na caixa de diálogo que pergunta se você deseja renomear todas as referências no projeto para o elemento de código “UnitTest1”.Alterações desta etapa o nome da classe BankAccountTest.

O arquivo de BankAccountTests.cs agora contém o código a seguir:

// unit test code
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace BankTests
{
    [TestClass]
    public class BankAccountTests
    {
        [TestMethod]
        public void TestMethod1()
        {
        }
    }
}

Adicione uma instrução em uso ao projeto no teste

Nós podemos também adicionar uma instrução de usar a classe para chamar deixar-nos no projeto no teste sem usar nomes totalmente qualificados.Na parte superior do arquivo da classe, adicione:

using BankAccountNS

ms182532.collapse_all(pt-br,VS.110).gifTestar requisitos de classe

Os requisitos mínimos de uma classe de teste são os seguintes:

  • O atributo de [TestClass] é necessário a estrutura dos testes de unidade da Microsoft para código gerenciado para qualquer classe que contém os métodos de testes de unidade que você deseja executar no teste Explorer.

  • Cada método de teste que você deseja que o teste Explorer para executar deve ter o atributo de [TestMethod].

Você pode ter outras classes em um projeto de teste de unidade que não têm o atributo de [TestClass] , e você pode ter outros métodos nas classes de teste que não têm o atributo de [TestMethod] .Você pode usar esses outros classes e métodos em seus métodos de teste.

Crie o primeiro método de teste

Neste procedimento, nós escreveremos métodos de testes de unidade para verificar o comportamento do método de Debit da classe de BankAccount .O método é listado acima.

Ao método no teste, nós determinamos que há pelo menos três comportamentos que precisam ser verificadas:

  1. O método gera [ArgumentOutOfRangeException] se a quantidade de crédito é maior do que o saldo.

  2. Também gera ArgumentOutOfRangeException se a quantidade de crédito é menor que zero.

  3. Se fazer check-in.) 1 e 2.) são (o método, subtrai a quantidade do saldo de contas.

Em nosso primeiro teste, nós verificação que uma quantidade que válido (uma que é menor que o saldo de contas e que é maior que zero) principais a quantidade correta da conta.

Para criar um método de teste

  1. Adicione uma instrução using de BankAccountNS; para o arquivo de BankAccountTests.cs.

  2. Adicione o seguinte método à classe de BankAccountTests :

    // unit test code
    [TestMethod]
    public void Debit_WithValidAmount_UpdatesBalance()
    {
        // arrange
        double beginningBalance = 11.99;
        double debitAmount = 4.55;
        double expected = 7.44;
        BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);
    
        // act
        account.Debit(debitAmount);
    
        // assert
        double actual = account.Balance;
        Assert.AreEqual(expected, actual, 0.001, "Account not debited correctly");
    }
    

O método é um pouco simples.Nós configuramos um novo objeto de BankAccount com um saldo de início e retiramos em um valor válido.Usamos a estrutura de testes de unidade da Microsoft para o método de AreEqual de código gerenciado para verificar que o saldo final é o que nós esperamos.

ms182532.collapse_all(pt-br,VS.110).gifRequisitos de teste

Um método de teste deve atender aos seguintes requisitos:

  • O método deve ser adornado com o atributo de [TestMethod] .

  • O método deve retornar void.

  • O método não pode ter parâmetros.

Compilar e executar o teste

Para compilar e executar o teste

  1. No menu Build, escolha Build Solution.

    Se não houver nenhum erro, a janela de UnitTestExplorer aparece com Debit_WithValidAmount_UpdatesBalance listados no grupo de Não teste de execução .Se o teste Explorer não aparece depois que uma compilação com êxito, escolha Testar no menu, e então escolha Janelas, e escolha Gerenciador de Testes.

  2. Escolha Execute Todos para executar o teste.Como o teste está executando a barra de status na parte superior da janela é animada.No final do ensaio, a barra gira o verde se todos os métodos de teste passa, ou vermelho se qualquer um dos testes falhará.

  3. Nesse caso, o teste falhar.O método de teste é movido para Testes com falha.grupo.Selecione o método no teste Explorer para exibir os detalhes na parte inferior da janela.

Corrigir o seu código e executar novamente seus testes

Analisar os resultados do teste

O resultado de teste contém uma mensagem que descreve a falha.Para o método de AreEquals , mensagem você o que foram esperadas (parâmetro deExpected<XXX>() e o recebido realmente (parâmetro de Atual<YYY> ).Nós esperávamos diminuir o saldo do início o saldo, mas em vez disso gera pela quantidade de retirada.

Um reexame de código de débito mostra que o teste de unidade foi bem-sucedida em encontrar um erro.A quantidade de retirada é adicionada ao saldo de contas quando ele deve ser subtraída.

Corrija o erro

Para corrigir o erro, substituir somente a linha

m_balance += amount;

com

m_balance -= amount;

Execute novamente o teste

No teste Explorer, escolha Execute Todos para executar novamente o teste.A barra vermelha/verde gira o verde, e o teste é movido para o grupo de Testes que Passaram .

Use testes de unidade para melhorar seu código

Esta seção descreve como um processo iterativo de análise de, desenvolvimento de testes de unidade, e de refatoração pode ajudar a tornar seu código mais robusto de produção e eficiente.

Analisar os problemas

Após criar um método de teste para confirmar que uma quantidade válido é deduzida corretamente no método de Debit , é possível girar para os outros casos na análise original:

  1. O método gera ArgumentOutOfRangeException se a quantidade de crédito é maior do que o saldo.

  2. Também gera ArgumentOutOfRangeException se a quantidade de crédito é menor que zero.

Crie os métodos de teste

A primeira tentativa de criar um método de teste para resolver esses problemas prometedora aparece:

//unit test method
[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRange()
{
    // arrange
    double beginningBalance = 11.99;
    double debitAmount = -100.00;
    BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);

    // act
    account.Debit(debitAmount);

    // assert is handled by ExpectedException
}

Usamos o atributo de ExpectedExceptionAttribute para declarar a direita esteve exceção lançada.O atributo faz com que o teste falha a menos que ArgumentOutOfRangeException é lançada.Executando o teste com valores positivos e negativos e então temporariamente alteração de debitAmount do método no teste para lançar ApplicationException genérica quando a quantidade for menor que zero demonstra que o teste se comportar corretamente.Para testar os casos quando a quantidade retirada é maior do que o saldo, tudo que nós precisamos de fazer é:

  1. Crie um novo método chamado Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRangede teste.

  2. Copie o corpo do método de Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRange para o novo método.

  3. Definir debitAmount a um número maior do que o saldo.

Execute teste

Executando os dois métodos com valores diferentes para debitAmount demonstra que testa tratam adequadamente nossos os outros casos.Executando todos os três teste confirmam que todos os casos na análise original são abordados corretamente.

Continue a análise

No entanto, os dois métodos do teste também são um pouco incomodando.Nós podemos não ter certeza que condicionam no código em gera de teste quando qualquer ensaios.Alguma maneira para diferenciar as duas condições seria útil.Como nós pensamos sobre o problema mais, torna-se aparente que aprendendo condição que foi violada aumentaria a confiança de testes.Essa informação também provavelmente seria útil ao mecanismo de produção que lida com a exceção quando é acionada pelo método no teste.A geração de mais informações quando o gera do método ajudariam a qualquer interessado, mas o atributo de ExpectedException não pode fornecer essas informações.

Examinando o método no teste novamente, visto o uso das duas instruções condicionais de ArgumentOutOfRangeException um construtor que utiliza o nome do argumento como um parâmetro:

throw new ArgumentOutOfRangeException("amount");

De uma pesquisa da Biblioteca MSDN, nós descobrimos que um construtor que existe uma informações distante mais rica de relatórios.ArgumentOutOfRangeException(String, Object, String) inclui o nome do argumento, o valor do argumento, e uma mensagem definido pelo usuário.Nós podemos refatora o método no teste usar esse construtor.Mesmo melhor, podemos usar membros disponíveis publicamente de tipo para especificar os erros.

Refatorar o código no teste

Nós definimos primeiro duas constantes para as mensagens de erro no escopo de classe:

// class under test
public const string DebitAmountExceedsBalanceMessage = "Debit amount exceeds balance";
public const string DebitAmountLessThanZeroMessage = "Debit amount less than zero";

Nós alteramos nas duas instruções condicionais no método de Debit :

// method under test
// ...
    if (amount > m_balance)
    {
        throw new ArgumentOutOfRangeException("amount", amount, DebitAmountExceedsBalanceMessage);
    }

    if (amount < 0)
    {
        throw new ArgumentOutOfRangeException("amount", amount, DebitAmountLessThanZeroMessage);
    }
// ...

Refactor os métodos de teste

Em nosso método de teste, nós removemos o primeiro atributo de ExpectedException .Em seu local, nós capturamos a exceção lançada e verifique que ela está lançada na instrução correta da condição.No entanto, nós devemos agora decidir entre duas opções verificar nossas condições restantes.Por exemplo no método de Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange , podemos dar um das seguintes ações:

  • Declarar que a propriedade de ActualValue de exceção (o segundo parâmetro do construtor de ArgumentOutOfRangeException ) é maior que o saldo inicial.Esta opção requer que nós testamos a propriedade de ActualValue de exceção com a variável de beginningBalance de teste, e também requer que você então verifica que ActualValue é maior que zero.

  • Declarar que a mensagem (o terceiro parâmetro de construtor inclui DebitAmountExceedsBalanceMessage definido na classe de BankAccount .

O método de StringAssert.Contains na estrutura de testes de unidade do Microsoft habilita-nos para verificar a segunda opção sem os cálculos necessários da primeira opção.

Uma segunda tentativa para revisar Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange pode parecer como a seguir:

[TestMethod]
public void Debit_WhenAmountIsGreaterThanBalance_ShouldThrowArgumentOutOfRange()
{
    // arrange
    double beginningBalance = 11.99;
    double debitAmount = 20.0;
    BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);\

    // act
    try
    {
        account.Debit(debitAmount);
    }
    catch (ArgumentOutOfRangeException e)
    {
        // assert
        StringAssert.Contains(e.Message, BankAccount. DebitAmountExceedsBalanceMessage);
    }
}

A contraprova, reescrita, e reanalyze

Quando nós reexaminamos os métodos de teste com valores diferentes, nós encontramos os seguintes eventos:

  1. Se o erro é capturamos correto usando debitAmount que é maior do que o saldo, Contains afirma passa, a exceção é ignorada, e então passa o método de teste.Este é o comportamento que gostaríamos.

  2. Se usamos debitAmount, afirmar falha porque a mensagem de erro errada é retornada.Declarar também falhará se nós introduzimos uma exceção temporária de ArgumentOutOfRange em outro ponto no método no caminho de código de teste.Isso é muito bom.

  3. Se o valor de debitAmount é válido (ou seja, a menos que o saldo mas maior que zero, nenhuma exceção é detectada, então declarar é capturado nunca.Passa o método de teste.Isso não é aconselhável, porque desejamos o método de teste para falhar se nenhuma exceção é lançada.

O terceiro fato é um bug em nosso método de teste.Para tentar resolver o problema, adicionaremos Fail afirmamos no final do método de teste para manipular o caso em que nenhuma exceção é lançada.

Mas reexaminando mostra que o teste agora falhar se a exceção é detectada correta.A instrução catch reinicializa a exceção e o método continuar a executar, falhando no novo afirma.Para resolver o problema novo, adicionaremos uma instrução de return após StringAssert.Confirma que reexaminar nós corrigimos nossos problemas.A versão final de Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange parece com o seguinte:

[TestMethod]
public void Debit_WhenAmountIsGreaterThanBalance_ShouldThrowArgumentOutOfRange()
{
    // arrange
    double beginningBalance = 11.99;
    double debitAmount = 20.0;
    BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);\

    // act
    try
    {
        account.Debit(debitAmount);
    }
    catch (ArgumentOutOfRangeException e)
    {
        // assert
        StringAssert.Contains(e.Message, BankAccount. DebitAmountExceedsBalanceMessage);
        return;
    }
    Assert.Fail("No exception was thrown.")
}

Nesta seção final, o trabalho que foi melhoramento o nosso código de teste conduziu a métodos mais robustos e mais informativos de teste.Mas mais importante, a análise adicional também conduziu para melhorar o código em nosso projeto no teste.