# Testing conventions > How Rust tests are laid out across the host-testable crates (`editor`, > `keymap`, `display`). All of these build and run off the xtensa target — > the firmware itself is exercised on hardware, not `cargo test`. > > Project overview: [`../README.md`](../README.md) · doc index: > [`README.md`](README.md). ## Two shapes, chosen by what the test exercises **Unit tests live in the source file.** A `#[cfg(test)] mod tests` block at the bottom of the `.rs` file. It compiles only under `cargo test` (zero cost in the shipped binary — which matters on a 16 MB part), and it gets private access to the module it sits in. This is the default. `keymap/src/lib.rs` is the worked example: 28 tests inline under the decoder they cover. **Behavioural tests live in a `src/tests/` submodule.** When a test drives the _whole_ `Editor` through `Key` events and asserts on private state — rather than calling one function in isolation — it isn't really a unit test of any single module. Those go in a `#[cfg(test)] mod tests;` **directory**, one file per theme. The `editor` crate is laid out this way. ## The `editor` crate's `src/tests/` - [`mod.rs`](../editor/src/tests/mod.rs) is the sole `#[cfg(test)] mod tests;` (declared at the bottom of [`lib.rs`](../editor/src/lib.rs)). It holds **every shared helper** (`typed`, `command`, `kinds`, `over`, `palette_editor`, …) and the fixture consts, and it re-exports the crate root with `pub(crate) use crate::*;` so each theme file reaches `Editor`, `Key`, `Effect`, … through a single `use super::*;`. - Each theme file (`editing.rs`, `visual.rs`, `palette.rs`, `search.rs`, …) is just `#[test]` fns plus that one `use super::*;`. No file re-imports the crate root directly. Adding a test: 1. Put it in the theme file matching the surface it exercises. A test that spans surfaces (e.g. edit → format → publish) goes with its _primary_ intent. 2. Need a helper used by more than one theme? Add it to `mod.rs`. A helper used by a single theme may stay in that theme file. 3. New theme? Add `mod ;` to `mod.rs` and a `//!` one-liner to the file. ## What we deliberately don't use - **The top-level `tests/` integration directory.** That dir only sees a crate's public API. The editor's tests read private state (`e.text`, `e.caret`, `e.mode()`), so they must stay in-crate under `#[cfg(test)]`. Reach for `tests/` only to pin a crate's _public_ contract. - **Doctests** for the embedded core. Fine for documenting a public API, but slow and awkward here; the behaviour is covered by the tests above. ## Running them No cargo workspace ties the crates together, so run per crate from its own directory: ```sh cd editor && cargo test # 224 tests cd keymap && cargo test # 28 tests ```