We test to ensure code works correctly and stays working as changes are made.
| Tool | Used For |
|---|---|
| Vitest | Testing everything (packages & apps) |
| React Native Testing Library | Component testing (via Vitest/React) |
pnpm test # Run all tests
pnpm --filter mobile test # Mobile app tests onlyTests are colocated with source code in __tests__/ folders:
src/hooks/
├── useToast.ts
└── __tests__/
└── useToast.test.ts
Focus on:
- Zustand store updates
- Data transformation functions
- Hook behavior (with
renderHook) - Error handling
Focus on:
- User interactions (button presses, form inputs)
- Conditional rendering
- Critical user flows
Avoid:
- Snapshot tests for complex components
- Testing third-party library behavior
- File Naming: Use
.spec.tsxextension. - Behavior Only: Test interactions (presses, inputs) and conditionals. Do not test static text rendering.
- AAA Pattern: Structure tests with Arrange, Act, Assert comments.
- Naming: Use
it('does something when event happens'). - Atomicity: Tests must be independent and self-contained. Setup dependencies inside the test or
beforeEach.
import { render, fireEvent, screen } from '@test-utils/render'
// ✅ Good Example
it('submits form when save is pressed', () => {
// Arrange
const onSave = vi.fn()
render(<UserForm onSave={onSave} />)
// Act
fireEvent.click(screen.getByText('Save'))
// Assert
expect(onSave).toHaveBeenCalled()
})Test behavior, not implementation.
Ask: "What should happen when the user does X?" rather than "Does internal method Y get called?"
For detailed test patterns and examples, see the development workflows.