PolarHub
  • Agents
  • MCP Servers
  • Skills
  • PolarBear
PolarHub © 2026
技能市场测试开发cpp-testing
返回「测试开发」

cpp-testing

by affaan-m·ecc

0下载测试开发

简介

Use only when writing/updating/fixing C++ tests, configuring GoogleTest/CTest, diagnosing failing or flaky tests, or adding coverage/sanitizers.

SKILL.md 详细内容

来自 ECC · 9KB

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
// tests/add_test.cpp
#include <gtest/gtest.h>

int Add(int a, int b); // Provided by production code.

TEST(AddTest, AddsTwoNumbers) { // RED
  EXPECT_EQ(Add(2, 3), 5);
}

// src/add.cpp
int Add(int a, int b) { // GREEN
  return a + b;
}

// REFACTOR: simplify/rename once tests pass

Code Examples

Basic Unit Test (gtest)

// tests/calculator_test.cpp
#include <gtest/gtest.h>

int Add(int a, int b); // Provided by production code.

TEST(CalculatorTest, AddsTwoNumbers) {
    EXPECT_EQ(Add(2, 3), 5);
}

Fixture (gtest)

// tests/user_store_test.cpp
// Pseudocode stub: replace UserStore/User with project types.
#include <gtest/gtest.h>
#include <memory>
#include <optional>
#include <string>

struct User { std::string name; };
class UserStore {
public:
    explicit UserStore(std::string /*path*/) {}
    void Seed(std::initializer_list<User> /*users*/) {}
    std::optional<User> Find(const std::string &/*name*/) { return User{"alice"}; }
};

class UserStoreTest : public ::testing::Test {
protected:
    void SetUp() override {
        store = std::make_unique<UserStore>(":memory:");
        store->Seed({{"alice"}, {"bob"}});
    }

    std::unique_ptr<UserStore> store;
};

TEST_F(UserStoreTest, FindsExistingUser) {
    auto user = store->Find("alice");
    ASSERT_TRUE(user.has_value());
    EXPECT_EQ(user->name, "alice");
}

Mock (gmock)

// tests/notifier_test.cpp
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <string>

class Notifier {
public:
    virtual ~Notifier() = default;
    virtual void Send(const std::string &message) = 0;
};

class MockNotifier : public Notifier {
public:
    MOCK_METHOD(void, Send, (const std::string &message), (override));
};

class Service {
public:
    explicit Service(Notifier &notifier) : notifier_(notifier) {}
    void Publish(const std::string &message) { notifier_.Send(message); }

private:
    Notifier &notifier_;
};

TEST(ServiceTest, SendsNotifications) {
    MockNotifier notifier;
    Service service(notifier);

    EXPECT_CALL(notifier, Send("hello")).Times(1);
    service.Publish("hello");
}

CMake/CTest Quickstart

# CMakeLists.txt (excerpt)
cmake_minimum_required(VERSION 3.20)
project(example LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include(FetchContent)
# Prefer project-locked versions. If using a tag, use a pinned version per project policy.
set(GTEST_VERSION v1.17.0) # Adjust to project policy.
FetchContent_Declare(
  googletest
  # Google Test framework (official repository)
  URL https://github.com/google/googletest/archive/refs/tags/${GTEST_VERSION}.zip
)
FetchContent_MakeAvailable(googletest)

add_executable(example_tests
  tests/calculator_test.cpp
  src/calculator.cpp
)
target_link_libraries(example_tests GTest::gtest GTest::gmock GTest::gtest_main)

enable_testing()
include(GoogleTest)
gtest_discover_tests(example_tests)
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build -j
ctest --test-dir build --output-on-failure

Running Tests

ctest --test-dir build --output-on-failure
ctest --test-dir build -R ClampTest
ctest --test-dir build -R "UserStoreTest.*" --output-on-failure
./build/example_tests --gtest_filter=ClampTest.*
./build/example_tests --gtest_filter=UserStoreTest.FindsExistingUser

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.

option(ENABLE_COVERAGE "Enable coverage flags" OFF)

if(ENABLE_COVERAGE)
  if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
    target_compile_options(example_tests PRIVATE --coverage)
    target_link_options(example_tests PRIVATE --coverage)
  elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    target_compile_options(example_tests PRIVATE -fprofile-instr-generate -fcoverage-mapping)
    target_link_options(example_tests PRIVATE -fprofile-instr-generate)
  endif()
endif()

GCC + gcov + lcov:

cmake -S . -B build-cov -DENABLE_COVERAGE=ON
cmake --build build-cov -j
ctest --test-dir build-cov
lcov --capture --directory build-cov --output-file coverage.info
lcov --remove coverage.info '/usr/*' --output-file coverage.info
genhtml coverage.info --output-directory coverage

Clang + llvm-cov:

cmake -S . -B build-llvm -DENABLE_COVERAGE=ON -DCMAKE_CXX_COMPILER=clang++
cmake --build build-llvm -j
LLVM_PROFILE_FILE="build-llvm/default.profraw" ctest --test-dir build-llvm
llvm-profdata merge -sparse build-llvm/default.profraw -o build-llvm/default.profdata
llvm-cov report build-llvm/example_tests -instr-profile=build-llvm/default.profdata

Sanitizers

option(ENABLE_ASAN "Enable AddressSanitizer" OFF)
option(ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer" OFF)
option(ENABLE_TSAN "Enable ThreadSanitizer" OFF)

if(ENABLE_ASAN)
  add_compile_options(-fsanitize=address -fno-omit-frame-pointer)
  add_link_options(-fsanitize=address)
endif()
if(ENABLE_UBSAN)
  add_compile_options(-fsanitize=undefined -fno-omit-frame-pointer)
  add_link_options(-fsanitize=undefined)
endif()
if(ENABLE_TSAN)
  add_compile_options(-fsanitize=thread)
  add_link_options(-fsanitize=thread)
endif()

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):

#include <cstddef>
#include <cstdint>
#include <string>

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    std::string input(reinterpret_cast<const char *>(data), size);
    // ParseConfig(input); // project function
    return 0;
}

Alternatives to GoogleTest

  • Catch2: header-only, expressive matchers
  • doctest: lightweight, minimal compile overhead

相关 Skills(来自「测试开发」)

测试用例生成 Skills v2.0

包含 15 个子 Skill 的测试用例生成流水线,从产品说明书读取、需求分析、测试策略、正负向用例编写、质量审查到 Excel 输出。

50

Simulink HIL Modeling Standard

通用 Simulink HIL 建模、重构、迁移、评审和发布规范。用于设计 Plant/Control/IO/Bus/Fault/Monitor 架构,定义 Subsystem、Bus、ValueType、MonBus 和 Variant 接口,治理数据字典、参数、采样时间、多核任务、引用组件和初始化流程,检查 .slx/.mdl/.sldd/MATLAB Project,或为实时 HIL 模型生成合规报告、迁移方案、测试计划与发布证据。

47

ICDConverter AVIAGE Template

航空电子系统 ICD 接口控制文件(AVIAGE SYSTEMS 格式)转标准 Template 格式转换专家,适用于 ICD 转换、接口控制文件格式统一和帧结构解析。

2

ICDConverter TIU

面向航空电子 ICD Excel 文件的标准 Template 格式转换 Skill,支持协议帧分析、颜色编码识别、字段元数据索引、帧长度校验和 Excel 输出。

2

ai-regression-testing

Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code.

0

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

0

给 Agent 的安装提示词

复制下方脚本发给 AI,Agent 会自动完成下载和解压

Download and install a skill. Follow these steps EXACTLY. If any step fails, STOP and report the error.

SKILL_NAME="cpp-testing"
DOWNLOAD_URL="/downloads/ecc-skills/cpp-testing.zip"
INSTALL_CMD="Download cpp-testing.zip and extract it into your Agent skills directory."

STEP 1 - FIND SKILL DIRECTORY
[ -d "$HOME/.agents/skills" ] && echo "USER: $HOME/.agents/skills"
[ -d "$PWD/.agents/skills" ] && echo "PROJECT: $PWD/.agents/skills"
for d in "$HOME"/.*/skills; do [ -d "$d" ] && echo "USER: $d"; done
for d in "$PWD"/.*/skills; do [ -d "$d" ] && echo "PROJECT: $d"; done

Decide based on output (deduplicate lines first):
a) Only USER lines -> INSTALL_DIR="<that dir>/$SKILL_NAME"
b) Only PROJECT lines -> INSTALL_DIR="<that dir>/$SKILL_NAME"
c) Both USER and PROJECT -> ask the user to pick global install or project install.
d) Nothing found -> mkdir -p "$HOME/.agents/skills"; INSTALL_DIR="$HOME/.agents/skills/$SKILL_NAME"

STEP 2 - PREPARE
[ -f "$INSTALL_DIR/SKILL.md" ] && echo "EXISTS" || echo "NEW"
# If EXISTS, ask user whether to overwrite. If no, STOP.
mkdir -p "$INSTALL_DIR"

STEP 3 - DOWNLOAD
TMPDIR=$(mktemp -d)
curl -fSL -o "$TMPDIR/skill.zip" "$DOWNLOAD_URL" 2>/dev/null || wget -q -O "$TMPDIR/skill.zip" "$DOWNLOAD_URL"
# If both fail, try INSTALL_CMD as fallback: $INSTALL_CMD
# If still fail, STOP.

STEP 4 - EXTRACT & INSTALL
unzip -o "$TMPDIR/skill.zip" -d "$TMPDIR/ext" 2>/dev/null || python3 -m zipfile -e "$TMPDIR/skill.zip" "$TMPDIR/ext"
# If both fail, this is not a valid ZIP. STOP.

SKILL_PATH=$(find "$TMPDIR/ext" -maxdepth 2 -name "SKILL.md" -print | head -1)
if [ -n "$SKILL_PATH" ]; then
  cp -R "$(dirname "$SKILL_PATH")"/. "$INSTALL_DIR"/
else
  echo "FATAL: SKILL.md not found"; find "$TMPDIR/ext" -type f
fi

STEP 5 - VERIFY
head -5 "$INSTALL_DIR/SKILL.md"

DONE
Read "$INSTALL_DIR/SKILL.md" and follow its instructions to finish the user's task.
粘贴到 Claude / Cursor / Codex 等 Agent 后,会按步骤自动安装到 ~/.agents/skills/

自动安装

通过 PolarBear 协议从 ZIP 地址导入 Skill

Skill 压缩包地址
/downloads/ecc-skills/cpp-testing.zip

polarbear://skills/download?name=cpp-testing&url=%2Fdownloads%2Fecc-skills%2Fcpp-testing.zip

手动安装

3 步完成

  1. 1

    下载 Skill 压缩包

    下载 ZIP
  2. 2

    将其解压到 Agent 的 Skills 目录

    ~/.agents/skills/cpp-testing/
  3. 3

    重启或重新加载 Agent,让 Skill 可用

    重启 Agent 客户端,或刷新会话后即可调用此 Skill。

来源

平台
ecc
作者
affaan-m
Slug
cpp-testing
在源站查看