← thecodex.expert · The Codex Family of Knowledge
C++

Testing

Unlike Java’s JUnit or Python’s pytest bundled with the ecosystem, C++ ships with absolutely no testing framework at all — Google Test and Catch2 are both genuinely popular third-party choices for filling that gap.

C++20 / C++23 Google Test or Catch2 Last verified:
Canonical Definition

Google Test (often called gtest) provides TEST() macros for individual test cases, ASSERT_*/EXPECT_* macros for assertions (ASSERT stops the current test on failure, EXPECT continues to report additional failures), and test fixtures for shared setup. Catch2 takes a lighter-weight approach, using TEST_CASE and expressive REQUIRE/CHECK macros — though as of Catch2 v3 it is no longer header-only by default (it is now built as a compiled static library for faster compile times; the old single-header style survives only as an explicit, slower-to-compile "amalgamated" fallback). Both integrate with CMake for automatic test discovery and CI execution; the choice between them is largely a matter of project convention rather than one being definitively superior.

A basic test with Google Test

ASSERT_EQ stops this specific test immediately on failure; EXPECT_EQ would instead record the failure and let the rest of the test continue running, useful for seeing multiple failures from one test run.

C++calculator_test.cpp
#include <gtest/gtest.h>
#include "calculator.h"

TEST(CalculatorTest, AddsTwoNumbers) {
    Calculator calc;
    ASSERT_EQ(calc.add(2, 3), 5);
}

TEST(CalculatorTest, ThrowsOnDivideByZero) {
    Calculator calc;
    ASSERT_THROW(calc.divide(1, 0), std::invalid_argument);
}

The same test with Catch2

Catch2's syntax reads closer to natural language. Note this example uses Catch2 v3's <catch2/catch_test_macros.hpp>, which is NOT header-only — v3 is built and linked as a compiled static library (e.g. the Catch2::Catch2WithMain CMake target); only the legacy amalgamated distribution still avoids a separate build step.

C++calculator_test.cpp
#include <catch2/catch_test_macros.hpp>
#include "calculator.h"

TEST_CASE("Calculator adds two numbers", "[calculator]") {
    Calculator calc;
    REQUIRE(calc.add(2, 3) == 5);
}

Test fixtures: shared setup across tests

Deriving a test from a fixture class gives every TEST_F in that fixture a fresh instance, avoiding repeated setup code in each individual test and preventing tests from accidentally sharing state.

C++fixture_example.cpp
class CalculatorTest : public ::testing::Test {
protected:
    Calculator calc;   // fresh instance for EVERY test using this fixture
};

TEST_F(CalculatorTest, AddsTwoNumbers) {
    ASSERT_EQ(calc.add(2, 3), 5);
}

Sources

1
Google. GoogleTest User’s Guide, google.github.io/googletest, and Catch2 documentation, github.com/catchorg/Catch2.