Files
cproof-context/playbooks/add-test.md
jabber.developer2 22977846a3 docs: split context into layered, agent-oriented files
Replace the single file-structure.md with a stratified layout designed
for AI/agent skill consumption: tables and concrete identifiers over
prose, files loaded on demand, content separated by churn rate.

Layers:
- architecture/  stable structural reference (overview, source-map,
                 test-map, data-flow)
- patterns/      memory, commands, autocomplete, events, xmpp,
                 encryption, ui, plugins
- testing/       unit-tests, stubs, functional-tests, bench
- build/         local, docker, ci
- playbooks/     add-command, add-test, add-autocomplete,
                 add-event-handler, add-encryption
- gotchas.md     append-only dated entries (seven seed entries)
- wip/           branch-specific notes; deleted on merge to master

Stable layers describe cproof on master only. In-flight feature
branches (currently feat/ai) get a single file under wip/.

INDEX.md is the entry map with churn labels; SKILL.md is the
always-loaded skill hint pointing to it.
2026-04-30 20:52:06 +03:00

98 lines
2.4 KiB
Markdown

# Playbook: add a unit test file
Recipe for a new `tests/unittests/test_<topic>.c` + `.h` pair.
## 1. Create the header
`tests/unittests/test_<topic>.h`:
```c
#ifndef TEST_<TOPIC>_H
#define TEST_<TOPIC>_H
void test_<topic>_<scenario_1>(void** state);
void test_<topic>_<scenario_2>(void** state);
#endif
```
One declaration per test function. Headers exist solely so `unittests.c` can
include them and reference each function symbol.
## 2. Create the source
`tests/unittests/test_<topic>.c`:
```c
#include "config.h"
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include "test_<topic>.h"
// ... includes for the unit under test and any types it needs ...
void
test_<topic>_<scenario_1>(void** state)
{
// Arrange — `will_return`, `expect_string`, etc.
// Act — call the unit
// Assert — `assert_*`
}
```
## 3. Register in `unittests.c`
```c
#include "test_<topic>.h"
// inside the tests[] array passed to cmocka_run_group_tests:
cmocka_unit_test(test_<topic>_<scenario_1>),
cmocka_unit_test(test_<topic>_<scenario_2>),
```
If multiple tests share fixture, add a setup / teardown pair and use
`cmocka_unit_test_setup_teardown` (or define a per-topic macro near the top
of `unittests.c`, like `muc_unit_test`).
## 4. Stubs
For each external function the unit calls, ensure a stub exists in the
matching `tests/unittests/<module>/stub_*.c`. Three flavours:
- **Pass-through** — no observation needed.
- **`mock()` / `will_return`** — test injects return values.
- **`check_expected()` / `expect_*`** — test asserts arguments.
See `testing/stubs.md`.
## 5. Wire into Make
`tests/unittests/Makefile.am` (or the active wiring file): add
`test_<topic>.c` to the `unittests_SOURCES` (or equivalent) list. Same for
any new stub file.
## 6. Build & run
Inside Docker:
```sh
./autogen.sh && ./configure && make -j$(nproc) check
```
Diagnose failures via `tests/unittests/unittests.log` and the cmocka stderr
output.
## 7. Conventions
- Test functions: `test_<topic>_<scenario>` — never `test_topic1`,
`test_topic2`. Names should describe the scenario.
- One assertion focus per test (multiple `assert_*` calls are fine; multiple
*unrelated* assertions are not).
- Don't reuse stubs across topic suites unless the call truly is uniform —
diverging behaviour is a strong sign you want a dedicated stub.
- No I/O in unit tests. Filesystem, network, ncurses are all stubbed.