From c6b7d89fb4886eb7bf56d1455fe018e069d20ecf Mon Sep 17 00:00:00 2001 From: wuyangfan <1102042793@qq.com> Date: Mon, 18 May 2026 00:09:35 +0800 Subject: [PATCH] docs: explain TEST_CASE re-runs and section leaf paths Clarify when Catch2 runs a test case without entering a SECTION, including the single- vs multi-sibling SECTION cases from #552. Fixes #552 --- docs/faq.md | 10 ++++++ docs/test-cases-and-sections.md | 63 +++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/docs/faq.md b/docs/faq.md index 80923d26e8..8c04ec383a 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -7,6 +7,7 @@ [Why cannot I derive from the built-in reporters?](#why-cannot-i-derive-from-the-built-in-reporters)
[What is Catch2's ABI stability policy?](#what-is-catch2s-abi-stability-policy)
[What is Catch2's API stability policy?](#what-is-catch2s-api-stability-policy)
+[When are test cases run without sections?](#when-are-test-cases-run-without-sections)
[Does Catch2 support running tests in parallel?](#does-catch2-support-running-tests-in-parallel)
[Can I compile Catch2 into a dynamic library?](#can-i-compile-catch2-into-a-dynamic-library)
[What repeatability guarantees does Catch2 provide?](#what-repeatability-guarantees-does-catch2-provide)
@@ -51,6 +52,15 @@ This means that we will not knowingly make backwards-incompatible changes without incrementing the major version number. +## When are test cases run without sections? + +Catch2 runs a `TEST_CASE` once per **leaf** `SECTION` path. With multiple +sibling `SECTION`s at the same level, there is also a run that skips all of +them; with only one `SECTION`, you get a single run. See +[How many times does a `TEST_CASE` run?](test-cases-and-sections.md#how-many-times-does-a-test_case-run) +for examples (including [issue #552](https://github.com/catchorg/Catch2/issues/552)). + + ## Does Catch2 support running tests in parallel? Not natively, no. We see running tests in parallel as the job of an diff --git a/docs/test-cases-and-sections.md b/docs/test-cases-and-sections.md index 14db55aee1..eae0208bfb 100644 --- a/docs/test-cases-and-sections.md +++ b/docs/test-cases-and-sections.md @@ -2,6 +2,7 @@ # Test cases and sections **Contents**
+[How many times does a `TEST_CASE` run?](#how-many-times-does-a-test_case-run)
[Tags](#tags)
[Tag aliases](#tag-aliases)
[BDD-style test cases](#bdd-style-test-cases)
@@ -30,6 +31,68 @@ executable.** For examples see the [Tutorial](tutorial.md#top) + + +## How many times does a `TEST_CASE` run? + +Catch2 re-enters a `TEST_CASE` from the top **once for each leaf `SECTION`** +in the section tree. On every re-entry, Catch2 follows a single path through +nested `SECTION`s and skips the other branches. Code before the first +`SECTION` on that path, and code in each entered `SECTION` along the path, runs +for that execution. + +This means: + +* A `TEST_CASE` with **no** `SECTION`s runs **once**. +* A `TEST_CASE` with **one** top-level `SECTION` also runs **once** (only + that leaf path exists). +* A `TEST_CASE` with **two or more sibling** `SECTION`s at the same level + runs **once per sibling**, plus an additional run that **does not enter any + of those siblings** (the path that skips them). That extra run is what + makes code after a `SECTION` block execute both with and without entering + the section. + +Example from [issue #552](https://github.com/catchorg/Catch2/issues/552): + +```c++ +TEST_CASE("run once with section") { + printf("a0\n"); + SECTION("foo") { + printf("a1\n"); + } + printf("a2\n"); +} +``` + +prints `a0`, `a1`, `a2` once, because there is only one leaf section (`foo`). + +```c++ +TEST_CASE("run twice with and without section") { + int error = 0; + printf("b0\n"); + try { + printf("b1\n"); + SECTION("bar") { + printf("b2\n"); + throw 1; + } + printf("b3\n"); + } catch (int e) { + printf("b4\n"); + error = e; + } + printf("b5\n"); + REQUIRE(error > 0); +} +``` + +prints the `b2` path once and the `b3` path once (two leaf paths at the same +level: enter `bar`, or skip it). See also [issue #191](https://github.com/catchorg/Catch2/issues/191). + +For setup that must run on every path, keep it **before** the first `SECTION` +or use a [test fixture](test-fixtures.md#top) / [event listener](event-listeners.md#top). + + ## Tags Tags allow an arbitrary number of additional strings to be associated with a test case. Test cases can be selected (for running, or just for listing) by tag - or even by an expression that combines several tags. At their most basic level they provide a simple way to group several related tests together.