Vitest Testing
Setup
- Config:
vitest.config.tsuses Astro'sgetViteConfigwrapper. - Environment: jsdom.
- Globals:
true—describe,it,expect,viare available without imports. - Matchers:
@testing-library/jest-domis loaded viasrc/test/setup.ts. - Cleanup:
@testing-library/reactcleanup runs after each test automatically.
TDD Workflow (Mandatory)
- Red: Write a failing test that describes the expected behaviour.
- Green: Write the minimum code to make it pass.
- Refactor: Clean up while keeping tests green.
File Placement
Tests live next to the code they test:
src/calculators/tiles.ts
src/calculators/tiles.test.ts
src/components/calculators/TileCalculator.tsx
src/components/calculators/TileCalculator.test.tsx
Calculator Logic Tests (Pure Functions)
describe('calculateTiles', () => {
it('calculates correct tile count for a simple area', () => {
const result = calculateTiles({
areaWidth: 3,
areaHeight: 2.4,
tileWidth: 300,
tileHeight: 300,
gapSize: 3,
wastage: 10,
});
expect(result.tilesNeeded).toBe(/* expected value */);
});
it('includes wastage in the calculation', () => {
// ...
});
it('handles zero dimensions', () => {
// ...
});
});
React Component Tests
Use @testing-library/react — test user behaviour, not implementation.
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import TileCalculator from './TileCalculator';
describe('TileCalculator', () => {
it('renders the input form', () => {
render(<TileCalculator />);
expect(screen.getByLabelText(/area width/i)).toBeInTheDocument();
});
it('displays results after calculation', async () => {
const user = userEvent.setup();
render(<TileCalculator />);
await user.type(screen.getByLabelText(/area width/i), '3');
await user.click(screen.getByRole('button', { name: /calculate/i }));
expect(screen.getByText(/tiles needed/i)).toBeInTheDocument();
});
});
Rules
- No snapshot tests unless explicitly requested.
- Test behaviour, not implementation. Don't test internal state.
- Use
screenqueries — prefergetByRole,getByLabelText,getByText(in that order). - No mocking calculator functions in component tests — test the integration.
- Mock only external dependencies (APIs, browser APIs, etc.).
Running Tests
npm test # Run all tests
npx vitest run # Run once (CI mode)
npx vitest --watch # Watch mode
npx vitest tiles # Run tests matching "tiles"
Note:
package.jsondoes not have atestscript yet. Add"test": "vitest"when implementing the first test.
Converted and distributed by TomeVault — claim your Tome and manage your conversions.