C++ Testing
High-signal workflow for writing and maintaining reliable C++ tests.
When to activate
- Adding new unit tests, regression tests, or integration tests
- Fixing failing or flaky C++ tests
- Wiring GoogleTest with CMake/CTest
- Enabling sanitizers for memory/UB/race diagnostics
Outcome expectations
- Fast deterministic unit tests with clear failure messages.
- Integration tests separated and labeled by cost/risk.
- Flake triage follows reproducible, root-cause-first workflow.
- Sanitizers/coverage are integrated as recurring quality signal.
Core rules
- Tests must be deterministic: no sleeping for synchronization.
- Prefer fakes for state, mocks for interactions.
- Use
ASSERT_*for preconditions,EXPECT_*for additional checks. - Keep unit tests fast; label integration tests separately.
- Keep one source of truth for test configuration in CMake targets.
- Avoid production-only test hooks unless they expose a real design seam.
- Pair with
test-driven-developmentwhen implementing persistent code or bug fixes test-first. - Pair with
testing-reliabilityfor mock/timing anti-patterns andsystematic-debuggingwhen symptoms are far from the defect.
Recommended workflow
- Define the behavior and test scope (unit vs integration) first.
- Add/adjust tests with clear Arrange-Act-Assert structure.
- Run focused test selection (
ctest -R/ gtest filter). - Run sanitizers for memory/UB/races where applicable.
- If flaky/failing, minimize reproducer and fix root cause before broad reruns.
Triage loop for failing tests
- Reproduce deterministically on one test binary.
- Capture failure class: assertion mismatch, crash, timeout, data race, UB.
- Narrow input/state until minimal failing case is obtained.
- Fix production code first (or fixture isolation), then harden test.
- Re-run focused + full suite + sanitizer build.
Resources
Load on demand:
references/googletest-cmake.md— FetchContent + CTest discovery (gtest_discover_tests)references/test-design.md— unit vs integration, fixtures, parameterized testsreferences/sanitizers-coverage.md— ASan/UBSan/TSan + coverage recipesreferences/flakes-debugging.md— anti-flake rules, gdb/lldb, Valgrind, MinGW objdump/nm, MSVC dumpbin/WinDbg, sanitizer env vars