Documentation

Testing Walnut apps

Tests are Walnut programs, not a side language. The Test module (stdlib) lets you build suites and run them on the host via walnut test. No Simulator required.

Live Simulator probing (dispatch / p model) remains walnut debug — useful for integration, separate from unit tests.

Quick start

walnut test

Discovers tests/**/*.walnut under the app. Each file exposes script main that prints a Test.Report:

module Smoke exposing (main)

import Main exposing (init, update, Msg(..))
import Test exposing (..)


main =
    format
        (run
            (describe "Counter"
                [ test "Increment"
                    (equalInt 1 (update Increment init).count)
                ]
            )
        )

API (import Test exposing (..))

FunctionRole
test name expectationSingle case
describe name [ … ]Nested suite
concat [ … ]Suite with empty label
equal / equalInt / equalFloat / true / false / pass / failExpectations
run suiteWalk the tree → Report
format reportHuman text (ok — N passed or FAILED …)

equal compares via Debug.toString (no Eq typeclass yet). Prefer equalInt / equalFloat when you can.

equalFloat expected actual epsilon passes when abs (actual - expected) <= epsilon.

Full Test module docs: documentation.md and the generated API site.

How walnut test works

  1. Find test modules (tests/**/*.walnut or paths you pass).
  2. Load only the import closure of each test from src/ (skips shipping unused Persist/HTTP into the JIT).
  3. Typecheck and run the test module’s main on the host.
  4. Print the report; exit non-zero if the text contains FAILED.

Stdlib modules (Test, Ui, …) come from the toolchain bundle (stdlib.md).

Layout

Put suites under tests/ in your app (or pass file paths):

walnut test
walnut test tests/Smoke.walnut

Limits

  • Runs on the host (not on-device).
  • Prefer small fixtures that import only what the test needs.
  • Simulator probing is not the unit-test path — use debug.md for that.