1. Project Overview
1.1 basic information
| Dimension | Information |
|---|---|
| Project name | Catch2 |
| Organization/Author | catchorg / Phil Nash (original author), Martin Hořeňovský (current maintainer) |
| GitHub | https://github.com/catchorg/Catch2 |
| Open Source Protocol | BSL(Boost Software License 1.0)-Business Friendly, Allow Unlimited Use |
| Main language | C (requires C 14 and above) |
| Star Number | 21,600**(2026-07 Query) |
| Cumulative Submissions | 4,769 Commits |
| Release | 50 versions (including v1.x series, the latest stable version v3.15.1) |
| Contributors | 300 |
| Created | 2010 (Catch 1.x);Catch2 v2 in 2017; Catch2 v3 in 2022 |
| Last Updated | 2026-07-15 (Continuously Active Development) |
| official website | https://github.com/catchorg/Catch2 |
1.2 Project Positioning
Catch2 is a modern C unit testing framework that covers three test paradigms: unit testing, TDD (test-driven development), and BDD (behavior-driven development), with built-in micro-benchmarking capabilities. Its design philosophy is "make writing tests as simple as writing natural language"-developers only need to master the two core assertion macros of' REQUIRE' and' CHECK' to start working. the framework automatically decomposes assertion expressions through c expression template technology, and outputs clear expected values and actual values when it fails.
Catch2 is positioned as a developer experience-first testing framework , emphasizing:
-Very low start-up threshold: Download two files to integrate, zero external dependencies
-The test code itself is a document: the test case is named as a free-format string, and tags management is supported.
-Compile to Library Mode to Improve Performance:v3 version no longer encourages the use of header-only, but changes to CMake static library integration to greatly improve the compilation speed of large-scale projects.
-Modern C syntax: takes full advantage of C 14/17 features, does not support legacy compilers
1.3 development process
| Phase | Time | Key Event |
|---|---|---|
| Initial Stage | 2010 | Phil Nash Created Catch 1.x (formerly Catch) to attract community attention with single-headed files and innovative "natural expression decomposition" mechanisms |
| Catch2 v2 | 2017 | Catch2 v2 was released, renamed Catch2, adopted the 'catch2/'namespace, and introduced new features such as Matcher and Benchmark |
| Maintenance Handover | 2020 | Phil Nash hands over maintenance to Martin Hořeňovský(horenmar) |
| Catch2 v3 | June 2022 | Catch2 v3 was officially released, changing from Header-only mode to CMake static library mode, greatly improving compilation performance; Remove C 11 support and require C 14 |
| Continuous Evolution | 2022-2026 | Release a functional version (v3.1 → v3.15) every 1-2 months, continuously adding thread safety assertions, event listeners, Constexpr Matcher, multi-Reporter parallel output, etc. |
2. Core Competence
2.1 Natural Expression Assertion System (Natural Expression Decomposition)
Catch2's most iconic innovation. Whereas traditional testing frameworks require a large number of specialized assertion macros (ASSERT_EQ, ASSERT_NE, ASSERT_LT, ASSERT_GT, ASSERT_TRUE, etc.), Catch2 covers almost all scenarios with just two core macros:
REQUIRE( Factorial(3) == 6 ); // 致命断言,失败则终止当前测试
CHECK( Fib(10) == 55 ); // 非致命断言,失败后继续执行
- Key Mechanism :Catch2 "decomposes" the expression 'a = = B 'at compile time through C operator overloading and expression templates, so that when the test fails, it can automatically output * the actual values of the left and right operands:
Example.cpp:9: FAILED:
REQUIRE( Factorial(0) == 1 )
with expansion:
0 == 1
Assertion Macro Family Bucket:
| Macro Category | Fatal (Terminate Test) | Non-Fatal (Continue Execution) | Purpose | |
|---|---|---|---|---|
| basic assertion | 'REQUIRE' | 'CHECK' | arbitrary boolean expression comparison | |
| Boolean Inverse | 'REQUIRE_FALSE' | 'CHECK_FALSE' | Assertion expression results in false | |
| do not throw exception | 'REQUIRE_NOTHROW' | 'CHECK_NOTHROW' | assertion expression does not throw exception | |
| throw any exception | 'REQUIRE_THROWS' | 'CHECK_THROWS' | assertion expression throws exception | |
| Throw specified type | 'REQUIRE_THROWS_AS' | 'CHECK_THROWS_AS' | Assertion throws a specific type exception | |
| Exception Message Match | 'REQUIRE_THROWS_WITH' | 'CHECK_THROWS_WITH' | Assertion Exception Message Match String/Matcher | |
| Exception matches all | 'REQUIRE_THROWS_MATCHES' | 'CHECK_THROWS_MATCHES' | Assertion exception types Matcher match at the same time | |
| Floating-point comparison | 'REQUIRE(x = = Approx(y))' | 'CHECK' | Use 'Catch::Approx' to customize the tolerance |
2.2 Test Case and Section Mechanism (Replacing Traditional Fixture)
Catch2 provides a unique Section mechanism to replace the SetUp/TearDown Fixture mode of the traditional xUnit framework:
TEST_CASE("vectors can be sized and resized", "[vector]") {
std::vector v(5); // setup 代码
REQUIRE(v.size() == 5);
REQUIRE(v.capacity() >= 5);
SECTION("resizing bigger changes size and capacity") {
v.resize(10);
REQUIRE(v.size() == 10);
REQUIRE(v.capacity() >= 10);
}
SECTION("resizing smaller changes size but not capacity") {
v.resize(0);
REQUIRE(v.size() == 0);
REQUIRE(v.capacity() >= 5);
}
// ...更多 SECTION
}
Section core features:
-When every'SECTION' is triggered, the TEST_CASE is executed from the beginning, and the context entered by each section is a newly constructed object
-Section can be nested arbitrarily to form a test path tree, which is executed in a depth-first manner.
-Completely eliminates the state leakage problem in the traditional 'SetUp()'/'TearDown()'
-The traditional Test Fixture (TEST_CASE_METHOD **) is also supported to meet scenarios that require class-level shared initialization.
2.3 BDD Style Test
Catch2 natively supports behavior-driven development (BDD) style test organization:
| Macro | Action | Corresponding |
|---|---|---|
| 'SCENARIO' | Define Scenario | = 'TEST_CASE("Scenario: ...")' |
| 'GIVEN' / 'AND_GIVEN | Given initial conditions | = 'SECTION("Given: ...")' |
| 'WHEN' / 'AND_WHEN | When an operation occurs | = 'SECTION("When: ...")' |
| 'THEN' / 'AND_THEN ' | Then the expected result is | = 'SECTION("Then: ...")' |
SCENARIO("User withdraws money from ATM", "[atm]") {
GIVEN("an account with $100 balance") {
Account account(100);
WHEN("withdrawing $60") {
account.withdraw(60);
THEN("balance is $40") {
REQUIRE(account.balance() == 40);
}
}
WHEN("withdrawing $200") {
THEN("exception is thrown") {
REQUIRE_THROWS(account.withdraw(200));
}
}
}
}
This makes Catch2 especially valuable for teams that need to work with non-developers (e. g., QA, BA)-the test specifications themselves are executable documents.
2.4 Tags-Driven Test Screening
Test cases can be categorized by free string labels and filtered flexibly at runtime:
TEST_CASE("Fast computation test", "[fast][math][core]") { ... }
TEST_CASE("Slow integration test", "[slow][io][integration]") { ... }
The command line runtime supports flexible filtering:
./tests "[fast]" # 只运行标有 [fast] 的测试
./tests "[core],[integration]" # 运行标有 [core] 或 [integration] 的
./tests "~[slow]" # 排除 [slow] 标签的测试
2.5 Matcher (matcher) system
Hamcrest-style based Matcher system for testing complex types and compound conditions:
Built-in Matcher:
-Strings: 'StartsWith', 'EndsWith', 'ContainsSubstring', 'Matches' (regular)
-Containers: 'Contains', 'VectorContains', 'UnorderedEquals'
-compound logic: by '& &', '| |', '! 'Free combination
REQUIRE_THAT(response,
StatusCode(200) &&
Header("Content-Type", ContainsSubstring("application/json"))
);
Custom Matcher (old and new API styles) is supported, and v3.15 supports the 'constexpr' Matcher.
2.6 Data Generator (Data Generators) and Type Parametric Testing
Supports data-driven and type-parameterized testing:
-Data generator: The'GENERATE' macro provides multiple input values for test cases, and the framework automatically generates a test path for each value
-Type parameterization test:'TEMPLATE_TEST_CASE' and 'TEMPLATE_PRODUCT_TEST_CASE', using the same test logic to verify multiple types
-Both can be used at the same time to achieve full coverage of the Cartesian product of type × data.
TEMPLATE_TEST_CASE("Numeric types support addition", "[math]", int, float, double) {
TestType a = GENERATE(1, 2, 5, 10);
TestType b = GENERATE(0, 1);
REQUIRE(add(a, b) == a + b);
}
2.7 Micro Benchmark (Micro-benchmarking)
Catch2 v2.9.0 has built-in benchmarking capabilities without introducing external dependencies such as Google Benchmark:
TEST_CASE("Sorting benchmark") {
BENCHMARK("std::sort random vector") {
std::vector v(1000);
std::generate(v.begin(), v.end(), std::rand);
std::sort(v.begin(), v.end());
return v; // 返回值防止编译器优化掉测试代码
};
}
Core competencies include:
-Automatic clock resolution detection and warm-up (warmup)
-Multi-stage estimation → run → analysis
-Support 'BENCHMARK_ADVANCED fine control timer
-Native Reporter output
2.8 Reporting System (Reporters) Integration with CI/CD
Catch2 has built-in 9 Reporter, which supports enabling multiple Reporter output to different targets at the same time:
| Reporter | Purpose |
|---|---|
| 'console' | Terminal-friendly color output (default) |
| 'xml' | Catch2 Native XML Format |
| 'junit' | JUnit XML format, seamless connection with Jenkins/TeamCity/GitLab CI |
| 'sonarqube' | SonarQube Common Test Data Format |
| 'tap' | Test Anything Protocol |
| 'automake' | Automake compatible formats |
| 'compact' | Compact single-line output |
| 'teamcity' | Automatic JetBrains TeamCity recognition |
| 'json' | Structured JSON output |
Custom Reporter (inherited from 'StreamingReporterBase' or 'CumulativeReporterBase') and Event Listener(Event Listeners) are supported to precisely control the output format and content.
2.9 Other Key Features
-Log macro:'INFO', 'WARN', 'FAIL', 'CAPTURE', etc., to output context information when the test is running.
-Skip tests at runtime:'SKIP' macro can dynamically skip tests based on runtime conditions
-CMake Auto Registration: Provides CMake scripts to automatically register tests to CTest
-Debugger Integration: Automatically breakpoint to debugger in case of failure
-Custom main(): supports user-defined main function, flexible control program entry
-Thread safety assertion:v3.15 assertion macros no longer need the '_THREAD_SAFE' suffix, the default thread safety
-Conan/Vcpkg/Bazel support: full coverage of mainstream package managers
3. Technical Architecture
Overall 3.1 Architecture
Catch2 v3 uses the modular library architecture and compiles it as a static library instead of header-only. The core architecture is as follows:
┌──────────────────────────────────────────────┐
│ TEST_CASE / SCENARIO │ ← 用户测试代码层
├──────────────────────────────────────────────┤
│ Assertion │ Matcher │ Generator │ Bench │ ← 测试工具层
│ Macros │ System │ System │ mark │
├──────────────────────────────────────────────┤
│ Expression Decomposition Engine │ ← 表达式分解引擎
├──────────────┬───────────────────────────────┤
│ Test Case │ Section Tracker │ ← 测试运行核心
│ Registry │ (Tree Walker) │
├──────────────┴───────────────────────────────┤
│ Reporter System + Event Bus │ ← 输出/事件层
├──────────────────────────────────────────────┤
│ CLI Parser │ Config │ CMake Integration │ ← 基础设施层
└──────────────────────────────────────────────┘
3.2 Key Components Details
3.2.1 Expression Decomposition Engine (Expression Decomposition Engine)
The core technology innovation of Catch2. Using C operator overloads ('= =', '!=', '<', '>', '<=', '>=', etc.) and expression template techniques:
- compile time: the expression 'a = = B 'is decomposed into the operation tree' ExprLhs(a) = = ExprRhs (B)'
- Runtime: The macro captures the value of each operand (serialized as a string via 'Catch::StringMaker
') - On failure: Output the actual value of the left and right operands of the complete expression.
Restriction: Expressions containing '& &' or '| |' cannot be decomposed (because these operators cannot be overloaded while maintaining short-circuit semantics). Parentheses or multiple independent assertions are required.
3.2.2 Section Tree Traversal (Section Tracker)
Section mechanism is implemented as a depth-first tree path walker:
-TEST_CASE as root node, each 'SECTION' as child node
-Each time it is executed, the framework tracks whether the current path has been executed
-One complete test run for each leaf node
-Path selection is done by 'Catch::RunContext' and 'Catch::SectionTracker' collaboration
3.2.3 Test Case Self-Registration Mechanism
Catch2 uses C static initialization to realize automatic registration of test cases:
-The TEST_CASE macro is expanded to generate a static object, and its constructor calls 'Catch::AutoReg' to register the test function to the global'TestCaseRegistry'
-No need to manually write any registration code other than 'RUN_ALL_TESTS()'
-In v3 release, the CMake integration script further automatically registers Catch2 tests to CTest
3.2.4 Reporter System and Event Bus
Event-driven architecture is used in the Reporter system:
-Catch2 defines 20 Reporter events ('testCaseStarting', 'assertionEnded', 'sectionEnded', 'benchmarkPreparing', etc.)
-Each Reporter selectively handles events of interest
-Support multi-Reporter parallel output to different files/streams
-Two base classes, 'StreamingReporterBase' (streaming output) and 'CumulativeReporterBase' (output after aggregation)
3.2.5 CMake Integration
Catch2 v3 takes CMake as a first-class build system:
-Provide 'Catch2::Catch2' and 'Catch2::Catch2WithMain' two CMake Target
-Automatic test registration: Automatically scan and register to CTest through the 'catch_discover_tests()'CMake function
-Supports all mainstream integration methods such as 'FetchContent', find_package, and add_subdirectory
-Compilation options are controlled by both CMake variables and C macros
4. Market positioning and competition analysis
4.1 Competitive Landscape
| Comparison dimension | Catch2 | Google Test | doctest | Boost.Test |
|---|---|---|---|---|
| GitHub Stars | 21.6K | 36K | 6.3K | (distributed with Boost) |
| Open Source Protocol | BSL 1.0 | BSD 3-Clause | MIT | Boost 1.0 |
| Minimum C Standard | C 14 | C 17 | C 11 | C 11 |
| Integration method | CMake static library | CMake static library | Single header file | Static/dynamic library |
| Assertion Style | Natural Expression Decomposition(2 macros) | Specialized Assertion Macros (20) | Class Catch2 Simplified to 2 Macros | Extremely Rich (Most Macros) |
| Core Innovation | Section Mechanism | Test Fixture Classes | Catch2 Section | Test Fixture Test Suite |
| BDD Support | Native GIVEN/WHEN/THEN | ❌Not supported | ❌Not supported | Limited support |
| Matcher | Built-in Composable | Built-in | Built-in (partial) | Requires Boost |
| Mocking | ❌Requires third party (trompeloeil) | ✅Built-in GMock | ❌Third Party Required | ❌Third Party Required |
| Benchmark | ✅Built-in | ❌Google Benchmark required | ❌Not supported | ❌Additional tools required |
| Compile Speed (1000 Test) | ~ 8.7s | ~ 12.8 4S | ~ 5.2s | ~ 15.8s |
| CI/CD | JUnit/TAP/SonarQube/TeamCity | Most Complete(Google Ecology) | JUnit/XML | JUnit/XML |
| IDE Integrated | CLion/VS Code Good | Widest(VS/CLion/QtC) | Medium | Medium |
| Learning curve | Low | Medium | Low | High (many concepts) |
| Community Activity | High (Ongoing Maintenance) | Very High(Google Endorsement) | Medium | Medium (With Boost) |
| Market Position | #2 Most Popular | #1 Most Popular | #3 Fastest Compile | #4 Most Comprehensive |
4.2 Differentiation Advantage
Catch2 has unique competitive advantages in the following dimensions:
- Natural Expression Decomposition: This is Catch2's signature capability. Google Test requires special macros such as ASSERT_EQ(a, B), while Catch2 uses REQUIRE(a = = B) '. The output when the test fails is clear and intuitive, greatly reducing the time to locate the problem.
- Section mechanism vs Fixture class: SetUp/TearDown mode of traditional Fixture is prone to state leakage and code duplication. Catch2's Section mechanism TEST_CASE from the beginning every time it enters a section, ensuring that test isolation is naturally established and the test intent is clear at a glance.
- Unification of BDD and TDD:Catch2 is the only mainstream C framework that natively supports both traditional TDD (TEST_CASE) and BDD('SCENARIO'/'GIVEN'/'WHEN'/'THEN') styles, suitable for teams that need to collaborate with non-technical stakeholders.
- Built-in benchmark test :Google Test needs to introduce additional Google Benchmark,Catch2 a library to solve unit test benchmark test, reduce the complexity of project dependency.
- Business-friendly BSL protocol : as loose as MIT/BSD, no GPL infection risk, suitable for enterprise closed-source projects.
4.3 target user group
| User Portrait | Scenario | Reason for Recommendation |
|---|---|---|
| Modern C ++ Project Team | Newly Started C ++ 14/17/20 Project | Concise Syntax, Fastest to Get Started, Zero Additional Dependencies |
| Team Pursuing Code Readability | Organization with Strong Code Review Culture | BDD Style Makes Testing = Documentation, Non-Developers Can Read |
| Embedded/C ++ Middle Layer Development | Need to compile fast and have few dependencies | Static library mode has excellent compilation performance and BSL protocol is commercially friendly |
| Game/Graphics Industry | King (Game), UX3D (Graphics), etc. are already in use | There are industry verification cases |
| Team Migrating from Google Test | Tired of 20 + Assertion Macros | 2 Core Macros Covering 90% of Scenes, Migration Cost Controllable |
| Teaching/Academic Scenario | Computer Science Courses, Research Projects | Very Low Learning Curve, One Lesson to Get started |
| Businesses that require compliance | Aerospace (NASA in use), Finance (Bloomberg in use) | Endorsements for use cases with stringent environments |
5. Business Model
Catch2 is a pure community-driven open source project with no commercial company support **and no revenue sources such as subscriptions, technical support or enterprise editions.
| Dimension | Description |
|---|---|
| License | BSL 1.0(Boost Software License), completely free, allows commercial closed-source use |
| Maintenance mode | Volunteer maintenance, core maintainer is Martin Hořeňovský(horenmar), supplemented by community contributors |
| Financial support | No VC financing, no corporate sponsorship (unlike some projects with foundation support) |
| Commercial Version | None -- Community Version only, and no Commercial Roadmap |
| Technical Support | Community Support via GitHub Issues / Discussions without SLA |
| Business Model Risks | Maintainers have limited energy, and the speed of fixing key bugs depends on personal time investment |
⚠ Pre-sales warning : For enterprise customers who need SLA guarantee or 24/7 technical support, please inform that Catch2 is a pure community project. If customers have such needs, they can recommend using Google Test (with Google endorsement and larger community) or introducing third-party C test consulting services as a supplement.
6. Pre-sales entry point
6.1 Why do customers need it?
- Pain point 1:C test code is too wordy and difficult to maintain *
Traditional testing frameworks have a large number of proprietary assertion macros (ASSERT_EQ, ASSERT_NE, ASSERT_LT, ASSERT_TRUE,...), which are costly for new members to learn, and a poor test code reading experience.
→ Catch2 scheme: two macros ('REQUIRE'/'CHECK') natural C expressions, writing tests is as intuitive as writing assertions.
Pain point 2:Fixture mechanism leads to state coupling between tests
XUnit style SetUp/TearDown is prone to the problem of "test B depends on the side effect of test a" and debugging is painful.
→ Catch2 scheme: Section mechanism executes TEST_CASE from scratch every time, test isolation is guaranteed by the framework, and state leakage never occurs.
Pain Point 3: Test Code Disconnected from Product Specifications
Test naming is often forced to use a legal identifier ('TestVectorResize') that cannot be read by business people.
→ Catch2 scheme: free-form string named test BDD-style macro, test = executable specification document.
Pain Point 4: Project Dependency Inflation
A variety of testing tools such as unit testing frameworks, benchmark libraries, and Mock libraries are required.
→ Catch2 scenario: a library coverage test benchmark (Mock still requires trompeloeil, etc., but trompeloeil also integrates well with Catch2 natively).
Pain Point 5:CI/CD Output Format Incompatible
Different CI systems require different reporting formats and require additional conversion scripts.
→ Catch2 scheme: 9 Reporter cover JUnit/TAP/SonarQube/TeamCity/JSON, and multiple Reporter can be output in parallel at the same time.
6.2 Pre-sales Speech
Opening Speech
"what framework does your team currently use for C ++ unit testing? Google Test, Boost.Test, or self-developed? In fact, the C ++ community has a very interesting framework called Catch2, which is the second most popular testing framework for C ++ in JetBrains developer surveys and is used by Bloomberg and NASA. The biggest difference is that only two assertion macros are needed to cover 90% of your test scenarios , and the written test code reads like natural language."
Technical Comparison (vs Google Test)
"Google Test is indeed the most perfect ecology, but it has dozens of macros like" ASSERT_EQ "and" ASSERT_NE ", which team members need to remember and choose. Catch2 put C's '= =', '! The = ','<'operator is used directly in the assertion-'REQUIRE(result = = expected)'-the actual value of both sides is automatically output when the test fails. In addition, Catch2's Section mechanism solves two old problems of traditional Fixture: state leakage and code duplication."
Quick Trial Technique
"Catch2 integration is very simple-CMake is only one line of configuration, no additional dependencies are required. You can try it on a small module first, migrate two or three test cases from the existing framework, and see the effect in half an hour. If you think it is easy to use, you can gradually promote it."
Risk Honest Words
"Of course I also need to be honest and say that Catch2 is a community-maintained open source project with no commercial support. If you need Mocking function, you also need to use it with trompeloeil. However, it uses BSL protocol, and commercial closed-source projects are completely fine."
7. Risks and Challenges
| Risk Dimension | Description | Impact Level | Mitigation Strategy |
|---|---|---|---|
| Maintaining Sustainability | Only Martin Hořeňovský is the core maintainer, part-time maintenance, no commercial entity support | 🔴High | Monitor community activity; choose Google Test as an alternative; or consider participating in maintenance through sponsorship/contribution |
| No built-in Mocking | Catch2 does not provide Mock capability, requires trompeloeil or Google Mock | 🟡Medium | Recommended trompeloeil (header file library consistent with Catch2 syntax style) as standard collocation |
| Google Test Ecological Advantages | Google Test has Google endorsement, IDE integration, CI templates, and enterprise training resources are more abundant | 🟡Medium | Catch2 already has JUnit/TeamCity/SonarQube Reporter to meet mainstream CI requirements; JetBrains CLion has good support for Catch2 |
| Old Compiler Incompatible | Requires C 14, does not support versions prior to MSVC 2015 | 🟢Low | Modern C projects have basically been upgraded to C 14/17; If customers still use C 11, consider doctest |
| Community size is relatively small | GitHub Issues 390, response speed depends on maintainer time and community volunteers | 🟡Medium | Documents are highly complete, and common problems are covered by tutorials; Evaluate whether the team has the ability to read the source code to solve bugs |
| Migration Cost | Migrating from Google Test or Boost.Test requires rewriting test cases | 🟡Medium | Progressive migration on a module-by-module basis; Catch2 is preferred in new modules, existing tests remain intact |
| AI Aided Development Adaptation | The AI Programming Assistant (Copilot/Cursor) has more training data for Google Test, and the accuracy of automatic test generation may be higher | 🟢Low | Limited impact, minimalist Catch2 syntax, sample code sufficient AI learning generation |
8. One sentence conclusion
Catch2 is the framework for optimal development experience in C unit testing-turning the test code into a living specification document with two assertion macros, zero additional dependencies and modern C syntax, especially suitable for enterprise-level C projects that attach importance to code readability, team collaboration efficiency and test maintenance cost. However, its pure community maintenance attribute determines that it is more suitable for "small and refined" technical teams, not large organizations that need SLA guarantees.