Testing
Quick Start
# Rust (Backend + TUI/CLI)cargo nextest run # All testscargo nextest run --run-ignored all # Include E2E testscargo nextest run -E 'test(/pattern/)' # Filter by patternmise run test-fast # via mise
# Webcd web && bun run test
# Mobilecd mobile && bun test
# CI simulationdagger call ciRust
Organization
tests/— Integration and E2E tests (24 files)src/— Unit tests with#[cfg(test)](colocated)
Install nextest: mise run setup-tools
Frameworks
tokio-test, proptest, tempfile, assert_cmd, predicates
Patterns
Unit tests (colocated):
#[cfg(test)]mod tests { use super::*; #[test] fn test_function() { /* ... */ }}Conditional E2E (skip when Docker unavailable):
#[tokio::test]#[ignore]async fn test_docker_session() { skip_if_no_docker!(); // ...}Mocks: MockGitBackend, MockApiClient in src/backends/mock.rs
Test Helpers (tests/common/mod.rs)
docker_available()— dependency checkskip_if_no_docker!()— graceful skipinit_git_repo(path)— git repo setup
Web (TypeScript/React)
Organization
9 test files across web/frontend/src/ and web/client/src/
cd web && bun run test # allcd web/frontend && bun test # frontend onlycd web/client && bun test # client onlyUses Bun’s native bun:test runner.
Patterns
import { describe, test, expect } from "bun:test";describe("Component", () => { test("should work", () => { /* ... */ });});Browser API mocks (localStorage, matchMedia): ThemeToggle.test.tsx
WebSocket mocks (controlled state): ConsoleClient.test.ts
Async timing: await new Promise(resolve => setTimeout(resolve, 0))
Mobile (React Native)
1 test file: mobile/src/lib/historyParser.test.ts
cd mobile && bun testcd mobile && bun test:windowsUses Jest with @rnx-kit/jest-preset. Infrastructure ready for component tests (react-test-renderer installed).
CI/CD
Dagger pipeline (/.dagger/src/index.ts, clauderonCi function):
- Build docs (
bun run build) - Build web (
bun run build) - Build Rust (
cargo build) - Clippy (
cargo clippy) - Tests (
cargo nextest run) - Release artifacts
Caches: Cargo registry, git deps, target dir, sccache.
dagger call ciTroubleshooting
| Problem | Solution |
|---|---|
| nextest not found | mise run setup-tools |
| Tests fail in CI, pass locally | Check Docker: docker ps; E2E tests skip gracefully |
| E2E tests always skip | Expected without Docker; run with --run-ignored all |
| Web test timing issues | Use await new Promise(resolve => setTimeout(resolve, 0)) |