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.
#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.
#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.
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);
}