NC Anima · Docs

Testing

cargo test --workspace     # everything
cargo xtask ci             # fmt, clippy -D warnings, tests, layers, assets, wasm

cargo xtask ci builds in the dev profile and runs the tests with cargo nextest run (plus cargo test --doc) when cargo-nextest is installed, and with cargo test otherwise. It then runs missing_translations_report with --nocapture, which prints the interface strings each language has no translation for. Those strings show in English; the report always passes.

Each crate with several integration-test files has one test binary, tests/it/main.rs, whose modules are the files in tests/it/. Run one file with cargo test -p <crate> --test it <module>:: or cargo nextest run -p <crate> -E 'binary(it) and test(/^<module>::/)'.

What the tests cover

Looking at the interface without a window

cargo run -p anima-ui-egui --example snapshot -- --out ui.png \
  --step '{"method":"engine.execute","params":{"command":"layer.select","params":{"layers":["#2"]}}}'

Each --step is a control-channel request; {"method":"snap","params":{"path":"x.png"}} writes an intermediate image.

Benchmarks

cargo run --release -p anima-cli -- bench --n 10 --play 30

prints per-layer and per-effect timings for one frame, and playback timings with and without the layer cache.

Render benchmark (cargo xtask bench)

nice -n 10 cargo xtask bench --bin target/release/anima-cli   # or no --bin: one `--release` build into target/bench
nice -n 10 cargo xtask bench --quick --compare before.jsonl        # 8 frames instead of 60, % change against an earlier run
cargo xtask bench --project F.ecproj --comp "Main"                 # any project's comp

measures memory, CPU and wall time of whole anima-cli runs, so every optimisation has a before and after number. It generates four deterministic scenarios into target/bench/projects with engine commands (no committed media): demo (the built-in demo comp), layers (1080p, 100 solid, text and shape layers with Gaussian Blur, Glow, Levels, Curves, Drop Shadow and keyframes), precomps (static and animated precomps nested three deep, each used several times) and footage (a rendered PNG sequence and H.264 clip on several 1080p layers, plus a 4K still). Each is opened (open), rendered at Full and Half (PNG sequence, deleted afterwards) and as one frame. /usr/bin/time -l on macOS gives peak memory footprint, max RSS, user + sys CPU and instructions retired; /usr/bin/time -v on Linux gives max RSS and CPU; elsewhere wall time only.

It prints a table and appends one JSON line per run to target/bench/results.jsonl (git rev, date, load average, scenario, settings, metrics); --compare OLD.jsonl prints the % change against the latest matching runs there, --compare OLD --with NEW compares two files without rendering. --repeat N runs every scenario N times; with N > 1, one "kind": "summary" line per key follows the runs. Its metrics are the medians of the successful runs (byte and instruction counts rounded), summary holds runs, failed and median/p90/min/max per metric (p90 is the nearest rank, so it equals the max for N < 10), and its other fields (date, load, ...) are those of the key's last run; scripts that average runs should skip kind: summary lines. One failed run marks the summary failed. Comparisons use the latest line per key, so a key is a median only if its summary is the latest line (a later single run, or a batch that aborted before its summaries, leaves a raw run latest). The table labels each side median of N or 1 run and warns when they differ; --fail-over refuses such keys. The table notes the 1-minute load average: on a busy machine wall time is noise, so compare peak memory and instructions retired, and rerun when the load differs a lot.

Results files allow blank lines; corrupt records or invalid comparison fields report the file and line instead of being discarded. --fail-over PCT requires the same run keys on both sides, successful latest runs, and at least one comparable resource metric per run. Failed latest runs, missing coverage, empty results and wall-time-only measurements cannot pass the gate. Omit --fail-over for an exploratory partial comparison; failed latest runs remain visible.