Compartilhar via


Passo a passo: desenvolvimento controlado por teste usando o Gerenciador de Testes

Crie testes de unidade para ajudar a manter seu código funcionando corretamente por meio de alterações de código incrementais. Há várias estruturas que você pode usar para gravar testes de unidade, incluindo algumas desenvolvidas por terceiros. Algumas estruturas de teste são especializadas em testes em diferentes linguagens ou plataformas. O Gerenciador de Testes fornece uma única interface para testes de unidade em qualquer uma dessas estruturas. Para obter mais informações sobre o Explorador de Testes, consulte Executar testes de unidade com o Explorador de Testes e FAQ do Explorador de Testes.

Este passo a passo demonstra como desenvolver um método testado em C# usando o MSTest (Microsoft Test Framework). Você pode adaptá-lo facilmente para outras linguagens ou outras estruturas de teste, como o NUnit. Para saber mais, confira Instalar estruturas de teste de unidade de terceiros.

Criar um teste e gerar código

  1. Crie um projeto da Biblioteca de Classes em C# para .NET ou .NET Standard. Este projeto conterá o código que desejamos testar. Nomeie o projeto MyMath.

  2. Na mesma solução, adicione um novo projeto de teste mstest para .NET.

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

    Nomeie o projeto de teste MathTests.

    Novos projetos de código e teste

    Novos projetos de código e teste

  3. No projeto de teste, escreva um método de teste simples que verifica o resultado obtido para uma entrada específica. Adicione o seguinte código à classe Test1 ou UnitTest1:

    [TestMethod]
    public void BasicRooterTest()
    {
      // Create an instance to test:
      Rooter rooter = new Rooter();
      // Define a test input and output value:
      double expectedResult = 2.0;
      double input = expectedResult * expectedResult;
      // Run the method under test:
      double actualResult = rooter.SquareRoot(input);
      // Verify the result:
      Assert.AreEqual(expectedResult, actualResult, delta: expectedResult / 100);
    }
    
  4. Gere um tipo a partir do código de teste.

    1. Coloque o cursor ligado Rootere, em seguida, abra o menu de lâmpada.

      Escolha Gerar novo tipo.

      Gerar ação rápida de novo tipo

      Escolha Gerar tipo 'Rooter'>. Gere um novo tipo.

      Gerar ação rápida de novo tipo

    2. Na caixa de diálogo Gerar Tipo , defina Project como MyMath, o projeto da biblioteca de classes e escolha OK.

      Caixa de diálogo Gerar Tipo no Visual Studio 2019

      Caixa de diálogo Gerar Tipo no Visual Studio 2019

  5. Gere um método a partir do código de teste. Coloque o cursor ativado SquareRoote, no menu de lâmpada, escolha Gerar método 'SquareRoot' ou Gerar método 'Rooter.SquareRoot'.

  6. Execute o teste de unidade.

    1. Abra o Gerenciador de Testes.

      Para abrir o Gerenciador de Testes no menu Teste , escolha o Gerenciador de Testes.

      Para abrir o Gerenciador de Testes no menu Teste, escolha o Gerenciadorde> Windows.

    2. No Gerenciador de Testes, escolha o botão Executar Tudo para executar o teste.

    A solução é compilada e o teste é executado e falha.

  7. Selecione o nome do teste.

    Os detalhes do teste são exibidos no painel Resumo de Detalhes do Teste .

    Resumo dos detalhes do teste no Gerenciador de Testes

    Resumo dos detalhes do teste no Gerenciador de Testes

  8. Selecione o link superior em Rastreamento de Pilha para ir para o local em que o teste falhou.

Neste ponto, você criou um teste e um stub que você pode modificar para que o teste seja aprovado.

Verificar uma alteração de código

  1. No arquivo Class1.cs , melhore o código de SquareRoot:

    public double SquareRoot(double input)
    {
        return input / 2;
    }
    
  2. No Gerenciador de Testes, escolha Executar Tudo.

    A solução é compilada e o teste é executado e aprovado.

    Gerenciador de Testes mostrando um teste de aprovação

    Gerenciador de Testes mostrando um teste de aprovação

Ampliar o escopo de entradas

Para melhorar nossa confiança de que o código funciona em todos os casos, adicione testes que tentem uma gama mais ampla de valores de entrada.

Dica

Evite alterar testes existentes que já passaram. Em vez disso, adicione novos testes. Altere os testes existentes somente quando os requisitos do usuário forem alterados. Essa política ajuda a garantir que você não perca a funcionalidade existente enquanto trabalha para estender o código.

  1. Na classe de teste, adicione o seguinte teste, que tenta um intervalo de valores de entrada:

    [TestMethod]
    public void RooterValueRange()
    {
        // Create an instance to test.
        Rooter rooter = new Rooter();
    
        // Try a range of values.
        for (double expected = 1e-8; expected < 1e+8; expected *= 3.2)
        {
            RooterOneValue(rooter, expected);
        }
    }
    
    private void RooterOneValue(Rooter rooter, double expectedResult)
    {
        double input = expectedResult * expectedResult;
        double actualResult = rooter.SquareRoot(input);
        Assert.AreEqual(expectedResult, actualResult, delta: expectedResult / 1000);
    }
    
  2. No Gerenciador de Testes, escolha Executar Tudo.

    O novo teste falha (embora o primeiro teste ainda seja aprovado). Para encontrar o ponto de falha, selecione o teste com falha e examine os detalhes no painel Resumo de Detalhes do Teste .

  3. Inspecione o método em teste para ver o que pode estar errado. Altere o código SquareRoot da seguinte maneira:

    public double SquareRoot(double input)
    {
      double result = input;
      double previousResult = -input;
      while (Math.Abs(previousResult - result) > result / 1000)
      {
        previousResult = result;
        result = result - (result * result - input) / (2 * result);
      }
      return result;
    }
    
  4. No Gerenciador de Testes, escolha Executar Tudo.

    Os dois testes agora passam.

Adicionar testes para casos excepcionais

  1. Adicione um novo teste para entradas negativas:

    [TestMethod]
    public void RooterTestNegativeInput()
    {
        Rooter rooter = new Rooter();
        Assert.ThrowsException<ArgumentOutOfRangeException>(() => rooter.SquareRoot(-1));
    }
    
  2. No Gerenciador de Testes, escolha Executar Tudo.

    O novo teste falha.

    Se o método estiver em loops de teste, escolha Cancelar na barra de ferramentas do Gerenciador de Testes. O teste interrompe a execução e falha.

  3. Corrija o SquareRoot código adicionando a seguinte if instrução no início do método:

    public double SquareRoot(double input)
    {
        if (input <= 0.0)
        {
            throw new ArgumentOutOfRangeException();
        }
        ...
    
  4. No Gerenciador de Testes, escolha Executar Tudo.

    Todos os testes são aprovados.

Refatorar o código em teste

Refatore o código, mas não altere os testes.

Dica

Uma refatoração é uma alteração que se destina a fazer com que o código tenha um desempenho melhor ou mais fácil de entender. Não se destina a alterar o comportamento do código e, portanto, os testes não são alterados.

Recomendamos que você execute as etapas de refatoração separadamente das etapas que estendem a funcionalidade. Manter os testes inalterados lhe dá confiança de que você não introduziu bugs acidentalmente durante a refatoração.

  1. Altere a linha que calcula result no método SquareRoot da seguinte maneira:

    public double SquareRoot(double input)
    {
        if (input <= 0.0)
        {
            throw new ArgumentOutOfRangeException();
        }
    
        double result = input;
        double previousResult = -input;
        while (Math.Abs(previousResult - result) > result / 1000)
        {
            previousResult = result;
            result = (result + input / result) / 2;
            //was: result = result - (result * result - input) / (2*result);
        }
        return result;
    }
    
  2. Escolha Executar Tudo e verifique se todos os testes continuam a passar.

    Gerenciador de Testes mostrando três testes aprovados

    Gerenciador de Testes mostrando três testes aprovados