Testes em C++: Unit, Integration, E2E do A ao Z

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 em C++ não é um luxo, mas uma necessidade



No mundo C++, a qualidade do código é crucial. A linguagem dá ao desenvolvedor um enorme poder sobre a memória e o desempenho, mas esse poder exige alta responsabilidade. Um erro no gerenciamento de memória, uso incorreto de ponteiros ou manipulação incorreta de multithreading pode levar a bugs difíceis de detectar que só aparecem em produção.



Testar é a única maneira confiável de garantir que seu código C++ se comporte conforme o esperado. Neste artigo, percorreremos o caminho desde pequenos testes unitários até verificações completas de ponta a ponta (E2E). Você aprenderá como estruturar adequadamente uma estratégia de teste, quais ferramentas usar e como escrever testes que realmente tragam benefícios.



Abordaremos três níveis da pirâmide de testes: unit (unitário), integration (integração) e e2e (ponta a ponta). Cada um resolve seu próprio problema, e somente a combinação deles oferece total confiança na confiabilidade do programa.



Testes unitários: A base da qualidade



Testes unitários são o nível mais baixo e mais rápido. Eles verificam funções, classes ou métodos individuais isoladamente de dependências externas (banco de dados, sistema de arquivos, rede). O objetivo principal é garantir que cada unidade lógica de código funcione corretamente.



Escolhendo um framework para C++



No ecossistema C++, existem vários frameworks populares para testes unitários:



  • Google Test (gtest) — o framework mais comum do Google. Suporta assertions, fixtures, testes parametrizados e mocks (via Google Mock).
  • Catch2 — um framework leve e moderno com excelente sintaxe. Particularmente bom para prototipagem rápida de testes.
  • Boost.Test — parte da biblioteca Boost. Poderoso, mas mais pesado.


Para o exemplo, usaremos o Google Test, pois é o padrão de facto em muitos projetos C++.



Exemplo de teste unitário em C++



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



// math_utils.h#ifndef MATH_UTILS_H#define MATH_UTILS_H

long long factorial(int n);

#endif

// math_utils.cpp#include "math_utils.h"

long long factorial(int n) { if (n < 0) throw std::invalid_argument("Negative input"); if (n == 0) return 1; long long result = 1; for (int i = 1; i <= n; ++i) { result *= i; } return result;}


Agora vamos escrever um teste unitário usando Google Test:



// test_math_utils.cpp#include <gtest/gtest.h>#include "math_utils.h"

TEST(FactorialTest, HandlesZeroInput) { EXPECT_EQ(factorial(0), 1);}

TEST(FactorialTest, HandlesPositiveInput) { EXPECT_EQ(factorial(1), 1); EXPECT_EQ(factorial(5), 120); EXPECT_EQ(factorial(10), 3628800);}

TEST(FactorialTest, ThrowsOnNegative) { EXPECT_THROW(factorial(-1), std::invalid_argument);}


Este teste verifica três cenários: caso limite (0), operação normal e tratamento de erro. Observe as macros EXPECT_EQ e EXPECT_THROW — elas não interrompem o teste em caso de erro, apenas o registram.



Objetos Mock para isolamento



Para testes unitários, é crucial isolar o código testado de dependências externas. Para isso, usamos objetos mock. O Google Mock (parte do Google Test) permite criar stubs facilmente:



// database_connector.hclass DatabaseConnector {public:    virtual ~DatabaseConnector() = default;    virtual bool connect(const std::string& url) = 0;    virtual std::vector<int> fetchData() = 0;};

// user_service.cppclass UserService { DatabaseConnector& db;public: UserService(DatabaseConnector& db) : db(db) {} int ge

Blogs

Book Recommendations