Testes em C++: unit, integration, e2e do A ao Z — guia completo

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: Por que testar C++ é a base de um código confiável

\n

Desenvolver em C++ é sempre trabalhar com alta responsabilidade. A linguagem oferece controle total sobre memória e desempenho, mas o preço de um erro pode ser catastrófico: desde vazamentos de memória até a falha de todo o sistema. É por isso que testar em C++ não é uma opção, mas uma etapa obrigatória no desenvolvimento de qualquer projeto sério.

\n

Neste artigo, abordaremos três níveis principais de teste: unit (unitário), integration (integração) e e2e (ponta a ponta). Você aprenderá como eles diferem, quais ferramentas usar e como escrever testes em C++ corretamente. O material será útil tanto para iniciantes quanto para desenvolvedores experientes que desejam sistematizar seus conhecimentos.

\n\n

1. Testes unitários em C++: Testando os "blocos" do programa

\n

Testes unitários verificam a menor unidade de código — geralmente uma função ou método de classe. Seu principal objetivo: isolar o componente e garantir que ele funcione corretamente, independentemente de dependências externas.

\n\n

1.1. Ferramentas para testes unitários em C++

\n

No mercado de C++, existem vários frameworks maduros. Aqui estão os mais populares:

\n
    \n
  • Google Test (GTest) — o padrão de facto. Macros poderosas, suporte a testes parametrizados, objetos mock (via Google Mock).
  • \n
  • Catch2 — leve, moderno, com excelente sintaxe. Adequado para projetos pequenos.
  • \n
  • Boost.Test — parte da biblioteca Boost. Robusto, mas pesado.
  • \n
\n

Usaremos o Google Test como a opção mais comum.

\n\n

1.2. Exemplo de teste unitário em C++ (Google Test)

\n

Suponha que temos uma função simples para calcular o fatorial:

\n
// math_utils.h\n#pragma once\nint factorial(int n);
\n
// math_utils.cpp\n#include "math_utils.h"\nint factorial(int n) {\n    if (n < 0) return -1; // erro: número negativo\n    if (n == 0) return 1;\n    return n * factorial(n - 1);\n}
\n

Agora, escrevemos um teste unitário com o Google Test:

\n
// test_math_utils.cpp\n#include <gtest/gtest.h>\n#include "math_utils.h"\n\nTEST(FactorialTest, HandlesZeroInput) {\n    EXPECT_EQ(factorial(0), 1);\n}\n\nTEST(FactorialTest, HandlesPositiveInput) {\n    EXPECT_EQ(factorial(5), 120);\n}\n\nTEST(FactorialTest, HandlesNegativeInput) {\n    EXPECT_EQ(factorial(-1), -1);\n}\n\nint main(int argc, char **argv) {\n    ::testing::InitGoogleTest(&argc, argv);\n    return RUN_ALL_TESTS();\n}
\n

Executamos os testes — e vemos o sinal verde. Se houvesse um erro na função (por exemplo, factorial(5) retornasse 119), o teste falharia e saberíamos imediatamente do problema.

\n\n

1.3. Melhores práticas para testes unitários

\n
    \n
  • Isolamento: Use mocks para substituir dependências externas (BD, rede, sistema de arquivos).
  • \n
  • Uma verificação por teste: Cada TEST deve verificar um único comportamento.
  • \n
  • Nomes claros: HandlesZeroInput é melhor que Test1.
  • \n
  • Cobertura de casos limite: Zero, números negativos, máximos.
  • \n
\n\n

2. Testes de integração (Integration Testing): Verificando a interação

\n

Testes de integração verificam como diferentes módulos do sistema funcionam juntos. Ao contrário dos testes unitários, aqui não isolamos componentes — verificamos as conexões reais (por exemplo, a chamada de uma função de uma classe que usa outra classe).

\n\n

2.1. Quando os testes de integração são necessários?

\n