Passer au contenu

Workspaces dans Vitest

Les workspaces Vitest permettent de gérer facilement les tests dans des projets complexes comme les monorepos ou les architectures modulaires. Cette fonctionnalité vous aide à organiser, exécuter et configurer vos tests de manière efficace à travers plusieurs packages ou modules.

Qu’est-ce qu’un Workspace Vitest?

Un workspace Vitest est un ensemble de configurations de test qui partagent certains paramètres mais peuvent avoir leurs propres spécificités. Ils sont particulièrement utiles dans les scénarios suivants:

  • Projets monorepo (pnpm/Yarn/npm workspaces, Turborepo, Nx, etc.)
  • Applications modulaires avec différents types de tests
  • Projets nécessitant différentes configurations selon les dossiers

Configuration de Base

Pour utiliser les workspaces, vous devez définir une configuration racine et éventuellement des configurations spécifiques pour chaque workspace:

// vitest.workspace.js (à la racine du projet)
import { defineWorkspace } from 'vitest/config'
export default defineWorkspace([
// Configuration partagée
{
extends: './vitest.config.js',
test: {
name: 'shared',
// Options partagées
}
},
// Workspace spécifique: backend
{
extends: './vitest.config.js',
test: {
name: 'backend',
include: ['packages/backend/**/*.test.ts'],
environment: 'node'
}
},
// Workspace spécifique: frontend
{
extends: './vitest.config.js',
test: {
name: 'frontend',
include: ['packages/frontend/**/*.test.ts'],
environment: 'happy-dom'
}
}
])

Exécution des Tests par Workspace

Une fois vos workspaces configurés, vous pouvez les exécuter séparément ou ensemble:

Fenêtre de terminal
# Exécuter tous les workspaces
vitest
# Exécuter un workspace spécifique
vitest --workspace=frontend
# Exécuter plusieurs workspaces
vitest --workspace=frontend --workspace=backend
# Exécuter avec un pattern de nom
vitest --workspace "*end*"

Configurations Héritées

Les workspaces peuvent hériter d’une configuration de base à l’aide de la propriété extends:

// vitest.config.js (configuration de base)
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
globals: true,
environment: 'node',
}
})
// Dans vitest.workspace.js
{
extends: './vitest.config.js',
test: {
name: 'backend',
// Hérite des globals: true et environment: 'node'
// Mais vous pouvez les surcharger ici
include: ['packages/backend/**/*.test.ts']
}
}

Détection Automatique dans les Monorepos

Vitest peut détecter automatiquement les packages dans les monorepos et créer des workspaces pour chacun:

vitest.workspace.js
import { defineWorkspace } from 'vitest/config'
// Détection automatique des packages
export default defineWorkspace([
// Configuration globale
{
test: {
name: 'shared',
// Options partagées
}
},
// Utilise le glob pour détecter tous les packages
'packages/*/vitest.config.{js,ts,mjs,mts}',
// Ou utilisez une fonction pour personnaliser la détection
async () => {
// Logique personnalisée pour détecter les packages
return [
// Liste de configurations
]
}
])

Configuration Avancée

Timeouts par Workspace

Vous pouvez définir des timeouts différents selon les types de tests:

export default defineWorkspace([
{
test: {
name: 'unit',
include: ['**/*.spec.ts'],
// Tests unitaires rapides
testTimeout: 5000
}
},
{
test: {
name: 'integration',
include: ['**/*.integration.ts'],
// Tests d'intégration plus lents
testTimeout: 30000
}
}
])

Environnements Différents

Configurez différents environnements selon les besoins de vos tests:

export default defineWorkspace([
{
test: {
name: 'node',
include: ['**/server/**/*.test.ts'],
environment: 'node'
}
},
{
test: {
name: 'browser',
include: ['**/client/**/*.test.ts'],
environment: 'happy-dom'
}
}
])

Organisation des Fichiers

Une organisation typique des fichiers dans un projet utilisant des workspaces pourrait ressembler à:

monorepo/
├── vitest.workspace.js # Configuration des workspaces
├── vitest.config.js # Configuration partagée
├── packages/
│ ├── backend/
│ │ ├── vitest.config.js # Configuration spécifique
│ │ ├── src/
│ │ └── tests/
│ │
│ ├── frontend/
│ │ ├── vitest.config.js # Configuration spécifique
│ │ ├── src/
│ │ └── tests/
│ │
│ └── shared/
│ ├── vitest.config.js # Configuration spécifique
│ ├── src/
│ └── tests/

Workspaces avec Différents Rapports

Vous pouvez configurer différents rapports pour chaque workspace:

export default defineWorkspace([
{
test: {
name: 'unit',
include: ['**/*.spec.ts'],
reporters: ['default']
}
},
{
test: {
name: 'e2e',
include: ['**/*.e2e.ts'],
reporters: ['verbose', 'junit']
}
}
])

Couverture de Code par Workspace

La couverture de code peut être configurée différemment pour chaque workspace:

export default defineWorkspace([
{
test: {
name: 'backend',
include: ['packages/backend/**/*.test.ts'],
coverage: {
provider: 'v8',
reporter: ['text', 'json'],
reportsDirectory: './coverage/backend'
}
}
},
{
test: {
name: 'frontend',
include: ['packages/frontend/**/*.test.ts'],
coverage: {
provider: 'istanbul',
reporter: ['html', 'lcov'],
reportsDirectory: './coverage/frontend'
}
}
}
])

Interface CLI pour les Workspaces

L’interface en ligne de commande pour les workspaces offre plusieurs options utiles:

Fenêtre de terminal
# Lister tous les workspaces disponibles
vitest --list-workspaces
# Exécuter des tests spécifiques dans un workspace
vitest --workspace=backend -t "should create user"
# Mode watch pour un workspace spécifique
vitest --workspace=frontend --watch
# Générer la couverture pour un workspace spécifique
vitest --workspace=shared --coverage

Bonnes Pratiques

  1. Nommez clairement vos workspaces pour faciliter leur identification
  2. Factotisez les configurations communes dans un fichier de base
  3. Utilisez des patterns d’inclusion précis pour éviter d’exécuter des tests dans les mauvais environnements
  4. Séparez les types de tests (unitaires, intégration, e2e) dans différents workspaces
  5. Utilisez les files de rapports distinctes pour chaque workspace

Les workspaces sont une fonctionnalité puissante qui peut considérablement améliorer l’organisation et l’efficacité de vos tests dans des projets complexes. Ils permettent d’adapter précisément la configuration aux besoins de chaque partie de votre application.