This document outlines the testing strategy and best practices for this Astro project.
- Vitest - Unit and integration testing (fast, Vite-native)
- @testing-library/react - React component testing
- happy-dom - Lightweight DOM implementation for tests
- pa11y - Accessibility testing (TODO: configure)
# Run tests in watch mode (development)
pnpm test
# Run tests once (CI)
pnpm test:run
# Run tests with UI
pnpm test:ui
# Run tests with coverage
pnpm test:coverage
# Run accessibility tests (TODO: needs URLs configured)
pnpm test:a11yTests are colocated with source files using the .test.ts or .spec.ts suffix:
src/
├── utils.ts
├── utils.test.ts ← Tests for utils
├── i18n/
│ ├── utils.ts
│ └── utils.test.ts ← Tests for i18n utils
└── components/
├── Footer.astro
└── Footer.test.ts ← Tests for components (future)
import { describe, it, expect } from 'vitest';
import { getImageMimeType } from './utils';
describe('getImageMimeType', () => {
it('should return correct MIME type for PNG', () => {
expect(getImageMimeType('image.png')).toBe('image/png');
});
});See src/utils.test.ts and src/i18n/utils.test.ts for complete examples.
Test React components if you add interactive features:
import { render, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import YourComponent from './YourComponent';
describe('YourComponent', () => {
it('should render correctly', () => {
render(<YourComponent />);
expect(screen.getByText('Expected Text')).toBeInTheDocument();
});
});Test that Astro pages render correctly:
import { experimental_AstroContainer as AstroContainer } from 'astro/container';
import { describe, it, expect } from 'vitest';
import BlogPost from './pages/blog/[slug].astro';
describe('Blog Post Page', () => {
it('should render blog post', async () => {
const container = await AstroContainer.create();
const result = await container.renderToString(BlogPost, {
props: {
/* ... */
},
});
expect(result).toContain('Expected Content');
});
});For full user flows, consider adding Playwright:
pnpm add -D @playwright/testTest navigation, search, filtering, etc.
Configure pa11y to test key pages:
// pa11y.config.js
export default {
urls: [
'http://localhost:4321/',
'http://localhost:4321/blog',
'http://localhost:4321/about',
],
standard: 'WCAG2AA',
};Tests run automatically on every PR via .github/workflows/test.yml:
- ✅ Unit tests run on every commit
- ✅ Tests must pass before merge
- ✅ Coverage reports generated (optional)
- Write tests for bugs - When you fix a bug, add a test to prevent regression
- Test behavior, not implementation - Focus on what the code does, not how
- Keep tests simple - Each test should verify one thing
- Use descriptive test names -
it('should return 404 for invalid blog slug')notit('works') - Avoid testing framework code - Don't test Astro itself, test your logic
- Mock external dependencies - Use
vi.mock()for API calls, file system, etc.