cpp-testing
Use only when writing/updating/fixing C++ tests, configuring GoogleTest/CTest, diagnosing failing or flaky tests, or adding coverage/sanitizers.
By affaan-m · 2,959 installs
npx skills add affaan-m/ecc --skill cpp-testing
Source repository · Upstream listing
C++ Testing (Agent Skill)
Agent focused testing workflow for modern C++ (C++17/20) using GoogleTest/GoogleMock with CMake/CTest.
When to Use
Writing new C++ tests or fixing existing tests
Designing unit/integration test coverage for C++ components
Adding test coverage, CI gating, or regression protection
Configuring CMake/CTest workflows for consistent execution
Investigating test failures or flaky behavior
Enabling sanitizers for memory/race diagnostics
When NOT to Use
Implementing new product features without test changes
Large scale refactors unrelated to test coverage or failures
Performance tuning without test regressions to validate
Non C++ projects or non test tasks
Core Concepts
TDD loop : red → green → refactor (tests first, minimal fix, then cleanups).
Isolation : prefer dependency injection and fakes over global state.
Test layout : tests/unit , tests/integration , tests/testdata .
Mocks vs fakes : mock for interactions, fake for stateful behavior.
CTest discovery : use gtest discover tests() for stable test discovery.
CI signal : run subset first, then full suite with output on failure .
TDD Workflow
Follow the RED → GREEN → REFACTOR loop:
1. RED : write a failing test that captures the new behavior
2. GREEN : implement the smallest change to pass
3. REFACTOR : clean up while tests stay green
Code Examples
Basic Unit Test (gtest)
Fixture (gtest)
Mock (gmock)
CMake/CTest Quickstart
Running Tests
Debugging Failures
1. Re run the single failing test with gtest filter.
2. Add scoped logging around the failing assertion.
3. Re run with sanitizers enabled.
4. Expand to full suite once the root cause is fixed.
Coverage
Prefer target level settings instead of global flags.
GCC + gcov + lcov:
Clang + llvm cov:
Sanitizers
Flaky Tests Guardrails
Never use sleep for synchronization; use condition variables or latches.
Make temp directories unique per test and always clean them.
Avoid real time, network, or filesystem dependencies in unit tests.
Use deterministic seeds for randomized inputs.
Best Practices
DO
Keep tests deterministic and isolated
Prefer dependency injection over globals
Use ASSERT for preconditions, EXPECT for multiple checks
Separate unit vs integration tests in CTest labels or directories
Run sanitizers in CI for memory and race detection
DON'T
Don't depend on real time or network in unit tests
Don't use sleeps as synchronization when a condition variable can be used
Don't over mock simple value objects
Don't use brittle string matching for non critical logs
Common Pitfalls
Using fixed temp paths → Generate unique temp directories per test and clean them.
Relying on wall clock time → Inject a clock or use fake time sources.
Flaky concurrency tests → Use condition variables/latches and bounded waits.
Hidden global state → Reset global state in fixtures or remove globals.
Over mocking → Prefer fakes for stateful behavior and only mock interactions.
Missing sanitizer runs → Add ASan/UBSan/TSan builds in CI.
Coverage on debug only builds → Ensure coverage targets use consistent flags.
Optional Appendix: Fuzzing / Property Testing
Only use if the project already supports LLVM/libFuzzer or a property testing library.
libFuzzer : best for pure functions with minimal I/O.
RapidCheck : property based tests to validate invariants.
Minimal libFuzzer harness (pseudocode: replace ParseConfig):
Alternatives to GoogleTest
Catch2 : header only, expressive matchers
doctest : lightweight, minimal compile overhead