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
# Run all tests
nix flake check
# List available tests
nix eval .#checks.x86_64-linux --apply builtins.attrNames
There is no way to run a single test in isolation — nix flake check runs them all.
Test structure
tests/
default.nix # Entry point combining all tests
module-tests.nix # Module evaluation tests
lib-tests.nix # Library function unit tests
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
Unit tests for lib functions using the assertTest helper.
Writing tests
Module evaluation test
Add to tests/module-tests.nix:
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
Add to tests/lib-tests.nix:
test-my-function = pkgs.runCommand "test-my-function" { } ''
result=$(nix eval --raw --expr '(import ../lib { inherit (pkgs) lib; }).myFunction "input"')
[[ "$result" == "expected" ]] || exit 1
touch $out
'';
CI pipeline
The GitHub Actions workflow (.github/workflows/validate.yml) runs three stages:
- Lint —
nix fmt -- --ci plus a flake.lock / devenv.lock rev-parity check on a single Linux runner.
- Check —
nix flake check --accept-flake-config matrix across x86_64-linux, aarch64-linux, and aarch64-darwin.
- Build —
nix build .#nixosConfigurations.x86_64.config.system.build.toplevel (runs after lint and check pass).
Stages 1 and 2 run in parallel; stage 3 runs after both succeed. Concurrency groups cancel superseded PR runs automatically. Builds use Cachix (jylhis cache).
A separate .github/workflows/pages.yml workflow deploys the docs to GitHub Pages, scoped via path filters to docs/** and flake sources so unrelated commits don’t trigger redeploys. Last modified on April 24, 2026