Catch2: Modern C++ Testing Framework for TDD & BDD
Reach for Catch2 if you want a dependency-free C++ test framework where test names are plain strings, assertions look like normal C++, and SECTION blocks let you share setup without fixture boilerplate. Skip it if you're stuck on C++11 or older (use the v2.x or Catch1.x branches instead), or if you need built-in mocking, which Catch2 doesn't ship.
A Test Framework That Reads Like C++
Catch2 is a C++ testing framework for unit tests, TDD, and BDD, released under the Boost Software License. The README describes it as C++-native and simple to use: test names are free-text strings rather than identifiers, assertions such as REQUIRE are written as ordinary C++ boolean expressions, and SECTION blocks provide a local way to share set-up and tear-down inside a single test. It also ships basic micro-benchmarking and simple BDD macros, and lists no external dependencies.
Why Fixture-Heavy C++ Testing Gets Old
Writing tests in C++ has historically meant fixture classes, macro-heavy registration, or dragging in a large framework. Test names get constrained to valid C++ identifiers, and sharing setup across cases pushes you into inheritance. Catch2 exists to make a unit test look close to the code it tests: a named case, a boolean assertion, and local setup you can read top to bottom.
The Move to v3: No More Single Header
Catch2 sits around 20.6k stars, and the notable recent shift is v3. Per the README, v3 drops the old single-header model and behaves like a normal library — multiple headers with a separately compiled implementation — which changes how you integrate and build it. The README notes the docs are still catching up to that change. For teams already on Catch2, the v2-to-v3 migration is the live conversation; for new projects, v3 is the current line.
TEST_CASE, SECTION, and Built-In Benchmarks
- ✓TEST_CASE and REQUIRE macros — assertions are plain C++ boolean expressions, and test names are free-text strings, not identifiers
- ✓SECTION blocks that share set-up and tear-down locally inside a test instead of forcing fixture inheritance (per the README)
- ✓Simple BDD macros for GIVEN/WHEN/THEN-style specs alongside classic unit tests
- ✓Built-in micro-benchmarking via BENCHMARK, which the README notes is opt-in behind the [!benchmark] tag and not run by default
- ✓No external dependencies, matching the project's no-dependencies topic
- ✓v3 as a proper compiled library with separate headers and implementation, rather than one giant include (README)
Writing Your First TEST_CASE
A test is a TEST_CASE with a free-text name and a tag, and you assert with REQUIRE, which reads like a normal comparison: ```cpp #include <catch2/catch_test_macros.hpp> TEST_CASE( "Factorials are computed", "[factorial]" ) { REQUIRE( factorial(1) == 1 ); REQUIRE( factorial(10) == 3'628'800 ); } ``` Micro-benchmarks use BENCHMARK inside a test case, but the README notes they don't run by default — you invoke them with the `[!benchmark]` tag. See the reference docs for the full macro set, including SECTION and the BDD macros.
Linking Against Catch2 v3
The README doesn't spell out full install commands in this excerpt — it points to the tutorial and reference docs (docs/tutorial.md, docs/Readme.md). What the README does show is the include used in code, e.g. `#include <catch2/catch_test_macros.hpp>`. Because v3 is a normally compiled library (not single-header), you build and link against Catch2 rather than dropping in one header; the README flags the v2-to-v3 migration guide (docs/migrate-v2-to-v3.md) for anyone coming from v2. For exact setup steps, follow the project's tutorial doc.
TDD, BDD, and Quick Benchmarks
- •Unit-testing C++ code in a TDD loop with readable, free-text test names
- •Writing BDD-style specs with GIVEN/WHEN/THEN when a scenario reads better than a bare assertion
- •Running quick micro-benchmarks next to your tests without a separate benchmarking tool
- •Adding a test framework to a project that wants zero external dependencies pulled in
What Makes Catch2 Pleasant to Use
- ✓Assertions read as ordinary C++ boolean expressions, and test names are plain strings — less ceremony than identifier-based frameworks
- ✓SECTION gives you local, readable setup/teardown sharing without fixture-class inheritance (per the README)
- ✓No external dependencies, so it doesn't drag extra libraries into your build
- ✓One framework covers unit tests, BDD-style specs, and basic micro-benchmarks
- ✓Permissive Boost Software License, so it's easy to drop into commercial and open-source projects alike
The v3 Migration and What's Missing
- △Requires C++14 or later; the README says C++11 support lives only on the v2.x branch and C++03 on the Catch1.x branch, so older toolchains are stuck on legacy lines
- △v3 is no longer single-header — you now compile and link against it as a library, which is more build setup than the old drop-in header
- △The README says v3 documentation is still being updated and that work is ongoing, so some reference material may lag the current code
- △Migrating an existing v2 suite to v3 is real work; the README ships a dedicated migration guide precisely because common problems come up
- △Catch2 focuses on assertions, sections, and benchmarks — it doesn't bundle a mocking framework, so you'll pair it with something like trompeloeil or FakeIt for mocks
Catch2 vs GoogleTest and doctest
Who Should Reach for Catch2
C++ developers who want tests that read like the code under test — free-text case names, natural boolean assertions, and local SECTION setup — with no external dependencies. It fits TDD and BDD workflows and projects on C++14 or newer. If you're pinned to C++11 or C++03, you're limited to the older v2.x/Catch1.x branches, and if you need mocking out of the box, GoogleTest may be the closer match.
Catch2 FAQ
Catch2 is a C++ testing framework for unit tests, TDD, and BDD. You write a TEST_CASE with a free-text name and assert with macros like REQUIRE that read as normal C++ boolean expressions. It also includes basic micro-benchmarking and simple BDD macros, with no external dependencies.
Not in v3. The README says v3 drops the single-header model and behaves like a normal library — multiple headers with a separately compiled implementation — so you build and link against it. The single-header style lives on in the older v2.x branch.
The current framework targets C++14 and later. Per the README, C++11 support is on the v2.x branch and C++03 on the Catch1.x branch, so older compilers have to use those legacy lines.
Yes. The README says Catch2 provides simple BDD macros alongside its unit-testing macros, so you can write GIVEN/WHEN/THEN-style specs when that reads better than a bare assertion.
Catch2 leans on free-text test names, natural assertions, and SECTION-based setup with no dependencies, but ships no mocking. GoogleTest bundles GoogleMock and is the more common choice when you need integrated mocking. For lighter, faster compiles with a Catch-like style, doctest is another option.
