Per-test-case shared setup across SUBCASEs
Some test setup is expensive (e.g. creating a GL context, loading a font atlas) and I'd like it to run once per TEST_CASE, with the resulting object shared by all sibling SUBCASEs, and destroyed when the test case finishes.
TEST_CASE("foo")
{
auto obj = makeObj(); // currently runs once per leaf SUBCASE
// I want it to run once per TEST_CASE
SUBCASE("A") { /* uses obj */ }
SUBCASE("B") { /* uses obj */ }
SUBCASE("C") { /* uses obj */ }
} // ...and I want `obj` to be destroyed at the very end, *once*I understand the section-tree model re-runs the body per leaf -- that's by design and I'm not asking to change it. I'm asking about the cleanest way to opt out of re-running specific setup, without giving the object process-lifetime.
Using static is also something that I don't want to do in my scenario, as I want to deterministically destroy the objects in reverse construction order at the end of the entire test case, once.
What I've tried so far:
Namespace-scope static / lazy singleton: kind of works, but lifetime is the whole process, which is wrong when the resource should be scoped to one test case (e.g. to release a GL context before the next case acquires one).
A RAII refcounted holder around a static
std::optional<T>: doesn't help. Each body invocation enters and exits the guard in a balanced pair, so the count cycles 0→1→0 per leaf and the object is destroyed every time. From inside the body there is no way to detect "last leaf."TEST_CASE_FIXTURE: fixture is reconstructed per leaf, same as a localCustom
IReporterhookingtest_case_end: this kind of works, but feels like a lot of plumbing for a use case that I'd expect others to hit (especially in graphics/audio test suites).
Is there a better solution to achieve what I want currently? If not, would it be possible to add support for this use case?
Source: doctest/doctest