Skip to content

Testing and quality

Molt’s GitHub Actions CI runs three independent jobs on macos-latest for pushes and pull requests targeting main.

From the repository root:

Terminal window
npm run check
cargo fmt --manifest-path src-tauri/Cargo.toml --check
cargo clippy --locked --manifest-path src-tauri/Cargo.toml --all-targets -- -D warnings
cargo test --locked --manifest-path src-tauri/Cargo.toml
.venv/bin/python -m pytest tests/python/ -q

Run all commands when a change crosses layer boundaries.

Terminal window
cargo clippy --locked --manifest-path src-tauri/Cargo.toml --all-targets -- -D warnings

CI treats every Clippy warning as an error.

Terminal window
cargo test --locked --manifest-path src-tauri/Cargo.toml

The selected release includes configuration unit tests for:

  • Complete defaults.
  • Custom interpreter parsing.
  • Empty TOML defaults.
  • Partial-section defaults.
  • Native-effects parsing.
  • Ignoring the legacy theme field.

Rust subprocess tests exercise startup handshakes, per-tab ownership, concurrent startup, FIFO lifecycle behavior, stop/restart, recoverable interrupts, force-kill fallbacks, stderr draining, and atomic storage replacement.

Install pytest into a development environment and run:

Terminal window
python3 -m pytest tests/python/ -v

CI uses Python 3.12. The suite starts a fresh kernel_server.py process per test and verifies:

  • Ping response.
  • Simple stdout execution.
  • Namespace persistence across requests.
  • Exception capture.
  • Stderr capture.
  • Namespace reset through the protocol restart message.
  • Unknown request types.
  • Malformed JSON.

The suite also verifies SystemExit capture, noninteractive stdin, request-shape validation, the __main__ namespace, and protocol recovery. Rich output remains outside the protocol.

Terminal window
npm run typecheck

Runs the TypeScript build in no-emit mode.

Terminal window
npm run lint

Runs ESLint across the repository’s configured frontend files.

Terminal window
npm run test

The store suite covers initialization, tab changes, cell insertion and deletion, reordering, source updates, cell state and output updates, execution counters, persisted-state restoration, clear behavior, command-mode state, and no-op update guards.

Execution, persistence, hook, toolbar, and store suites cover tab reservations, Run All stopping, stale-result cancellation, load validation, serialized saves, visible errors, and notebook mutations.

Automated tests do not fully cover native Tauri behavior. For relevant changes, verify:

  1. Main and settings windows open and focus correctly.
  2. Native effects apply and clear without losing readability.
  3. A configured interpreter launches the bundled resource.
  4. Separate tabs retain isolated namespaces.
  5. Run All is sequential.
  6. Stop blocks subsequent execution until Restart.
  7. Restart clears live variables and rendered outputs.
  8. Interrupt behavior is recoverable through Restart.
  9. Notebook source restores after app relaunch.
  10. All child Python processes terminate on app quit.
  11. Gatekeeper behavior is understood on an unsigned local bundle.
  12. The DMG build completes in the intended GUI or CI environment.
Change Minimum tests
Cell/store mutation Vitest store test
React control behavior Testing Library component test
Tauri invoke wrapper or response mapping Frontend test with invoke mock plus Rust contract review
TOML field Rust parse/default/save tests and settings UI test
Kernel protocol Python subprocess test and Rust deserialization test
Process lifecycle Rust async test where feasible plus macOS integration check
Persistence schema Frontend load/save tests, malformed-data test, migration behavior
Window/menu/native effect macOS Tauri integration check
  • Jobs cancel in-progress runs for the same Git reference.
  • Rust dependency caching uses Swatinem/rust-cache with src-tauri as the workspace.
  • Frontend installation uses npm ci with the committed lockfile.
  • CI validates code but does not produce release artifacts; the release workflow is separate.