Compartilhar via


Teste de código nativo com Explorer de teste de unidade

No Visual Studio, você pode criar testes de unidade para código não gerenciado escrito em C++.O código não gerenciado as vezes é conhecido como código nativo.

O procedimento a seguir contém informações essencial que o obterá iniciado.As seções posteriores fornecem um explicação passo a passo que descreve as etapas em mais detalhes.

Para gravar testes de unidade para uma DLL de código não gerenciado

  1. Use o modelo de Teste nativo Projeto para criar um projeto separado do Visual Studio para os testes.

    O projeto contém qualquer código de exemplo.

  2. Faça o DLL acessível para o projeto de teste:

    • #include um arquivo de .h que contenha declarações das funções externo- acessíveis de DLL.

      O arquivo de .h deve conter as declarações de função marcadas com _declspec(dllimport).Como alternativa, você pode exportar os métodos usando um arquivo de DEF.Para obter mais informações, consulte Importação e exportação.

      Seus testes de unidade podem acessar somente as funções que são exportadas de DLL no teste.

    • Adicionar o projeto da DLL referências de projeto de teste:

      Em Propriedades de projeto de teste, expanda Propriedades Comuns, Estrutura e Referências, e escolha Adicionar Referência.

  3. No projeto de teste, crie classes de teste e métodos de teste usando as macros de TESTE e declarar a classe da seguinte maneira:

    #include "stdafx.h"
    #include <CppUnitTest.h>
    #include "..\MyProjectUnderTest\MyCodeUnderTest.h"
    using namespace Microsoft::VisualStudio::CppUnitTestFramework;
    TEST_CLASS(TestClassName)
    {
    public:
      TEST_METHOD(TestMethodName)
      {
        // Run a function under test here.
        Assert::AreEqual(expectedValue, actualValue, L"message", LINE_INFO());
      }
    }
    
    • Assert contém várias funções estáticas que você pode usar para verificar o resultado de um teste.

    • O parâmetro de LINE_INFO() é opcional.Em casos onde não há nenhum arquivo de PDB, permite que o corredor de teste identifica o local de uma falha.

    • Você também pode escrever métodos de configuração e de limpeza de teste.Para obter mais informações, abra a definição de macro de TEST_METHOD , e ler os comentários em CppUnitTest.h

    • Você não pode aninhar classes de teste.

  4. Use o teste Explorer para executar testes:

    1. No menu de Modo de Visualização , escolha Outras Janelas, Gerenciador de Testes.

    2. Crie a solução do Visual Studio.

    3. No teste Explorer, escolha Execute Todos.

    4. Para investigar com mais detalhes em qualquer teste teste Explorer:

      1. Selecione o nome de teste para ver mais detalhes como um rastreamento de pilha e de mensagem de falha.

      2. Abra o nome de teste (por exemplo clicando duas vezes) para ir para o local de falha ou código de teste.

      3. No menu de atalho para um teste, escolha Depurar Teste Selecionado para executar o teste no depurador.

Passo a passo: Desenvolvendo uma DLL não gerenciado com teste Explorer

Você pode adaptar essa explicação passo a passo para desenvolver seu próprio DLL.As etapas principais são:

  1. Crie um teste nativo Projeto.Os testes são criados em um projeto separado do DLL que você está desenvolvimento.

  2. Criar uma DLL Projeto.Essa explicação passo a passo cria um novo DLL, mas o procedimento para testar uma DLL existente é semelhante.

  3. Faça as funções de DLL visíveis para teste.

  4. Aumente iterativa os testes.Recomendamos um ciclo vermelho- verde “-” refactor, no desenvolvimento de código é causado pelos testes.

  5. Depuração que falha teste.Você pode executar testes no modo de depuração.

  6. Refactor para manter os testes inalteradas.Refatoração significa o melhoramento estrutura de código sem modificar seu comportamento externo.Você pode fazê-lo para melhorar o desempenho, a extensibilidade, ou a legibilidade do código.Porque a intenção não é alterar o comportamento, você não altera os testes para fazer uma alteração de refatoração o código.Os testes ajudam a certificar-se de que você não apresenta erro quando você refatoração.Você pode fazer portanto essas alterações com muito mais confiável de que se você não tem os testes.

  7. Tinta de verificação.Os testes de unidade são mais úteis quando exercitam mais do seu código.Você pode descobrir que partes do seu código foram usadas pelos testes.

  8. Unidades de isolado de recursos externos.Normalmente, uma DLL é dependente de outros componentes do sistema que você está desenvolvendo, como outros DLL, bancos de dados, ou de subsistemas remotos.É útil testar cada unidade no isolamento de suas dependências.Os componentes externos podem fazer testes executar mais lentamente.Durante o desenvolvimento, outros componentes podem não estar concluída.

Crie um projeto nativo de testes de unidade

  1. No menu de Arquivo , escolha Novo, Projeto.

    Na caixa de diálogo, expanda Instalado, Modelos, Visual C++, Testar.

    Escolha o modelo de Teste nativo Projeto .

    Neste passo-a-passo, o projeto de teste é chamado NativeRooterTest.

    Criar um projeto de teste de unidade em C++

  2. No novo projeto, inspecione unittest1.cpp

    Projeto de teste com TEST_CLASS e TEST_METHOD

    Observe que:

    • Cada teste é definido usando TEST_METHOD(YourTestName){...}.

      Você não tem que escrever uma assinatura convencional de função.A assinatura é criada pelo macro TEST_METHOD.A macro gera uma função de instância que vácuo returns.Ele também produz uma função estático que retorna informações sobre o método de teste.Essa informação permite que o gerenciador de teste localize o método.

    • Os métodos de teste são agrupados em classes usando TEST_CLASS(YourClassName){...}.

      Quando os testes são executados, uma instância de cada classe de teste é criada.Os métodos de teste são chamados em uma ordem não-especificada.Você pode definir os métodos especiais que são chamados antes e depois de cada módulo, classe, ou método.Para obter mais informações, consulte Teste de organização de C++.

  3. Verifique que a execução de teste no teste Explorer:

    1. Inserir qualquer código de teste:

      TEST_METHOD(TestMethod1)
      {
      Assert::AreEqual(1,1);
      }
      

      Observe que a classe de Assert fornece vários métodos estáticos que você pode usar para verificar resultados em métodos de teste.

    2. No menu de Testar , escolha Executar , Todos os Testes.

      As compilações e as sequências de teste.

      O teste Explorer aparece.

      O teste aparece em Testes que Passaram.

      Explorer de teste de unidade com um teste passado

Crie um projeto não gerenciado de DLL

  1. Crie um projeto de Visual C++ usando o modelo de Projeto Win32 .

    Neste passo-a-passo, o projeto é nomeado RootFinder.

    Criando um projeto C++ Win32

  2. Selecione DLL e Símbolos de exportação no assistente de aplicação Win32.

    A opção de Símbolos de exportação gera uma macro conveniente que você pode usar para declarar métodos exportados.

    Assistente de projeto do C++ para a DLL e exportar símbolos

  3. Declarar uma função exportada no arquivo principal .h:

    Novo código de projeto e. h arquivo DLL com macros de API

    O declarator __declspec(dllexport) faz com que o público e membros protegidos de classe é visível fora do DLL.Para obter mais informações, consulte Usando dllimport e dllexport em Classes C++.

  4. No arquivo principal .cpp, adicione um corpo mínimo para a função:

    // Find the square root of a number.
    double CRootFinder::SquareRoot(double v)
    {
      return 0.0;
    }
    

Acoplar o projeto de teste para o projeto de DLL

  1. Adicionar o projeto da DLL referências de projeto do projeto de teste:

    1. Abra as propriedades do projeto de teste e escolha Propriedades Comuns, Estrutura e Referências.

      Propriedades do projeto C++ - estrutura e referências

    2. Escolha Adicionar Nova Referência.

      Na caixa de diálogo Adicionar Referência , selecione o projeto de DLL e escolha Adicionar.

      Propriedades do projeto C++ - Add New Reference

  2. No arquivo chave de teste .cpp da unidade, inclua o arquivo .h de código de DLL:

    #include "..\RootFinder\RootFinder.h"
    
  3. Adicione um teste básico que usa a função exportada:

    TEST_METHOD(BasicTest)
    {
    CRootFinder rooter;
    Assert::AreEqual(
    // Expected value:
    0.0, 
    // Actual value:
    rooter.SquareRoot(0.0), 
    // Tolerance:
    0.01,
    // Message:
    L"Basic test failed",
    // Line number - used if there is no PDB file:
    LINE_INFO());
    }
    
  4. Crie a solução.

    O novo teste aparece no teste Explorer.

  5. No teste Explorer, escolha Execute Todos.

    Passado do Explorer de teste de unidade - teste básico

Você configurou o teste e projetos de código, e verificado que você possa executar testes que executam funções no projeto de código.Agora você pode começar a escrever teste e o código reais.

Aumente iterativa os testes e passar faça-os

  1. Adicione um novo teste:

    TEST_METHOD(RangeTest)
    {
      CRootFinder rooter;
      for (double v = 1e-6; v < 1e6; v = v * 3.2)
      {
        double actual = rooter.SquareRoot(v*v);
        Assert::AreEqual(v, actual, v/1000);
      }
    }
    
    DicaDica

    Recomendamos que você não altera os testes que passaram.Em vez disso, adicione um novo teste, atualizem o código para que o teste passe, e em seguida outro teste, e assim por diante.

    Quando os usuários alterem suas necessidades, desativar os testes que não estão corretos.Gravar novos e testes faça-os trabalhar um de cada vez, na mesma forma incremental.

  2. Crie a solução e em seguida, no teste Explorer, clique Execute Todos.

    O novo teste falhar.

    A falha de RangeTest

    DicaDica

    Verifique se cada teste falha imediatamente após o escreveu.Isso ajuda a evitar o erro fácil de escrever um teste que nunca falhou.

  3. Aprimorar o código no teste de modo que o novo teste passe:

    #include <math.h>
    ...
    double CRootFinder::SquareRoot(double v)
    {
      double result = v;
      double diff = v;
      while (diff > result/1000)
      {
        double oldResult = result;
        result = result - (result*result - v)/(2*result);
        diff = abs (oldResult - result);
      }
      return result;
    }
    
  4. Crie a solução e no teste Explorer, clique Execute Todos.

    Passagem de ambos os testes.

    Explorer de teste de unidade - aprovação no teste de intervalo

    DicaDica

    Desenvolva o código adicionando um teste de cada vez.Certifique-se de que todos os testes passam após cada iteração.

Depurar um teste falhando

  1. Adicione outro teste:

    #include <stdexcept>
    ...
    // Verify that negative inputs throw an exception.
    TEST_METHOD(NegativeRangeTest)
    {
      wchar_t message[200];
      CRootFinder rooter;
      for (double v = -0.1; v > -3.0; v = v - 0.5)
      {
        try 
        {
          // Should raise an exception:
          double result = rooter.SquareRoot(v);
    
          _swprintf(message, L"No exception for input %g", v);
          Assert::Fail(message, LINE_INFO());
        }
        catch (std::out_of_range ex)
        {
          continue; // Correct exception.
        }
        catch (...)
        {
          _swprintf(message, L"Incorrect exception for %g", v);
          Assert::Fail(message, LINE_INFO());
        }
      }
    }
    
  2. Crie a solução e escolha Execute Todos.

  3. Abra (ou clique duas vezes no teste) falha.

    A declaração falha é realçada.A mensagem de falha é visível no painel de detalhes de teste Explorer.

    Falha de NegativeRangeTests

  4. Para ver como o teste falhar, para percorrer a função:

    1. Definir um ponto de interrupção no início da função SquareRoot.

    2. No menu de atalho de teste falha, escolha Depurar testes selecionados.

      Quando a execução pára no ponto de interrupção, entrar com o código.

  5. Inserir o código na função que você está desenvolvendo:

    #include <stdexcept>
    ...
    double CRootFinder::SquareRoot(double v)
    {
        // Validate parameter:
        if (v < 0.0) 
        {
          throw std::out_of_range("Can't do square roots of negatives");
        }
    
  6. Todos os testes passam agora.

    Passarem todos os testes

Refatorar o código sem alterar teste

  1. Simplifica o cálculo central na função SquareRoot:

    // old code:
    //   result = result - (result*result - v)/(2*result);
    // new code:
         result = (result + v/result)/2.0;
    
  2. Crie a solução e escolha Execute Todos, para certificar-se de que você não introduziu um erro.

    DicaDica

    Um bom conjunto de testes de unidade de confiança que você não introduziu erro quando você altera o código.

    Manter refatoração a separar-se de outras alterações.

Próximas etapas

  • Isolamento. A maioria de DLL são dependentes em outros subsistemas como bancos de dados e outros DLL.Esses outros componentes desenvolvidos são geralmente paralelamente.Para permitir a unidade que testa para ser executado quando os outros componentes ainda não estiverem disponíveis, você precisa substituir a ou exemplo

  • Teste de verificação de compilação. Você pode ter os testes executados no servidor de compilação de sua equipe em intervalos definidos.Isso garante que os erros não sejam introduzidos quando o trabalho de vários membros da equipe é integrado.

  • Testes de check-in. Você pode encarregar-se de qualquer teste que são executados antes que cada membro da equipe verifica o código no controle de origem.Normalmente este é um subconjunto do conjunto completo de teste de verificação de compilação.

    Você também pode encarregar de um nível mínimo de tinta de código.

Consulte também

Tarefas

Walkthrough: Creating and Using a Dynamic Link Library (C++)

Conceitos

Importação e exportação

Outros recursos

Uma visão geral de interoperabilidade gerenciada/código não gerenciado

Depurando código nativo