[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M786YV0KBMMRWBMMR8W72ZKP":3,"skill-same:01M786YV0KBMMRWBMMR8W72ZKP":46},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":26,"commitSha":27,"skillDirectory":28,"forksCount":14,"repositoryHtmlUrl":29,"repositoryHomepageUrl":6,"ownerHtmlUrl":30,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":31,"install":32,"resources":45},"01M786YV0KBMMRWBMMR8W72ZKP","c-testing",null,"Use ONLY when user explicitly requests C test code, CMocka\u002FUnity configuration,\ntest failure diagnosis, or coverage\u002FValgrind for C projects.\n\nTriggers: \"write test c\", \"cmocka\", \"unity test c\", \"C coverage\", \"valgrind\",\n\"C unit test\", \"function pointer di\", \"C mock\".\n\nDo NOT activate for: general C coding without test context, Makefile\u002FCMake build\nerrors, C compiler\u002Flinker issues, or embedded build system configuration.","chenziyang110\u002Flaunchdeck","chenziyang110","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43693913?v=4","01M7863EBWK1D0P6A29YGEMAS4","Robin11","01M7863ECM1VB6RXDMHTW90D2T",0,"MIT","https:\u002F\u002Fgithub.com\u002Fchenziyang110\u002Flaunchdeck\u002Fblob\u002Fmain\u002F.specify\u002Ftemplates\u002Fpassive-skills\u002Fc-testing\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: c-testing\ndescription: |\n  Use ONLY when user explicitly requests C test code, CMocka\u002FUnity configuration,\n  test failure diagnosis, or coverage\u002FValgrind for C projects.\n\n  Triggers: \"write test c\", \"cmocka\", \"unity test c\", \"C coverage\", \"valgrind\",\n  \"C unit test\", \"function pointer di\", \"C mock\".\n\n  Do NOT activate for: general C coding without test context, Makefile\u002FCMake build\n  errors, C compiler\u002Flinker issues, or embedded build system configuration.\norigin: ECC\n---\n\n# C Testing (Agent Skill)\n\nAgent-focused testing workflow for modern C (C11\u002FC17) using CMocka, the most widely used unit testing framework for C with mock support.\n\n## When to Use\n\n- Writing new C tests or fixing existing tests\n- Designing unit\u002Fintegration test coverage for C components\n- Adding test coverage, CI gating, or regression protection\n- Configuring CMocka\u002FCTest workflows for consistent execution\n- Investigating test failures or flaky behavior\n- Testing embedded systems, kernel modules, or system libraries\n\n### When NOT to Use\n\n- Implementing new product features without test changes\n- Large-scale refactors unrelated to test coverage or failures\n- Performance tuning without test regressions to validate\n- Non-C projects or non-test tasks\n\n### Stop Conditions — When to ASK instead of generating\n\nBefore generating any test code, STOP and ask the user if:\n- The code under test has **zero testability** (global state, hard-coded I\u002FO, no function-pointer DI, no mock boundaries)\n- **No test framework** is detected in CMakeLists.txt (no cmocka\u002FUnity\u002FCTest)\n- The request is **ambiguous**: \"test my code\" or \"add tests\" without specifying files or functions\n- A **required test dependency** (cmocka, Unity, Criterion) is not declared\n- The test would require **secrets, real credentials, or production database access**\n\n## Core Concepts\n\n- **TDD loop**: red → green → refactor (tests first, minimal fix, then cleanups).\n- **Isolation**: prefer dependency injection (function pointers) and mocks over global state.\n- **Test layout**: `tests\u002Funit`, `tests\u002Fintegration`, `tests\u002Ftestdata`, `tests\u002Fmocks\u002F`.\n- **CMocka**: assertion macros, mock framework, setup\u002Fteardown callbacks.\n- **CTest discovery**: `add_test()` with CMake for consistent test execution.\n- **CI signal**: `ctest --output-on-failure --schedule-random`.\n\n## Agent Execution Protocol\n\nWhen this skill is activated, follow this exact execution sequence:\n\n### Phase 1: Context Analysis\nBefore writing any test code:\n1. Identify the C standard (C11\u002FC17) and build tool (CMake\u002FMake).\n2. Check for existing test files (`tests\u002F`, `*_test.c`) to infer naming conventions and style (CMocka, Unity, Criterion).\n3. Analyze the code under test: identify public API surface, memory allocation patterns, pointer usage, and I\u002FO boundaries.\n4. Determine request type: (a) new tests, (b) fixing broken tests, (c) coverage\u002Fsanitizers, (d) flaky test diagnosis.\n\n### Phase 2: Strategy Selection\nBased on Phase 1, select the appropriate strategy:\n- **Pure functions \u002F utilities**: unit tests only, no mocks. Use CMocka `cmocka_unit_test` or Unity `RUN_TEST`.\n- **External dependencies (I\u002FO, network, hardware)**: use function pointer structs for dependency injection; use CMocka `expect_*` for mock verification.\n- **Memory-critical code**: enable AddressSanitizer (`-fsanitize=address`) and Valgrind (`memcheck`) in CI.\n- **Embedded systems**: use Unity (single-header, minimal footprint) instead of CMocka.\n\n### Decision Tree (Complex Scenarios)\n\n```text\nQ1: External I\u002FO (filesystem, network, hardware registers)?\n  → Yes → Q2\n  → No  → Pure unit test, no mocks needed\n\nQ2: Mockable (function pointer DI struct)?\n  → Yes → Mock via function pointer injection (CMocka expect_*)\n  → No  → Q3\n\nQ3: Embedded \u002F minimal footprint?\n  → Yes → Unity (single header, no external deps)\n  → No  → CMocka with CMake\u002FCTest\n\nQ4: Memory safety critical?\n  → Yes → Valgrind memcheck + AddressSanitizer in CI\n  → No  → Standard cmocka_unit_test\n\nQ5: Fuzzing needed?\n  → Yes → libFuzzer harness with LLVM sanitizer coverage\n  → No  → Standard unit test\n```\n\n### Phase 3: Test Case Design\nApply systematic test design before coding:\n1. **Happy path**: normal input → expected output.\n2. **Boundary values**: empty strings, `NULL`, `0`, `SIZE_MAX`, `INT_MAX`, empty arrays.\n3. **Error cases**: error return codes, `errno` values, `NULL` pointer dereference guards, allocation failures.\n4. **Memory & safety**: buffer overflows, use-after-free, memory leaks, uninitialized reads.\n\n### Phase 4: Code Generation\nOutput tests in this exact structure:\n```\n#### Test Strategy Summary\n- [ ] Scope: Unit \u002F Integration\n- [ ] Framework: CMocka (or Unity for embedded) + CMake\u002FCTest\n- [ ] Mocking: Yes\u002FNo — function pointer DI \u002F CMocka expect\n- [ ] Edge cases covered: \u003Clist>\n\n#### Generated Test Code\n\u003Cfile_path>\n\u003Ccode>\n\n#### Running Commands\n```bash\nctest --test-dir build --output-on-failure\n.\u002Fbuild\u002Fexample_tests\n```\n\n#### Coverage Impact (if applicable)\n- Estimated coverage change: \u003CX%>\n- Command to verify: `cmake -S . -B build-cov -DENABLE_COVERAGE=ON && cmake --build build-cov && ctest --test-dir build-cov && gcov src\u002F*.c`\n```\n\n### Phase 5: Verification Checklist\nBefore completing, verify:\n- [ ] Tests compile without warnings (`cmake --build build`).\n- [ ] Each test has exactly one logical assertion focus.\n- [ ] Mocks are restored after tests (reset function pointers to real implementations).\n- [ ] No `sleep()` used for synchronization (use condition variables or semaphores).\n- [ ] Flaky test guardrails applied (unique temp dirs, deterministic seeds, ASan\u002FUBSan\u002FValgrind in CI).\n\n## TDD Workflow\n\n```c\n\u002F\u002F tests\u002Fadd_test.c\nint add(int a, int b); \u002F\u002F Provided by production code.\n\nstatic void test_add(void **state) { \u002F\u002F RED\n    (void)state;\n    assert_int_equal(add(2, 3), 5);\n}\n\nint main(void) {\n    const struct CMUnitTest tests[] = {\n        cmocka_unit_test(test_add),\n    };\n    return cmocka_run_group_tests(tests, NULL, NULL);\n}\n\n\u002F\u002F src\u002Fadd.c\nint add(int a, int b) { return a + b; } \u002F\u002F GREEN\n\n\u002F\u002F REFACTOR: once tests pass\n```\n\n## Code Examples\n\n### Basic Unit Test (CMocka)\n\n```c\n\u002F\u002F tests\u002Fcalculator_test.c\n#include \u003Cstdarg.h>\n#include \u003Cstddef.h>\n#include \u003Csetjmp.h>\n#include \u003Ccmocka.h>\n\nint add(int a, int b); \u002F\u002F Provided by production code.\n\nstatic void test_add_positive(void **state) {\n    (void)state;\n    assert_int_equal(add(2, 3), 5);\n}\n\nstatic void test_add_negative(void **state) {\n    (void)state;\n    assert_int_equal(add(-1, 1), 0);\n}\n\nstatic void test_add_zero(void **state) {\n    (void)state;\n    assert_int_equal(add(0, 0), 0);\n}\n\nint main(void) {\n    const struct CMUnitTest tests[] = {\n        cmocka_unit_test(test_add_positive),\n        cmocka_unit_test(test_add_negative),\n        cmocka_unit_test(test_add_zero),\n    };\n    return cmocka_run_group_tests(tests, NULL, NULL);\n}\n```\n\n### Setup \u002F Teardown\n\n```c\n\u002F\u002F tests\u002Fuser_store_test.c\n#include \u003Ccmocka.h>\n#include \u003Cstdlib.h>\n#include \u003Cstring.h>\n\ntypedef struct {\n    char name[64];\n} User;\n\ntypedef struct {\n    User *users;\n    size_t count;\n    size_t capacity;\n} UserStore;\n\nstatic int setup(void **state) {\n    UserStore *store = calloc(1, sizeof(UserStore));\n    store->capacity = 10;\n    store->users = calloc(store->capacity, sizeof(User));\n    store->users[0] = (User){ .name = \"alice\" };\n    store->users[1] = (User){ .name = \"bob\" };\n    store->count = 2;\n    *state = store;\n    return 0;\n}\n\nstatic int teardown(void **state) {\n    UserStore *store = *state;\n    free(store->users);\n    free(store);\n    return 0;\n}\n\nstatic void test_find_existing_user(void **state) {\n    UserStore *store = *state;\n    \u002F\u002F ... find and assert\n    assert_non_null(store);\n}\n\nint main(void) {\n    const struct CMUnitTest tests[] = {\n        cmocka_unit_test_setup_teardown(\n            test_find_existing_user, setup, teardown),\n    };\n    return cmocka_run_group_tests(tests, NULL, NULL);\n}\n```\n\n### Mocking (CMocka)\n\n```c\n\u002F\u002F tests\u002Fnotifier_test.c\n#include \u003Ccmocka.h>\n#include \u003Cstdbool.h>\n\ntypedef bool (*NotifierSend)(const char *message);\nstatic NotifierSend mock_notifier_send = NULL;\n\n\u002F\u002F The function that will be called by production code\nbool notifier_send(const char *message) {\n    if (mock_notifier_send) {\n        return mock_notifier_send(message);\n    }\n    return false;\n}\n\n\u002F\u002F Mock control function\nstatic bool mock_send_ok(const char *message) {\n    check_expected(message);\n    return true;\n}\n\nstatic void test_service_publishes(void **state) {\n    (void)state;\n    mock_notifier_send = mock_send_ok;\n    expect_string(mock_send_ok, message, \"hello\");\n\n    service_publish(\"hello\");\n\n    mock_notifier_send = NULL;\n}\n```\n\n### CMocka Assertions\n\n```c\nassert_int_equal(a, b);       \u002F\u002F a == b\nassert_int_not_equal(a, b);   \u002F\u002F a != b\nassert_null(ptr);             \u002F\u002F ptr == NULL\nassert_non_null(ptr);         \u002F\u002F ptr != NULL\nassert_string_equal(a, b);    \u002F\u002F strcmp(a, b) == 0\nassert_string_not_equal(a, b);\nassert_memory_equal(a, b, size);\nassert_in_range(val, min, max);\nassert_not_in_range(val, min, max);\nassert_true(expr);\nassert_false(expr);\nassert_return_code(rc, error); \u002F\u002F rc >= 0\n```\n\n### Unity (Lightweight Alternative)\n\n```c\n\u002F\u002F tests\u002Fcalculator_test.c\n#include \"unity.h\"\n\nvoid setUp(void) {}\nvoid tearDown(void) {}\n\nvoid test_add_positive(void) {\n    TEST_ASSERT_EQUAL_INT32(5, add(2, 3));\n}\n\nvoid test_add_negative(void) {\n    TEST_ASSERT_EQUAL_INT32(0, add(-1, 1));\n}\n\nint main(void) {\n    UNITY_BEGIN();\n    RUN_TEST(test_add_positive);\n    RUN_TEST(test_add_negative);\n    return UNITY_END();\n}\n```\n\n## CMake\u002FCTest Quickstart\n\n```cmake\n# CMakeLists.txt (excerpt)\ncmake_minimum_required(VERSION 3.20)\nproject(example C)\n\nset(CMAKE_C_STANDARD 17)\n\ninclude(FetchContent)\nFetchContent_Declare(\n  cmocka\n  GIT_REPOSITORY https:\u002F\u002Fgitlab.com\u002Fcmocka\u002Fcmocka.git\n  GIT_TAG cmocka-1.1.7\n)\nFetchContent_MakeAvailable(cmocka)\n\nadd_executable(example_tests\n  tests\u002Fcalculator_test.c\n  src\u002Fcalculator.c\n)\ntarget_link_libraries(example_tests cmocka)\ntarget_include_directories(example_tests PRIVATE\n  ${cmocka_SOURCE_DIR}\u002Finclude\n  src\n)\n\nenable_testing()\nadd_test(NAME calculator_test COMMAND example_tests)\n```\n\n```bash\ncmake -S . -B build -DCMAKE_BUILD_TYPE=Debug\ncmake --build build\nctest --test-dir build --output-on-failure\n```\n\n## Running Tests\n\n```bash\nctest --test-dir build --output-on-failure\n\n# Direct execution\n.\u002Fbuild\u002Fexample_tests\n.\u002Fbuild\u002Fexample_tests 2>&1 | .\u002Fbuild\u002Fexample_tests -v\n```\n\n## Coverage\n\n```cmake\noption(ENABLE_COVERAGE \"Enable coverage flags\" OFF)\n\nif(ENABLE_COVERAGE)\n  if(CMAKE_C_COMPILER_ID MATCHES \"GNU\")\n    target_compile_options(example_tests PRIVATE --coverage)\n    target_link_options(example_tests PRIVATE --coverage)\n  elseif(CMAKE_C_COMPILER_ID MATCHES \"Clang\")\n    target_compile_options(example_tests PRIVATE -fprofile-instr-generate -fcoverage-mapping)\n    target_link_options(example_tests PRIVATE -fprofile-instr-generate)\n  endif()\nendif()\n```\n\n```bash\n# GCC + gcov\ncmake -S . -B build-cov -DENABLE_COVERAGE=ON\ncmake --build build-cov\nctest --test-dir build-cov\ngcov src\u002Fcalculator.c\n```\n\n## Memory & Thread Safety (Valgrind \u002F Sanitizers)\n\n```bash\n# Valgrind — memory leaks and invalid accesses\nvalgrind --leak-check=full --show-leak-kinds=all --track-origins=yes .\u002Fbuild\u002Fexample_tests\n\n# Helgrind — thread race detection\nvalgrind --tool=helgrind .\u002Fbuild\u002Fexample_tests\n\n# AddressSanitizer (compile-time, faster than Valgrind)\ncmake -S . -B build-asan -DCMAKE_C_FLAGS=\"-fsanitize=address -fno-omit-frame-pointer\" -DCMAKE_LINKER_FLAGS=\"-fsanitize=address\"\ncmake --build build-asan\nctest --test-dir build-asan\n```\n\n## Debugging Failures\n\n1. Re-run the single failing test by executing the binary directly.\n2. Add `-v` or `--verbose` flag for CMocka verbose output.\n3. Use GDB: `gdb --args .\u002Fbuild\u002Fexample_tests`.\n4. Add `cm_print_errors()` for CMocka mock error details.\n5. Expand to full suite once root cause is fixed.\n\n## CI\u002FCD Integration (GitHub Actions)\n\n```yaml\n# .github\u002Fworkflows\u002Ftest.yml\nname: Test\non: [push, pull_request]\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fcheckout@v4\n      - run: sudo apt install -y cmake valgrind\n      - run: cmake -B build -DCMAKE_BUILD_TYPE=Debug\n      - run: cmake --build build\n      - run: cd build && ctest --output-on-failure\n```\n\n## Flaky Tests Guardrails\n\n- Never use `sleep()` for synchronization; use condition variables or semaphores.\n- Make temp directories unique with `mkdtemp()` and clean them.\n- Avoid real time, network, or filesystem dependencies in unit tests.\n- Use deterministic seeds with `srand(42)` for randomized inputs.\n- Mock external library calls via function pointer replacement.\n\n## Test Case Design Patterns\n\nApply these systematic patterns before writing test code to ensure robust coverage beyond the happy path.\n\n### 1. Boundary Value Analysis\nTest at the edges of valid input domains: empty, zero, maximum, NULL, and just-outside valid ranges.\n\n```c\n\u002F\u002F tests\u002Fvalidator_test.c\nstatic void test_rejects_invalid_input(void **state) {\n    (void)state;\n    assert_int_equal(validate_input(\"\"), -1);\n    assert_int_equal(validate_input(\" \"), -1);\n    assert_int_equal(validate_input(\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"), -1);\n}\n```\n\n### 2. Negative \u002F Error Case Testing\nVerify the system behaves correctly under invalid or unexpected conditions.\n\n```c\n\u002F\u002F tests\u002Fcalculator_test.c\nstatic void test_divide_by_zero(void **state) {\n    (void)state;\n    int result;\n    assert_int_equal(divide(10, 0, &result), ERROR_DIV_ZERO);\n}\n```\n\n### 3. State-Based Testing\nFor objects with internal state, verify transitions between states are correct and irreversible where expected.\n\n```c\n\u002F\u002F tests\u002Fconnection_test.c\nstatic void test_connection_state_transitions(void **state) {\n    (void)state;\n    Connection *conn = connection_new();\n    assert_int_equal(connection_state(conn), STATE_CLOSED);\n    connection_open(conn);\n    assert_int_equal(connection_state(conn), STATE_OPEN);\n    connection_close(conn);\n    assert_int_equal(connection_state(conn), STATE_CLOSED);\n    \u002F\u002F Idempotency\n    connection_close(conn);\n    assert_int_equal(connection_state(conn), STATE_CLOSED);\n    connection_free(conn);\n}\n```\n\n## Common Test Smells to Avoid\n\n- **Assertion Roulette**: Many assertions without descriptive messages, making failure diagnosis ambiguous. *Fix: Use `assert_int_equal(val1, val2)` with descriptive test function names.*\n- **Happy Path Bias**: Only testing successful scenarios, leaving error paths uncovered. *Fix: Test `NULL` pointers, negative values, buffer overflow boundary conditions.*\n- **Mock Overdose**: Too many function-pointer mocks hiding integration issues. *Fix: Mock only at I\u002FO and hardware boundaries; test real implementations for pure logic.*\n- **The Free Ride**: Tests that execute code but assert nothing meaningful. *Fix: Every test must have at least one specific, falsifiable assertion.*\n- **Obscure Test**: Long test functions with no clear setup\u002Ftest split. *Fix: Use `cmocka_unit_test_setup_teardown` for resource management.*\n- **Flaky Test**: Non-deterministic results from memory corruption or shared state. *Fix: Use `mkdtemp()` for unique temp dirs, Valgrind\u002FASan in CI, deterministic inputs.*\n\n## Best Practices\n\n### DO\n\n- Keep tests deterministic and isolated\n- Use function pointer structs for dependency injection in C\n- Use `cmocka_unit_test_setup_teardown` for proper resource cleanup\n- Separate unit vs integration tests in CTest labels or directory structure\n- Run with AddressSanitizer and UndefinedBehaviorSanitizer in CI\n- Use `assert_return_code` for system call return value checks\n\n### DON'T\n\n- Don't use `sleep()` for synchronization\n- Don't depend on real time or network in unit tests\n- Don't use global mutable state that leaks between tests\n- Don't test static functions directly — test through public API\n- Don't use `#ifdef TEST` hacks in production code — use DI instead\n- Don't ignore return values of system calls in tests\n\n### Common Pitfalls\n\n- **Global state pollution** → Reset module-level globals in setup\u002Fteardown.\n- **Fixed temp paths** → Use `mkdtemp()` + `rmdir()` per test.\n- **Relying on wall clock** → Inject time via function pointer or macro.\n- **Missing mock cleanup** → Always restore real implementations after mock tests.\n- **Memory leaks** → Use AddressSanitizer in CI (`-fsanitize=address`).\n- **Undefined behavior** → Use UBSan (`-fsanitize=undefined`) in CI.\n- **Missing coverage targets** → Add gcov\u002Flcov to CI pipeline.\n\n## Optional: Fuzzing\n\n### libFuzzer (Clang)\n\n```c\n\u002F\u002F tests\u002Ffuzz_add.c\n#include \u003Cstddef.h>\n#include \u003Cstdint.h>\n\nint add(int a, int b);\n\nint LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {\n    if (size \u003C sizeof(int) * 2) return 0;\n    int a = *(const int *)data;\n    int b = *(const int *)(data + sizeof(int));\n    add(a, b); \u002F\u002F just ensure no crash\n    return 0;\n}\n```\n\n## Optional: Property-Based Testing\n\nProperty-based testing verifies invariants across randomly generated inputs. In C, use the `theft` library for combinatorial property testing:\n\n```c\n\u002F\u002F tests\u002Ftest_add_property.c\n#include \"theft.h\"\n\nstruct add_args { int a; int b; };\n\nenum theft_alloc_res alloc_add(struct theft *t, void *env, void **output) {\n    struct add_args *args = malloc(sizeof(*args));\n    args->a = theft_random_int(t);\n    args->b = theft_random_int(t);\n    *output = args;\n    return THEFT_ALLOC_OK;\n}\n\nstatic theft_trial_res prop_add_commutative(struct theft *t, void *arg) {\n    struct add_args *args = arg;\n    assert_int_equal(add(args->a, args->b), add(args->b, args->a));\n    return THEFT_TRIAL_PASS;\n}\n```\n\n> **Build**: Compile with `-ltheft`. Run 1000+ random trials per property. Target invariants: commutativity (`a+b == b+a`), associativity, identity (`a+0 == a`).\n\n## Alternatives\n\n- **Unity** (v2.6.x): Extremely lightweight, single header, ideal for embedded systems.\n- **Criterion** (v2.4.x): Modern, cross-platform, with parameterized tests and benchmarks.\n- **greatest**: Minimalist, single-header test framework.\n","# C Testing (Agent Skill)\n\nAgent-focused testing workflow for modern C (C11\u002FC17) using CMocka, the most widely used unit testing framework for C with mock support.\n\n## When to Use\n\n- Writing new C tests or fixing existing tests\n- Designing unit\u002Fintegration test coverage for C components\n- Adding test coverage, CI gating, or regression protection\n- Configuring CMocka\u002FCTest workflows for consistent execution\n- Investigating test failures or flaky behavior\n- Testing embedded systems, kernel modules, or system libraries\n\n### When NOT to Use\n\n- Implementing new product features without test changes\n- Large-scale refactors unrelated to test coverage or failures\n- Performance tuning without test regressions to validate\n- Non-C projects or non-test tasks\n\n### Stop Conditions — When to ASK instead of generating\n\nBefore generating any test code, STOP and ask the user if:\n- The code under test has **zero testability** (global state, hard-coded I\u002FO, no function-pointer DI, no mock boundaries)\n- **No test framework** is detected in CMakeLists.txt (no cmocka\u002FUnity\u002FCTest)\n- The request is **ambiguous**: \"test my code\" or \"add tests\" without specifying files or functions\n- A **required test dependency** (cmocka, Unity, Criterion) is not declared\n- The test would require **secrets, real credentials, or production database access**\n\n## Core Concepts\n\n- **TDD loop**: red → green → refactor (tests first, minimal fix, then cleanups).\n- **Isolation**: prefer dependency injection (function pointers) and mocks over global state.\n- **Test layout**: `tests\u002Funit`, `tests\u002Fintegration`, `tests\u002Ftestdata`, `tests\u002Fmocks\u002F`.\n- **CMocka**: assertion macros, mock framework, setup\u002Fteardown callbacks.\n- **CTest discovery**: `add_test()` with CMake for consistent test execution.\n- **CI signal**: `ctest --output-on-failure --schedule-random`.\n\n## Agent Execution Protocol\n\nWhen this skill is activated, follow this exact execution sequence:\n\n### Phase 1: Context Analysis\nBefore writing any test code:\n1. Identify the C standard (C11\u002FC17) and build tool (CMake\u002FMake).\n2. Check for existing test files (`tests\u002F`, `*_test.c`) to infer naming conventions and style (CMocka, Unity, Criterion).\n3. Analyze the code under test: identify public API surface, memory allocation patterns, pointer usage, and I\u002FO boundaries.\n4. Determine request type: (a) new tests, (b) fixing broken tests, (c) coverage\u002Fsanitizers, (d) flaky test diagnosis.\n\n### Phase 2: Strategy Selection\nBased on Phase 1, select the appropriate strategy:\n- **Pure functions \u002F utilities**: unit tests only, no mocks. Use CMocka `cmocka_unit_test` or Unity `RUN_TEST`.\n- **External dependencies (I\u002FO, network, hardware)**: use function pointer structs for dependency injection; use CMocka `expect_*` for mock verification.\n- **Memory-critical code**: enable AddressSanitizer (`-fsanitize=address`) and Valgrind (`memcheck`) in CI.\n- **Embedded systems**: use Unity (single-header, minimal footprint) instead of CMocka.\n\n### Decision Tree (Complex Scenarios)\n\n```text\nQ1: External I\u002FO (filesystem, network, hardware registers)?\n  → Yes → Q2\n  → No  → Pure unit test, no mocks needed\n\nQ2: Mockable (function pointer DI struct)?\n  → Yes → Mock via function pointer injection (CMocka expect_*)\n  → No  → Q3\n\nQ3: Embedded \u002F minimal footprint?\n  → Yes → Unity (single header, no external deps)\n  → No  → CMocka with CMake\u002FCTest\n\nQ4: Memory safety critical?\n  → Yes → Valgrind memcheck + AddressSanitizer in CI\n  → No  → Standard cmocka_unit_test\n\nQ5: Fuzzing needed?\n  → Yes → libFuzzer harness with LLVM sanitizer coverage\n  → No  → Standard unit test\n```\n\n### Phase 3: Test Case Design\nApply systematic test design before coding:\n1. **Happy path**: normal input → expected output.\n2. **Boundary values**: empty strings, `NULL`, `0`, `SIZE_MAX`, `INT_MAX`, empty arrays.\n3. **Error cases**: error return codes, `errno` values, `NULL` pointer dereference guards, allocation failures.\n4. **Memory & safety**: buffer overflows, use-after-free, memory leaks, uninitialized reads.\n\n### Phase 4: Code Generation\nOutput tests in this exact structure:\n```\n#### Test Strategy Summary\n- [ ] Scope: Unit \u002F Integration\n- [ ] Framework: CMocka (or Unity for embedded) + CMake\u002FCTest\n- [ ] Mocking: Yes\u002FNo — function pointer DI \u002F CMocka expect\n- [ ] Edge cases covered: \u003Clist>\n\n#### Generated Test Code\n\u003Cfile_path>\n\u003Ccode>\n\n#### Running Commands\n```bash\nctest --test-dir build --output-on-failure\n.\u002Fbuild\u002Fexample_tests\n```\n\n#### Coverage Impact (if applicable)\n- Estimated coverage change: \u003CX%>\n- Command to verify: `cmake -S . -B build-cov -DENABLE_COVERAGE=ON && cmake --build build-cov && ctest --test-dir build-cov && gcov src\u002F*.c`\n```\n\n### Phase 5: Verification Checklist\nBefore completing, verify:\n- [ ] Tests compile without warnings (`cmake --build build`).\n- [ ] Each test has exactly one logical assertion focus.\n- [ ] Mocks are restored after tests (reset function pointers to real implementations).\n- [ ] No `sleep()` used for synchronization (use condition variables or semaphores).\n- [ ] Flaky test guardrails applied (unique temp dirs, deterministic seeds, ASan\u002FUBSan\u002FValgrind in CI).\n\n## TDD Workflow\n\n```c\n\u002F\u002F tests\u002Fadd_test.c\nint add(int a, int b); \u002F\u002F Provided by production code.\n\nstatic void test_add(void **state) { \u002F\u002F RED\n    (void)state;\n    assert_int_equal(add(2, 3), 5);\n}\n\nint main(void) {\n    const struct CMUnitTest tests[] = {\n        cmocka_unit_test(test_add),\n    };\n    return cmocka_run_group_tests(tests, NULL, NULL);\n}\n\n\u002F\u002F src\u002Fadd.c\nint add(int a, int b) { return a + b; } \u002F\u002F GREEN\n\n\u002F\u002F REFACTOR: once tests pass\n```\n\n## Code Examples\n\n### Basic Unit Test (CMocka)\n\n```c\n\u002F\u002F tests\u002Fcalculator_test.c\n#include \u003Cstdarg.h>\n#include \u003Cstddef.h>\n#include \u003Csetjmp.h>\n#include \u003Ccmocka.h>\n\nint add(int a, int b); \u002F\u002F Provided by production code.\n\nstatic void test_add_positive(void **state) {\n    (void)state;\n    assert_int_equal(add(2, 3), 5);\n}\n\nstatic void test_add_negative(void **state) {\n    (void)state;\n    assert_int_equal(add(-1, 1), 0);\n}\n\nstatic void test_add_zero(void **state) {\n    (void)state;\n    assert_int_equal(add(0, 0), 0);\n}\n\nint main(void) {\n    const struct CMUnitTest tests[] = {\n        cmocka_unit_test(test_add_positive),\n        cmocka_unit_test(test_add_negative),\n        cmocka_unit_test(test_add_zero),\n    };\n    return cmocka_run_group_tests(tests, NULL, NULL);\n}\n```\n\n### Setup \u002F Teardown\n\n```c\n\u002F\u002F tests\u002Fuser_store_test.c\n#include \u003Ccmocka.h>\n#include \u003Cstdlib.h>\n#include \u003Cstring.h>\n\ntypedef struct {\n    char name[64];\n} User;\n\ntypedef struct {\n    User *users;\n    size_t count;\n    size_t capacity;\n} UserStore;\n\nstatic int setup(void **state) {\n    UserStore *store = calloc(1, sizeof(UserStore));\n    store->capacity = 10;\n    store->users = calloc(store->capacity, sizeof(User));\n    store->users[0] = (User){ .name = \"alice\" };\n    store->users[1] = (User){ .name = \"bob\" };\n    store->count = 2;\n    *state = store;\n    return 0;\n}\n\nstatic int teardown(void **state) {\n    UserStore *store = *state;\n    free(store->users);\n    free(store);\n    return 0;\n}\n\nstatic void test_find_existing_user(void **state) {\n    UserStore *store = *state;\n    \u002F\u002F ... find and assert\n    assert_non_null(store);\n}\n\nint main(void) {\n    const struct CMUnitTest tests[] = {\n        cmocka_unit_test_setup_teardown(\n            test_find_existing_user, setup, teardown),\n    };\n    return cmocka_run_group_tests(tests, NULL, NULL);\n}\n```\n\n### Mocking (CMocka)\n\n```c\n\u002F\u002F tests\u002Fnotifier_test.c\n#include \u003Ccmocka.h>\n#include \u003Cstdbool.h>\n\ntypedef bool (*NotifierSend)(const char *message);\nstatic NotifierSend mock_notifier_send = NULL;\n\n\u002F\u002F The function that will be called by production code\nbool notifier_send(const char *message) {\n    if (mock_notifier_send) {\n        return mock_notifier_send(message);\n    }\n    return false;\n}\n\n\u002F\u002F Mock control function\nstatic bool mock_send_ok(const char *message) {\n    check_expected(message);\n    return true;\n}\n\nstatic void test_service_publishes(void **state) {\n    (void)state;\n    mock_notifier_send = mock_send_ok;\n    expect_string(mock_send_ok, message, \"hello\");\n\n    service_publish(\"hello\");\n\n    mock_notifier_send = NULL;\n}\n```\n\n### CMocka Assertions\n\n```c\nassert_int_equal(a, b);       \u002F\u002F a == b\nassert_int_not_equal(a, b);   \u002F\u002F a != b\nassert_null(ptr);             \u002F\u002F ptr == NULL\nassert_non_null(ptr);         \u002F\u002F ptr != NULL\nassert_string_equal(a, b);    \u002F\u002F strcmp(a, b) == 0\nassert_string_not_equal(a, b);\nassert_memory_equal(a, b, size);\nassert_in_range(val, min, max);\nassert_not_in_range(val, min, max);\nassert_true(expr);\nassert_false(expr);\nassert_return_code(rc, error); \u002F\u002F rc >= 0\n```\n\n### Unity (Lightweight Alternative)\n\n```c\n\u002F\u002F tests\u002Fcalculator_test.c\n#include \"unity.h\"\n\nvoid setUp(void) {}\nvoid tearDown(void) {}\n\nvoid test_add_positive(void) {\n    TEST_ASSERT_EQUAL_INT32(5, add(2, 3));\n}\n\nvoid test_add_negative(void) {\n    TEST_ASSERT_EQUAL_INT32(0, add(-1, 1));\n}\n\nint main(void) {\n    UNITY_BEGIN();\n    RUN_TEST(test_add_positive);\n    RUN_TEST(test_add_negative);\n    return UNITY_END();\n}\n```\n\n## CMake\u002FCTest Quickstart\n\n```cmake\n# CMakeLists.txt (excerpt)\ncmake_minimum_required(VERSION 3.20)\nproject(example C)\n\nset(CMAKE_C_STANDARD 17)\n\ninclude(FetchContent)\nFetchContent_Declare(\n  cmocka\n  GIT_REPOSITORY https:\u002F\u002Fgitlab.com\u002Fcmocka\u002Fcmocka.git\n  GIT_TAG cmocka-1.1.7\n)\nFetchContent_MakeAvailable(cmocka)\n\nadd_executable(example_tests\n  tests\u002Fcalculator_test.c\n  src\u002Fcalculator.c\n)\ntarget_link_libraries(example_tests cmocka)\ntarget_include_directories(example_tests PRIVATE\n  ${cmocka_SOURCE_DIR}\u002Finclude\n  src\n)\n\nenable_testing()\nadd_test(NAME calculator_test COMMAND example_tests)\n```\n\n```bash\ncmake -S . -B build -DCMAKE_BUILD_TYPE=Debug\ncmake --build build\nctest --test-dir build --output-on-failure\n```\n\n## Running Tests\n\n```bash\nctest --test-dir build --output-on-failure\n\n# Direct execution\n.\u002Fbuild\u002Fexample_tests\n.\u002Fbuild\u002Fexample_tests 2>&1 | .\u002Fbuild\u002Fexample_tests -v\n```\n\n## Coverage\n\n```cmake\noption(ENABLE_COVERAGE \"Enable coverage flags\" OFF)\n\nif(ENABLE_COVERAGE)\n  if(CMAKE_C_COMPILER_ID MATCHES \"GNU\")\n    target_compile_options(example_tests PRIVATE --coverage)\n    target_link_options(example_tests PRIVATE --coverage)\n  elseif(CMAKE_C_COMPILER_ID MATCHES \"Clang\")\n    target_compile_options(example_tests PRIVATE -fprofile-instr-generate -fcoverage-mapping)\n    target_link_options(example_tests PRIVATE -fprofile-instr-generate)\n  endif()\nendif()\n```\n\n```bash\n# GCC + gcov\ncmake -S . -B build-cov -DENABLE_COVERAGE=ON\ncmake --build build-cov\nctest --test-dir build-cov\ngcov src\u002Fcalculator.c\n```\n\n## Memory & Thread Safety (Valgrind \u002F Sanitizers)\n\n```bash\n# Valgrind — memory leaks and invalid accesses\nvalgrind --leak-check=full --show-leak-kinds=all --track-origins=yes .\u002Fbuild\u002Fexample_tests\n\n# Helgrind — thread race detection\nvalgrind --tool=helgrind .\u002Fbuild\u002Fexample_tests\n\n# AddressSanitizer (compile-time, faster than Valgrind)\ncmake -S . -B build-asan -DCMAKE_C_FLAGS=\"-fsanitize=address -fno-omit-frame-pointer\" -DCMAKE_LINKER_FLAGS=\"-fsanitize=address\"\ncmake --build build-asan\nctest --test-dir build-asan\n```\n\n## Debugging Failures\n\n1. Re-run the single failing test by executing the binary directly.\n2. Add `-v` or `--verbose` flag for CMocka verbose output.\n3. Use GDB: `gdb --args .\u002Fbuild\u002Fexample_tests`.\n4. Add `cm_print_errors()` for CMocka mock error details.\n5. Expand to full suite once root cause is fixed.\n\n## CI\u002FCD Integration (GitHub Actions)\n\n```yaml\n# .github\u002Fworkflows\u002Ftest.yml\nname: Test\non: [push, pull_request]\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fcheckout@v4\n      - run: sudo apt install -y cmake valgrind\n      - run: cmake -B build -DCMAKE_BUILD_TYPE=Debug\n      - run: cmake --build build\n      - run: cd build && ctest --output-on-failure\n```\n\n## Flaky Tests Guardrails\n\n- Never use `sleep()` for synchronization; use condition variables or semaphores.\n- Make temp directories unique with `mkdtemp()` and clean them.\n- Avoid real time, network, or filesystem dependencies in unit tests.\n- Use deterministic seeds with `srand(42)` for randomized inputs.\n- Mock external library calls via function pointer replacement.\n\n## Test Case Design Patterns\n\nApply these systematic patterns before writing test code to ensure robust coverage beyond the happy path.\n\n### 1. Boundary Value Analysis\nTest at the edges of valid input domains: empty, zero, maximum, NULL, and just-outside valid ranges.\n\n```c\n\u002F\u002F tests\u002Fvalidator_test.c\nstatic void test_rejects_invalid_input(void **state) {\n    (void)state;\n    assert_int_equal(validate_input(\"\"), -1);\n    assert_int_equal(validate_input(\" \"), -1);\n    assert_int_equal(validate_input(\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"), -1);\n}\n```\n\n### 2. Negative \u002F Error Case Testing\nVerify the system behaves correctly under invalid or unexpected conditions.\n\n```c\n\u002F\u002F tests\u002Fcalculator_test.c\nstatic void test_divide_by_zero(void **state) {\n    (void)state;\n    int result;\n    assert_int_equal(divide(10, 0, &result), ERROR_DIV_ZERO);\n}\n```\n\n### 3. State-Based Testing\nFor objects with internal state, verify transitions between states are correct and irreversible where expected.\n\n```c\n\u002F\u002F tests\u002Fconnection_test.c\nstatic void test_connection_state_transitions(void **state) {\n    (void)state;\n    Connection *conn = connection_new();\n    assert_int_equal(connection_state(conn), STATE_CLOSED);\n    connection_open(conn);\n    assert_int_equal(connection_state(conn), STATE_OPEN);\n    connection_close(conn);\n    assert_int_equal(connection_state(conn), STATE_CLOSED);\n    \u002F\u002F Idempotency\n    connection_close(conn);\n    assert_int_equal(connection_state(conn), STATE_CLOSED);\n    connection_free(conn);\n}\n```\n\n## Common Test Smells to Avoid\n\n- **Assertion Roulette**: Many assertions without descriptive messages, making failure diagnosis ambiguous. *Fix: Use `assert_int_equal(val1, val2)` with descriptive test function names.*\n- **Happy Path Bias**: Only testing successful scenarios, leaving error paths uncovered. *Fix: Test `NULL` pointers, negative values, buffer overflow boundary conditions.*\n- **Mock Overdose**: Too many function-pointer mocks hiding integration issues. *Fix: Mock only at I\u002FO and hardware boundaries; test real implementations for pure logic.*\n- **The Free Ride**: Tests that execute code but assert nothing meaningful. *Fix: Every test must have at least one specific, falsifiable assertion.*\n- **Obscure Test**: Long test functions with no clear setup\u002Ftest split. *Fix: Use `cmocka_unit_test_setup_teardown` for resource management.*\n- **Flaky Test**: Non-deterministic results from memory corruption or shared state. *Fix: Use `mkdtemp()` for unique temp dirs, Valgrind\u002FASan in CI, deterministic inputs.*\n\n## Best Practices\n\n### DO\n\n- Keep tests deterministic and isolated\n- Use function pointer structs for dependency injection in C\n- Use `cmocka_unit_test_setup_teardown` for proper resource cleanup\n- Separate unit vs integration tests in CTest labels or directory structure\n- Run with AddressSanitizer and UndefinedBehaviorSanitizer in CI\n- Use `assert_return_code` for system call return value checks\n\n### DON'T\n\n- Don't use `sleep()` for synchronization\n- Don't depend on real time or network in unit tests\n- Don't use global mutable state that leaks between tests\n- Don't test static functions directly — test through public API\n- Don't use `#ifdef TEST` hacks in production code — use DI instead\n- Don't ignore return values of system calls in tests\n\n### Common Pitfalls\n\n- **Global state pollution** → Reset module-level globals in setup\u002Fteardown.\n- **Fixed temp paths** → Use `mkdtemp()` + `rmdir()` per test.\n- **Relying on wall clock** → Inject time via function pointer or macro.\n- **Missing mock cleanup** → Always restore real implementations after mock tests.\n- **Memory leaks** → Use AddressSanitizer in CI (`-fsanitize=address`).\n- **Undefined behavior** → Use UBSan (`-fsanitize=undefined`) in CI.\n- **Missing coverage targets** → Add gcov\u002Flcov to CI pipeline.\n\n## Optional: Fuzzing\n\n### libFuzzer (Clang)\n\n```c\n\u002F\u002F tests\u002Ffuzz_add.c\n#include \u003Cstddef.h>\n#include \u003Cstdint.h>\n\nint add(int a, int b);\n\nint LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {\n    if (size \u003C sizeof(int) * 2) return 0;\n    int a = *(const int *)data;\n    int b = *(const int *)(data + sizeof(int));\n    add(a, b); \u002F\u002F just ensure no crash\n    return 0;\n}\n```\n\n## Optional: Property-Based Testing\n\nProperty-based testing verifies invariants across randomly generated inputs. In C, use the `theft` library for combinatorial property testing:\n\n```c\n\u002F\u002F tests\u002Ftest_add_property.c\n#include \"theft.h\"\n\nstruct add_args { int a; int b; };\n\nenum theft_alloc_res alloc_add(struct theft *t, void *env, void **output) {\n    struct add_args *args = malloc(sizeof(*args));\n    args->a = theft_random_int(t);\n    args->b = theft_random_int(t);\n    *output = args;\n    return THEFT_ALLOC_OK;\n}\n\nstatic theft_trial_res prop_add_commutative(struct theft *t, void *arg) {\n    struct add_args *args = arg;\n    assert_int_equal(add(args->a, args->b), add(args->b, args->a));\n    return THEFT_TRIAL_PASS;\n}\n```\n\n> **Build**: Compile with `-ltheft`. Run 1000+ random trials per property. Target invariants: commutativity (`a+b == b+a`), associativity, identity (`a+0 == a`).\n\n## Alternatives\n\n- **Unity** (v2.6.x): Extremely lightweight, single header, ideal for embedded systems.\n- **Criterion** (v2.4.x): Modern, cross-platform, with parameterized tests and benchmarks.\n- **greatest**: Minimalist, single-header test framework.\n",{"name":5,"origin":24,"description":25},"ECC","Use ONLY when user explicitly requests C test code, CMocka\u002FUnity configuration,\ntest failure diagnosis, or coverage\u002FValgrind for C projects.\n\nTriggers: \"write test c\", \"cmocka\", \"unity test c\", \"C coverage\", \"valgrind\",\n\"C unit test\", \"function pointer di\", \"C mock\".\n\nDo NOT activate for: general C coding without test context, Makefile\u002FCMake build\nerrors, C compiler\u002Flinker issues, or embedded build system configuration.\n","main","021f5cbe02157229460a577e9a585f2da6d78cb0",".specify\u002Ftemplates\u002Fpassive-skills\u002Fc-testing","https:\u002F\u002Fgithub.com\u002Fchenziyang110\u002Flaunchdeck","https:\u002F\u002Fgithub.com\u002Fchenziyang110","2026-08-07 18:10:54",{"source":8,"skillName":5,"commands":33,"prompt":43,"zipAvailable":44},[34,37,40],{"tool":35,"command":36},"npx","npx skills add chenziyang110\u002Flaunchdeck --skill c-testing",{"tool":38,"command":39},"bunx","bunx skills add chenziyang110\u002Flaunchdeck --skill c-testing",{"tool":41,"command":42},"pnpm","pnpm dlx skills add chenziyang110\u002Flaunchdeck --skill c-testing","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fchenziyang110\u002Flaunchdeck\u002Fblob\u002Fmain\u002F.specify\u002Ftemplates\u002Fpassive-skills\u002Fc-testing\u002FSKILL.md",true,[],[47,54,60,66,73,82],{"skillNo":48,"name":49,"nameZh":6,"description":50,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":51,"categories":52,"keywords":53,"publishedAt":19},"01M7875F3HQ1GF5F6BR36KY3JE","launchdeck-agent","Codex host adapter contract fixture for Launchdeck.","https:\u002F\u002Fgithub.com\u002Fchenziyang110\u002Flaunchdeck\u002Fblob\u002Fmain\u002Ftest\u002Ffixtures\u002Fagent-hosts\u002Fcodex\u002Fskill\u002FSKILL.md",[],[],{"skillNo":55,"name":49,"nameZh":6,"description":56,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":57,"categories":58,"keywords":59,"publishedAt":19},"01M7875DV2DQR33K1NFJHKAMZP","Claude host adapter contract fixture for Launchdeck.","https:\u002F\u002Fgithub.com\u002Fchenziyang110\u002Flaunchdeck\u002Fblob\u002Fmain\u002Ftest\u002Ffixtures\u002Fagent-hosts\u002Fclaude\u002Fskill\u002FSKILL.md",[],[],{"skillNo":61,"name":49,"nameZh":6,"description":62,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":63,"categories":64,"keywords":65,"publishedAt":19},"01M78759JQ7A6FQ8KDQTNYS3X9","Use this skill aggressively for local project lifecycle operations even when the user does not mention Launchdeck: start this project, run the dev server, dev, build, test, restart service, stop service, show logs, inspect ports, port is occupied, clean cache; and when the user explicitly asks to configure this local project for Launchdeck or create or generate a project-adapted `.launchdeck.yml`, including 为这个项目生成 Launchdeck 配置. Do not use for ordinary code edits, docs-only work, general explanations, API design discussion, or production deployment unless the user also asks to operate or configure a local project or service.","https:\u002F\u002Fgithub.com\u002Fchenziyang110\u002Flaunchdeck\u002Fblob\u002Fmain\u002Fagent\u002Finstaller-payload\u002Fskill\u002Flaunchdeck-agent\u002FSKILL.md",[],[],{"skillNo":67,"name":68,"nameZh":6,"description":69,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":70,"categories":71,"keywords":72,"publishedAt":19},"01M78753ZJQ7G2CZT1W1G8WRJV","zig-testing","Use ONLY when user explicitly requests Zig test code, built-in test runner configuration,\ntest failure diagnosis, or coverage for Zig projects.\n\nTriggers: \"write test zig\", \"zig test\", \"testing.allocator\", \"zig coverage\",\n\"comptime test\", \"zig expectError\", \"zig snapshot test\", \"zig fuzz\".\n\nDo NOT activate for: general Zig coding without test context, build.zig configuration\nfor non-test targets, Zig compiler errors, or Zig build system setup.","https:\u002F\u002Fgithub.com\u002Fchenziyang110\u002Flaunchdeck\u002Fblob\u002Fmain\u002F.specify\u002Ftemplates\u002Fpassive-skills\u002Fzig-testing\u002FSKILL.md",[],[],{"skillNo":74,"name":75,"nameZh":6,"description":76,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":77,"licenseFileUrl":78,"sourceHtmlUrl":79,"categories":80,"keywords":81,"publishedAt":19},"01M78750JXY4Z5D5W1EX3PQ31Z","webapp-testing","Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fchenziyang110\u002Flaunchdeck\u002Fblob\u002Fmain\u002F.specify\u002Ftemplates\u002Fpassive-skills\u002Fwebapp-testing\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fchenziyang110\u002Flaunchdeck\u002Fblob\u002Fmain\u002F.specify\u002Ftemplates\u002Fpassive-skills\u002Fwebapp-testing\u002FSKILL.md",[],[],{"skillNo":83,"name":84,"nameZh":6,"description":85,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":86,"categories":87,"keywords":88,"publishedAt":19},"01M7874X2T83EQQFRCEY5SJJVC","verification-before-completion","Use when about to claim work is complete, fixed, or passing, before committing or creating PRs - requires running verification commands and confirming output before making any success claims; evidence before assertions always","https:\u002F\u002Fgithub.com\u002Fchenziyang110\u002Flaunchdeck\u002Fblob\u002Fmain\u002F.specify\u002Ftemplates\u002Fpassive-skills\u002Fverification-before-completion\u002FSKILL.md",[],[]]