Skip to content
Back to skills

Ceedling Build Runner

ASecurity

Author and run the Ceedling build system for C unit testing - the canonical build orchestration on top of Unity (assertions) + CMock (mocks) + CException (exceptions). Covers ceedling new scaffolding, the project.yml schema (:project / :paths / :files / :defines / :flags / :tools / :test_runner / :cmock / :unity / :cexception / :gcov / :plugins), the task surface (test:all, test:{name}, test:pattern, test:path, release, clean / clobber, gcov:all, module:create, environment, dumpconfig), JUnit...

  • 10 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 12, 2026
testinggorubyc++bashtestinggitapidocumentation

Works with

  • api

Security analysis

A100/100

Pro scans all 5 files and shows the line behind each finding

Scanned October 12, 2026

npx -y skills add testland/qa --skill ceedling-build-runner --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Ceedling Build Runner?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Ceedling Build Runner
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/testland-ceedling-build-runner/badge)](https://www.skillsdirectory.com/skills/testland-ceedling-build-runner)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: ceedling-build-runner
description: "Author and run the Ceedling build system for C unit testing - the canonical build orchestration on top of Unity (assertions) + CMock (mocks) + CException (exceptions). Covers ceedling new scaffolding, the project.yml schema (:project / :paths / :files / :defines / :flags / :tools / :test_runner / :cmock / :unity / :cexception / :gcov / :plugins), the task surface (test:all, test:{name}, test:pattern, test:path, release, clean / clobber, gcov:all, module:create, environment, dumpconfig), JUnit XML via the report_tests_* plugins, gcov integration, host vs cross-build flow, and CI wiring. CMock semantics - the generated Expect / Ignore / IgnoreArg / ReturnThruPtr / AddCallback / Stub / ExpectAndThrow family, cmock.yml :plugins, mock naming, tearDown verification, strict-vs-ignore matching - are in references/cmock.md. Use when a C project wants the ThrowTheSwitch trio bundled by one build command, or when authoring / reading CMock mocks. For the Unity assertion API see unity-test-framework-c."
metadata:
  keywords: "ceedling, unity, cmock, cexception, c, embedded, rake, throwtheswitch"
  version: "1.3.10"
---

# ceedling-build-runner

## Overview

This skill covers the Ceedling build orchestration - the
`ceedling` command-line tool, `project.yml` schema, and rake
tasks, per
[throwtheswitch.org/ceedling](https://www.throwtheswitch.org/ceedling).
For the Unity assertion API see `unity-test-framework-c`; for
CMock's generated mock API see [references/cmock.md](references/cmock.md);
for cross-target run see `qemu-system-test-runner`; for coverage see
`embedded-coverage-strategy-reference`.

## When to use

- C unit-test project - Ceedling is the canonical setup for the
  ThrowTheSwitch stack.
- Host-build-driven test loop (most embedded teams test on the
  host first, then cross-compile under
  `qemu-system-test-runner`) - Ceedling handles the host pipeline natively.
- Coverage required - the bundled gcov plugin produces LCOV /
  HTML / Cobertura without external glue.
- Mock-heavy module - CMock is integrated; no separate generator
  invocation needed.

If the unit-under-test is C++ instead of C, prefer
`googletest-embedded-arm`;
Ceedling does not target C++.

## Authoring

### Scaffolding a new project

Per the Ceedling README and the command-line reference at
[github.com/ThrowTheSwitch/Ceedling/.../getting-started/command-line.md](https://github.com/ThrowTheSwitch/Ceedling/blob/master/docs/mkdocs/getting-started/command-line.md):

```bash
gem install ceedling
ceedling new my-firmware --docs --local
cd my-firmware
```

`--docs` includes the documentation locally; `--local` vendors
Unity / CMock / CException into `vendor/ceedling/` so the build
doesn't need network at compile time. The generated layout:

```
my-firmware/
  project.yml          # the schema covered below
  src/                 # production code under test
  test/                # one test_<module>.c per module
  test/support/        # shared test helpers
  build/               # generated; gitignore'd
  vendor/ceedling/     # bundled Unity + CMock + CException
```

### project.yml

A minimal project.yml for a host test loop:

```yaml
:project:
  :build_root: build/
  :use_mocks: TRUE
  :test_file_prefix: test_
:paths:
  :test:
    - test/**
  :source:
    - src/**
  :include:
    - inc/**
:plugins:
  :enabled:
    - report_tests_pretty_stdout
    - report_tests_junit_xml
    - gcov
```

The full schema (every top-level section, test vs release
`:flags`, the `:cmock` / `:cexception` / `:gcov` blocks, per-section
notes, and the plugin list) is in
[references/project-yml-schema.md](references/project-yml-schema.md).

### Creating a module

```bash
ceedling module:create[ringbuffer]
# Creates src/ringbuffer.c, src/ringbuffer.h, test/test_ringbuffer.c
```

The generator emits the canonical skeleton - production header /
source with includes wired, test file with `setUp` / `tearDown` /
one `test_ringbuffer_NeedToImplement` placeholder.

## Running

```bash
ceedling test:all         # Run every test_*.c
ceedling test:ringbuffer  # Run only test_ringbuffer.c
ceedling gcov:all         # Run under gcov instrumentation + generate report
```

`ceedling test:all` returns non-zero on any test failure; CI
gates on the exit code. `gcov:all` writes
`build/artifacts/gcov/GcovCoverageResults.html` (HtmlDetailed) or
`GcovCoverageCobertura.xml` (Cobertura) - see
`embedded-coverage-strategy-reference`.

The canonical CI invocation chains tasks on one command line:

```bash
ceedling clobber test:all release gcov:all
# Clean -> run tests -> build release -> produce coverage report
```

The full task surface (`test:pattern`, `test:path`,
`--test-case`, `release`, `clean` / `clobber`, `environment`,
`dumpconfig`) is in
[references/task-reference.md](references/task-reference.md).

## Parsing results

### Pretty stdout output

```
-------------------
OVERALL TEST SUMMARY
-------------------
TESTED:  47
PASSED:  46
FAILED:   1
IGNORED:  0
```

Failures are reported per assertion with file:line:test:reason:

```
test/test_ringbuffer.c:48:test_overflow_returns_minus_one:FAIL: Expected -1 Was 0
```

### JUnit XML

With `report_tests_junit_xml` enabled, `ceedling test:all` writes
`build/artifacts/test/report.xml` in the canonical JUnit schema - 
the same one GoogleTest produces, so the same CI pipeline plugin
(GitHub `mikepenz/action-junit-report`, GitLab JUnit, Jenkins
JUnit) consumes both.

## CI integration

```yaml
jobs:
  ceedling-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - name: Setup Ruby + Ceedling
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.2'
      - run: gem install ceedling
      - name: Run tests + coverage
        run: ceedling clobber test:all gcov:all
      - name: Publish JUnit
        if: always()
        uses: mikepenz/action-junit-report@v4
        with:
          report_paths: 'build/artifacts/test/*.xml'
      - name: Publish coverage
        uses: codecov/codecov-action@v5
        with:
          files: build/artifacts/gcov/GcovCoverageCobertura.xml
```

For a cross-compile path (host build for CI, ARM build for
hardware-in-loop) the recipe is: keep two `project.yml` files
(`project.yml` for host, `project-arm.yml` for ARM) and pass
`--project=project-arm.yml` for the ARM build. The ARM build's
`:tools:` overrides the compiler to `arm-none-eabi-gcc` and the
results route through `qemu-system-test-runner`.

## Anti-patterns

| Anti-pattern | Why it fails | Fix |
|---|---|---|
| Editing the generated `*_Runner.c` files | Regenerated on every build; edits lost | Edit the source `test_*.c`; the runner is derived |
| `:enforce_strict_ordering: FALSE` to "make tests pass" | Mock-call-order bugs become invisible | Keep `:enforce_strict_ordering: TRUE`; fix the SUT's call shape |
| Commit `build/` artifacts | Repo bloat; merges conflict on generated files | `.gitignore build/` always |
| Skipping `ceedling clobber` in CI | Stale mocks survive header changes; ghost test failures | Always `clobber` before the CI run |
| Mixing test compile flags with release flags | `--coverage` in release build inflates the binary | Keep `:flags: :test:` separate from `:flags: :release:` |
| Naming a test file `_test.c` instead of `test_*.c` | Default `:test_file_prefix: test_` won't pick it up | Match the prefix or change the project.yml setting |
| Using `:use_mocks: FALSE` then including a `Mock*.h` | CMock isn't invoked; link fails on the mock symbol | Either enable mocks globally or use Ceedling's `--mocks` runtime flag |
| Hardcoding the build directory in scripts | `:build_root` is project.yml-driven; scripts break on rename | Read it from `ceedling environment` |

## Limitations

- **Ruby dependency.** Ceedling runs on Ruby; embedded teams
  without a Ruby toolchain have an adoption cost.
- **C only.** No C++ support - for C++ pair
  `googletest-embedded-arm`
  with CMake.
- **Per-file flag overrides are verbose.** The `:flags` schema's
  glob keys are powerful but error-prone - `dumpconfig` is the
  only reliable verifier.
- **No native parallel test execution.** Each `test_*` runs
  serially. Parallelise across multiple `test:path[...]` jobs in
  CI if needed.
- **Plugin discovery is path-sensitive.** Custom plugins must
  live under `:plugins: :load_paths:` in project.yml. Ceedling's
  error messages on missing plugins are terse.
- **gcov plugin reports are coupled to host-built coverage.**
  For on-target coverage, write a custom plugin or feed gcovr
  manually after a QEMU run.

## References

Cited inline. Foundational documents:

- Ceedling repository - [github.com/ThrowTheSwitch/Ceedling](https://github.com/ThrowTheSwitch/Ceedling).
- Ceedling overview - [www.throwtheswitch.org/ceedling](https://www.throwtheswitch.org/ceedling).
- Ceedling docs (project.yml + task reference) - [throwtheswitch.github.io/Ceedling/latest](https://throwtheswitch.github.io/Ceedling/latest/).
- CMock semantics (generated API surface, cmock.yml plugins,
  lifecycle, matching modes): [references/cmock.md](references/cmock.md).
- Sibling skills:
  `unity-test-framework-c`,
  `embedded-coverage-strategy-reference`,
  `qemu-system-test-runner`,
  `googletest-embedded-arm`.

Files in this skill

  • .tessl-plugin/plugin.json1.1 KB
  • SKILL.md9.1 KB
  • references/cmock.md10.5 KB
  • references/project-yml-schema.md2.5 KB
  • references/task-reference.md1.6 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.