Skip to content

Unit & integration tests

Unit and integration tests run on Vitest in a jsdom environment. Test files sit colocated next to the source they test — either right beside it (TabBar.tsx / TabBar.test.tsx) or in a colocated __tests__/ subfolder. Both styles exist in the codebase; either is fine for new tests.

Every test run loads tests/setup.ts, which:

  • Mocks @/lib/shared/dexie-storage so every Dexie table adapter (collections, environments, history, settings, and more) is an async no-op — jsdom has no IndexedDB, and Zustand’s persist middleware would otherwise fire real async I/O and throw after teardown.
  • Registers React Testing Library’s cleanup() in afterEach.
  • Imports @testing-library/jest-dom/vitest for matcher extensions (toBeInTheDocument(), etc.).
  • Installs an in-memory localStorage mock and stubs window.matchMedia and global.ResizeObserver.

Import describe/it/expect from vitest and render/screen/fireEvent from @testing-library/react. Pull the component and any Zustand store directly through the @/ alias, and reset store state in beforeEach. Assert with RTL queries (getByRole, queryByLabelText, and similar) and, where it’s simpler, direct store-state assertions.

ScriptWhat it does
npm run testVitest interactive mode
npm run test:runSingle run, no watch
npm run test:watchWatch mode
npm run test:uiVitest’s browser UI dashboard
npm run test:coverageCoverage report