Vitest Workspace Configuration
Vitest Workspace Configuration
Problem Statement
The codebase contains both Astro and React components, requiring different testing environments:
| Component Type | Testing Requirements | 
|---|---|
| Astro | Astro’s test utilities | 
| React | jsdom environment, React Testing Library | 
Previously maintained two separate Vitest configs - inefficient and required running multiple test commands.
Solution: Vitest Workspaces
Implemented Vitest’s workspace feature to combine configurations while maintaining specialized testing environments.
Key Files
vitest.workspace.ts- Entry point for all tests
import { defineWorkspace } from 'vitest/config';
export default defineWorkspace([
  'vitest.astro.config.ts',
  'vitest.react.config.ts',
]);
vitest.astro.config.ts- Astro-specific configuration
import { getViteConfig } from 'astro/config';
import react from '@vitejs/plugin-react';
export default getViteConfig({
  plugins: [react()],
  test: {
    name: 'astro',
    globals: true,
    setupFiles: ['./vitest.setup.ts'],
    include: ['src/**/*.test.*'],
    exclude: ['src/**/react/*.test.*'],
    coverage: {
      include: ['src/**/*.astro', 'src/**/*.ts', 'src/**/*.tsx'],
      provider: 'v8',
    },
  },
});
vitest.react.config.ts- React-specific configuration
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { resolve } from 'path';
export default defineConfig({
  plugins: [react()],
  test: {
    name: 'react',
    include: ['src/**/react/*.test.tsx'],
    environment: 'jsdom',
    setupFiles: ['./vitest.setup.ts'],
  },
  resolve: {
    alias: {
      '@': resolve(__dirname, './src'),
    },
  },
});
NOTE: Original
vitest.config.tshas been removed as it’s no longer needed.
Usage Instructions
Available Commands
# Run all tests
pnpm test
# Run only Astro tests
pnpm test:astro
# Run only React tests
pnpm test:react
# Run all tests with coverage
pnpm coverage
Package.json Configuration
{
  "scripts": {
    "test": "vitest",
    "test:astro": "vitest --workspace=astro",
    "test:react": "vitest --workspace=react",
    "coverage": "vitest run --coverage"
  }
}
File Organization
src/
├── components/
│   └── *.test.ts     # Astro component tests
└── react/
    └── *.test.tsx    # React component tests
Benefits
- ✅ Single command to run all tests
 - ✅ Environment-specific configurations
 - ✅ Unified test reporting
 - ✅ Reduced configuration duplication
 - ✅ Simplified CI/CD pipeline
 - ✅ Clear separation of test types
 
Troubleshooting
| Issue | Solution | 
|---|---|
| Tests not running in correct environment | Check file path matches the include patterns | 
| React tests failing with DOM errors | Ensure the test file is in a path matched by React config | 
| Coverage report incomplete | Check the include patterns in coverage configuration | 
Usage Examples
Testing an Astro Component
// src/components/Header.test.ts
import { expect, test, describe } from 'vitest';
import { AstroContainer } from 'astro/container';
import Header from './Header.astro';
describe('Header', () => {
  test('renders correctly', async () => {
    const container = await AstroContainer.create();
    const result = await container.renderToString(Header, {});
    expect(result).toContain('Site Title');
  });
});
Testing a React Component
// src/react/Button.test.tsx
import { render, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import Button from './Button';
describe('Button', () => {
  it('renders with correct text', () => {
    render(<Button>Click Me</Button>);
    expect(screen.getByRole('button')).toHaveTextContent('Click Me');
  });
});
TIP: When adding new test files, ensure they follow the path patterns defined in the configuration files to be picked up by the correct workspace.