npm installThis will install:
- Vitest 2.1.8 (test runner)
- @testing-library/react 16.1.0 (React testing utilities)
- @playwright/test 1.49.1 (E2E testing)
- happy-dom 15.11.7 (fast DOM environment)
- msw 2.7.0 (API mocking)
- And more...
# Run all tests
npm test
# Run tests in watch mode (recommended for development)
npm run test:watch
# Run with coverage
npm run test:coverage
# Run with UI (visual test runner)
npm run test:uiYou should see output like:
β src/renderer/utils/logger.test.ts (5 tests)
β src/renderer/components/auth/Button.test.tsx (9 tests)
β src/renderer/stores/environmentStore.test.ts (15 tests)
β src/renderer/components/notebook/ErrorBoundary.test.tsx (13 tests)
Test Files 4 passed (4)
Tests 42 passed (42)
Start at 10:30:45
Duration 2.34s
Tests should be colocated with source files:
src/
βββ renderer/
βββ components/
βββ MyComponent.tsx
βββ MyComponent.test.tsx β Create this
import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import MyComponent from './MyComponent';
describe('MyComponent', () => {
it('should render text', () => {
render(<MyComponent text="Hello" />);
expect(screen.getByText('Hello')).toBeInTheDocument();
});
});npm run test:watchThe test will run automatically when you save!
import userEvent from '@testing-library/user-event';
it('should handle clicks', async () => {
const handleClick = vi.fn();
const user = userEvent.setup();
render(<Button onClick={handleClick} />);
await user.click(screen.getByRole('button'));
expect(handleClick).toHaveBeenCalled();
});import { waitFor } from '@testing-library/react';
it('should load data', async () => {
render(<MyComponent />);
await waitFor(() => {
expect(screen.getByText('Loaded!')).toBeInTheDocument();
});
});import { renderHook, act } from '@testing-library/react';
it('should update state', () => {
const { result } = renderHook(() => useMyStore());
act(() => {
result.current.setValue('new value');
});
expect(result.current.value).toBe('new value');
});import { setupDatalayerAPIMocks, mockDatalayerClient } from '@tests/mocks';
beforeEach(() => {
setupDatalayerAPIMocks();
// Customize mock response
mockDatalayerClient.listEnvironments.mockResolvedValue([...]);
});import { mockUser, mockEnvironments } from '@tests/fixtures';
it('should display user info', () => {
render(<UserProfile user={mockUser} />);
expect(screen.getByText(mockUser.email)).toBeInTheDocument();
});it('should render something', () => {
render(<MyComponent />);
screen.debug(); // Prints the DOM to console
});it('should work', () => {
const result = someFunction();
console.log('Result:', result);
expect(result).toBe(expected);
});// Add .only to run just this test
it.only('should test something', () => {
// ...
});// Add .skip to skip a test
it.skip('should test something', () => {
// ...
});# Generate coverage report
npm run test:coverage
# Open coverage report in browser
open coverage/index.htmlCoverage thresholds:
- Lines: 60%
- Functions: 60%
- Branches: 55%
- Statements: 60%
- User interactions (clicks, typing, form submission)
- Data display and transformations
- Error states and loading states
- Accessibility (ARIA attributes, keyboard navigation)
- State management (Zustand stores)
- API integration (with mocked APIs)
- Implementation details (internal state, private methods)
- Third-party libraries (React, Primer, etc.)
- Styling (unless critical to functionality)
Fix: Check tsconfig.json includes path aliases:
{
"compilerOptions": {
"paths": {
"@tests/*": ["./tests/*"]
}
}
}Fix: This is mocked in tests/setup.ts. Make sure it's imported.
Fix: Tests run in happy-dom which provides window. Check that your test imports the component correctly.
Fix:
- Use
vi.mock()for expensive operations - Don't use
setTimeoutorsetIntervalin tests - Run tests in parallel (default in Vitest)
- Full Documentation: tests/README.md
- Test Summary: TEST_SUMMARY.md
- Vitest Docs: https://vitest.dev
- Testing Library: https://testing-library.com
- Playwright: https://playwright.dev
Start writing tests and let the test runner guide you. Happy testing! π
Pro Tip: Run npm run test:watch in a terminal and keep it open while coding. Tests will run automatically as you save files!