Testing
Tests in Marchyo are fast evaluation-based checks that verify NixOS configurations evaluate without errors. They don’t build any derivations, so they complete in under a minute.
Running tests
Section titled “Running tests”# Run all testsnix flake check
# List available testsnix eval .#checks.x86_64-linux --apply builtins.attrNamesThere is no way to run a single test in isolation — nix flake check runs them all.
Test structure
Section titled “Test structure”tests/ default.nix # Entry point — auto-discovers tests/eval/ and merges the results lib.nix # Shared helpers (assertTest, testNixOS, withTestUser, …) lib-tests.nix # Library function unit tests eval/ # Per-feature module tests, auto-discovered (one file per feature)Module tests
Section titled “Module tests”Verify that NixOS configurations evaluate without errors for various feature combinations:
| Test | Description |
|---|---|
eval-minimal |
Minimal NixOS modules import |
eval-desktop |
Desktop feature flag |
eval-development |
Development feature flag |
eval-all-features |
All features enabled together |
eval-themes |
Theme configurations |
eval-keyboard |
Keyboard layouts and IME |
eval-graphics-* |
GPU configurations (Intel, AMD, NVIDIA, PRIME) |
Library tests
Section titled “Library tests”Unit tests for lib functions using the assertTest helper.
Writing tests
Section titled “Writing tests”Module evaluation test
Section titled “Module evaluation test”Create (or extend) a file under tests/eval/ — e.g. tests/eval/my-feature.nix. Each file is a function that receives the shared helpers and returns an attrset of named tests; it is auto-discovered, so no registration is needed:
{ helpers, ... }:let inherit (helpers) testNixOS withTestUser;in{ eval-my-feature = testNixOS "my-feature" (withTestUser { marchyo.myFeature.enable = true; });}The testNixOS helper evaluates the NixOS config without building derivations. The withTestUser helper merges your config with a minimal bootable config (grub disabled, root filesystem, stateVersion).
Library test
Section titled “Library test”Add to tests/lib-tests.nix, using the assertTest helper from tests/lib.nix (assertTest name assertion message — fails at evaluation time when the assertion is false):
test-my-function = let result = lib.myFunction "input"; in assertTest "my-function" (result == "expected") "Expected myFunction to transform input";CI pipeline
Section titled “CI pipeline”The GitHub Actions workflow (.github/workflows/validate.yml) runs four jobs:
- Lint —
nix fmt -- --ciplus aflake.lock/devenv.lockrev-parity check on a single Linux runner. Runs on every push and PR. - Check —
nix flake check --accept-flake-configonx86_64-linux. Runs on every push and PR. - Check (aarch64-linux) — the same checks on an ARM runner. Runs only on pushes to
mainand manual dispatch. - Build —
nix build .#nixosConfigurations.x86_64.config.system.build.toplevel. Runs only on pushes tomainand manual dispatch, after lint and check succeed.
Lint and check run in parallel. Concurrency groups cancel superseded PR runs automatically. Builds use Cachix (jylhis cache).
A separate .github/workflows/site.yml workflow is a build-only gate for the website: changes touching site/** run bun run check and bun run build. Deployment happens outside GitHub Actions — Cloudflare Workers Builds deploys the site to marchyo.org on push to main.