Mis à jour ces 90 derniers jours 5 nouvelles · 19 révisées
Expérimentation ou deux variantes (A et B) sont présentées a des groupes d'utilisateurs différents pour mesurer laquelle performe le mieux selon des métriques définies.
Comme un restaurant qui teste deux recettes de dessert sur deux tables différentes et mesure laquelle est la plus commandée.
// Feature flag A/B test
const variant = getExperimentVariant(userId, 'checkout-v2');
if (variant === 'B') {
return <NewCheckout />;
}
return <OldCheckout />;
// Tracking: analytics.track('purchase', { variant });Cas d'usage : Pour prendre des décisions produit basées sur des données réelles plutôt que des opinions (boutons, textes, parcours).
Pattern de structuration des tests en 3 phases : Arrange (préparer les données), Act (exécuter l'action), Assert (vérifier le résultat). Rend les tests lisibles et uniformes.
Comme une recette de cuisine : préparer les ingrédients (Arrange), cuisiner (Act), goûter et vérifier (Assert).
test('applies 10% discount for VIP', () => {
// Arrange
const user = createUser({ vip: true });
const cart = createCart({ total: 100 });
// Act
const finalPrice = applyDiscount(user, cart);
// Assert
expect(finalPrice).toBe(90);
});Cas d'usage : Comme structure standard pour tous les tests unitaires afin de maintenir la lisibilité et la cohérence.
Test qui vérifie qu'une fonctionnalité répond aux critères d'acceptation définis par le Product Owner ou le client. Souvent écrit en langage naturel (Gherkin).
Comme la checklist du client lors de la réception d'une maison neuve : chaque point du cahier des charges est vérifié.
// En Gherkin (Cucumber)
// Feature: Connexion utilisateur
// Scenario: Login reussi
// Given un utilisateur inscrit "[email protected]"
// When il saisit son mot de passe correct
// Then il voit son tableau de bord
// And un cookie de session est creeCas d'usage : Pour formaliser et automatiser les critères d'acceptation du Product Owner en tests exécutables.
Transpileur JavaScript historique qui transforme la syntaxe moderne (ES2024+, JSX) en code compatible avec les anciens navigateurs. Remplace progressivement par SWC et esbuild.
Comme un traducteur universel : il prend votre texte moderne et le traduit en langue ancienne que tout le monde comprend.
// babel.config.json
{
"presets": [
["@babel/preset-env", { "targets": "> 0.5%" }],
"@babel/preset-react",
"@babel/preset-typescript"
]
}Cas d'usage : Pour les projets legacy nécessitant des transformations custom ou un support navigateurs très anciens.
Fichiers index.ts qui re-exportent tout un dossier. Pratique pour les imports mais cause des problèmes de tree-shaking et de performance en chargeant du code inutilisé.
Comme une porte d'entrée unique pour un centre commercial : pratique pour trouver, mais vous devez traverser tout le bâtiment même pour un seul magasin.
// src/utils/index.ts (barrel file)
export { formatDate } from './date';
export { formatCurrency } from './currency';
export { sendEmail } from './email'; // lourd!
// Probleme: import { formatDate } from './utils'
// => charge aussi sendEmail inutilement
// Fix: import directement depuis le fichier sourceCas d'usage : Acceptable pour les librairies publiées, mais a éviter dans le code applicatif pour les performances.
Behavior-Driven Development : extension du TDD qui exprime les tests en langage métier (Given-When-Then) pour favoriser la collaboration entre devs, QA et PO.
Comme écrire le scénario d'un film avant de le tourner : tout le monde (réalisateur, acteurs, producteur) comprend l'histoire.
// Cucumber + step definitions
// Feature: Panier d'achat
// Scenario: Ajout d'un produit
// Given un panier vide
// When j'ajoute "iPhone" au panier
// Then le panier contient 1 article
Given('un panier vide', () => { cart = new Cart(); });
When('j\'ajoute {string} au panier', (item) => {
cart.add(item);
});Cas d'usage : Pour les projets ou la communication entre équipes techniques et métier est critique pour la qualité.
Règles GitHub/GitLab sur les branches protégées (main, develop) : requiert reviews, CI verte, signatures, et interdit les force push. Filet de sécurité essentiel.
Comme les barrières de sécurité sur une autoroute : elles empêchent les véhicules de sortir de la route même en cas d'erreur.
# Regles recommandees pour main
# - Require 1+ review approvals
# - Require status checks (CI) to pass
# - Require branches to be up to date
# - No force pushes
# - No deletions
# - Include administratorsCas d'usage : Pour protéger les branches de production contre les pushes directs, les force pushes et les merges sans review.
Analyse visuelle de la composition du bundle JavaScript pour identifier les dépendances lourdes et les opportunités d'optimisation (code splitting, lazy loading).
Comme une radiographie de votre valise : vous voyez exactement ce qui prend le plus de place et ce que vous pouvez retirer.
// Avec Vite
// npx vite-bundle-visualizer
// Avec Webpack
// webpack-bundle-analyzer
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
module.exports = {
plugins: [new BundleAnalyzerPlugin()],
};Cas d'usage : Avant chaque release pour détecter les dépendances qui gonflent inutilement le bundle.
Stratégie de déploiement ou la nouvelle version est déployée sur un petit pourcentage du trafic pour détecter les problèmes avant un rollout complet.
Comme le canari dans la mine de charbon : s'il s'arrête de chanter, on sait qu'il y a un problème avant que les mineurs soient en danger.
# Kubernetes canary deployment
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
spec:
http:
- route:
- destination: { host: app, subset: stable }
weight: 95
- destination: { host: app, subset: canary }
weight: 5Cas d'usage : Pour déployer en production avec un filet de sécurité, en limitant l'impact d'un bug a 5% des utilisateurs.
Outil de gestion de versions pour monorepos. Chaque PR ajoute un fichier changeset décrivant le changement et son semver, puis l'outil génère le changelog et publie automatiquement.
Comme un carnet de bord de modifications : chaque mécanicien note ce qu'il a change, et le système compile le rapport final.
# Creer un changeset
npx changeset
# Choisir package -> minor -> "Add OAuth"
# Fichier cree: .changeset/brave-fox.md
# En CI: version + publish
npx changeset version # bump versions
npx changeset publish # publish to npmCas d'usage : Pour les librairies et design systems en monorepo nécessitant un versioning et changelog automatises.
Discipline qui consiste a injecter volontairement des pannes (réseau, serveur, latence) en production pour vérifier la resilience du système. Popularisée par Netflix (Chaos Monkey).
Comme un exercice d'évacuation incendie : on simule la catastrophe pour vérifier que tout le monde sait réagir correctement.
// Principe Chaos Monkey (conceptuel)
// 1. Definir l'etat stable (metriques normales)
// 2. Hypothese: le systeme resiste a la panne X
// 3. Injecter: kill un pod, coupure reseau...
// 4. Observer: le systeme se retablit-il ?
// Outils: Gremlin, LitmusChaos, Chaos MeshCas d'usage : Pour les systèmes distribues critiques afin de découvrir les failles de resilience avant qu'elles ne causent des incidents réels.
Métrique qui mesure le pourcentage de code exécuté par les tests (lignes, branches, fonctions). Utile comme indicateur mais trompeur comme objectif unique.
Comme mesurer le pourcentage de pièces visitées lors d'une inspection de maison : visiter 100% ne garantit pas d'avoir vu les fissures.
// jest.config.js
module.exports = {
collectCoverage: true,
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
},
},
};Cas d'usage : Comme garde-fou pour détecter les zones non testées, avec un seuil raisonnable (70-80%).
Pratique ou un ou plusieurs pairs examinent le code soumis avant son intégration. Amélioré la qualité, partage les connaissances et détecte les bugs humainement.
Comme la relecture d'un manuscrit par un éditeur : il détecte les fautes et les incohérences que l'auteur ne voit plus.
// Bonne PR review checklist
// [ ] Le code fait ce que la description promet
// [ ] Pas de code mort ou commente
// [ ] Tests inclus pour les nouveaux cas
// [ ] Pas de secrets hardcodes
// [ ] Performance acceptable
// [ ] Nommage clair et coherentCas d'usage : Pour chaque changement de code afin de maintenir la qualité et partager les connaissances dans l'équipe.
Fichier GitHub qui assigne automatiquement des reviewers aux PR en fonction des fichiers modifies. Garantit que les experts appropriées reviewent chaque changement.
Comme un organigramme de responsabilités : chaque zone du bâtiment a un responsable attitré pour les travaux.
# .github/CODEOWNERS
*.ts @team/frontend
/api/ @team/backend
/infra/ @team/devops
*.sql @team/dba
package.json @team/leadsCas d'usage : Dans les équipes moyennes/grandes pour garantir que les bons experts sont automatiquement assignes en review.
Environnements de dev cloud GitHub bases sur les Dev Containers. Un VS Code complet dans le navigateur ou en local, avec les ports, extensions et outils pre-configures.
Comme un PC gamer dans le cloud : vous y accédez de n'importe quel appareil et retrouvez toute votre configuration.
# Lancer un Codespace depuis GitHub
# 1. Bouton 'Code' -> 'Codespaces'
# 2. 'Create codespace on main'
# 3. VS Code s'ouvre dans le navigateur
# 4. npm ci + extensions installes automatiquement
# Ou en CLI:
# gh codespace create -r owner/repo -b mainCas d'usage : Pour les contributions open source ou les équipes distribuées voulant un setup zéro-config.
Outil qui vérifie que les messages de commit respectent un format conventionnel (Conventional Commits). Permet l'automatisation du changelog et du versioning sémantique.
Comme un formulaire avec des champs obligatoires : votre message de commit doit respecter le modèle pour être accepte.
// commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional']
};
// Valide: feat(auth): add OAuth login
// Valide: fix(cart): handle empty state
// Invalide: fixed stuffCas d'usage : Pour automatiser le changelog et le semantic versioning a partir de messages de commit structures.
Test qui vérifie que l'interface (contrat) entre un consommateur et un fournisseur d'API est respectée. Chaque cote teste indépendamment sa conformité au contrat.
Comme un contrat de location : le locataire et le propriétaire vérifient chacun que les clauses sont respectées sans avoir besoin de se rencontrer.
// Pact consumer test
const interaction = {
uponReceiving: 'a request for user',
withRequest: { method: 'GET', path: '/users/1' },
willRespondWith: {
status: 200,
body: { id: 1, name: like('Alice') }
}
};Cas d'usage : En architecture microservices pour garantir que les équipes peuvent déployer indépendamment sans casser les intégrations.
Framework de test E2E et de composants qui s'exécute dans le navigateur, avec un débogueur « time-travel » visuel. Toujours activement maintenu : Cypress 16.1.0 est sorti le 15 septembre 2026. Face à Playwright, il reste apprécié pour sa prise en main, mais son modèle (un onglet, une origine à la fois, pas de WebKit natif) le rend moins adapté au multi-navigateur et au parallélisme massif.
Comme une caméra de surveillance dans votre app : vous voyez chaque clic, chaque requête, et vous pouvez rembobiner.
// login.cy.js
describe('Login', () => {
it('logs in successfully', () => {
cy.visit('/login');
cy.get('#email').type('[email protected]');
cy.get('#password').type('secret123');
cy.get('button[type=submit]').click();
cy.url().should('include', '/dashboard');
});
});Cas d'usage : Pour les tests E2E d'applications web avec besoin d'un debugger visuel puissant et une courbe d'apprentissage douce.
Spécification permettant de définir un environnement de développement reproductible dans un conteneur Docker. Supporte par VS Code, GitHub Codespaces et JetBrains.
Comme un bureau portable pre-équipe : ou que vous alliez, vous retrouvez exactement le même poste de travail configure.
// .devcontainer/devcontainer.json
{
"name": "Node.js Dev",
"image": "mcr.microsoft.com/devcontainers/node:20",
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {}
},
"postCreateCommand": "npm ci",
"customizations": { "vscode": { "extensions": ["dbaeumer.vscode-eslint"] } }
}Cas d'usage : Pour onboarder un nouveau développeur en 5 minutes avec un environnement identique a toute l'équipe.
Outil qui charge et décharge automatiquement des variables d'environnement quand vous entrez ou sortez d'un répertoire. Base sur un fichier .envrc versionne.
Comme un badge d'accès automatique : en entrant dans le bureau (dossier), vos droits (variables) s'activent automatiquement.
# .envrc
export DATABASE_URL=postgres://localhost/myapp
export API_KEY=dev-key-123
export NODE_ENV=development
# Terminal:
# cd my-project -> direnv: loading .envrc
# cd .. -> direnv: unloading
# direnv allow -> autoriser un nouvel .envrcCas d'usage : Pour gérer automatiquement les variables d'environnement par projet sans .env global.
Fichiers de configuration commençant par un point (.bashrc, .gitconfig, .zshrc). Versionnes dans un repo Git, ils permettent de reproduire son environnement sur n'importe quelle machine.
Comme emporter ses préférences personnelles (siège, miroir, thermostat) d'un bureau a l'autre : votre confort vous suit.
# Structure typique d'un repo dotfiles
# ~/.dotfiles/
# .gitconfig
# .zshrc
# .vimrc
# install.sh -> symlink tout
# GitHub Codespaces utilise automatiquement
# votre repo dotfiles si configure dans
# Settings > Codespaces > DotfilesCas d'usage : Pour reproduire son environnement de dev sur un nouveau poste ou dans un Codespace en quelques secondes.
Test de bout en bout qui simule le parcours réel d'un utilisateur a travers l'application complète (navigateur, API, BDD). Valide le système dans son ensemble.
Comme un client mystère qui entre dans un restaurant, commande, mange et paye pour vérifier toute l'expérience.
// checkout.spec.ts (Playwright)
test('user can complete checkout', async ({ page }) => {
await page.goto('/products');
await page.click('[data-testid="add-to-cart"]');
await page.click('[data-testid="checkout"]');
await page.fill('#email', '[email protected]');
await page.click('button:text("Pay")');
await expect(page.locator('.success')).toBeVisible();
});Cas d'usage : Pour valider les parcours utilisateurs critiques (inscription, achat, paiement) avant chaque release.
Fichier de configuration standardise (.editorconfig) qui définit les règles basiques d'édition (indentation, fin de ligne, charset) pour tous les éditeurs et IDE.
Comme une règle commune pour toute la classe : que vous utilisiez un stylo bleu ou noir, tout le monde écrit sur les mêmes lignes.
# .editorconfig
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = trueCas d'usage : Pour garantir des bases communes (tabs vs spaces, LF vs CRLF) dans une équipe avec différents éditeurs.
Bundler et transpileur JavaScript écrit en Go, 10 a 100x plus rapide que les alternatives JavaScript. Utilise en interne par Vite pour le dev server.
Comme un TGV face a un train régional : même destination, mais la vitesse est dans une autre catégorie.
// En CLI
// esbuild src/index.ts --bundle --outfile=out.js
// En API
import { build } from 'esbuild';
await build({
entryPoints: ['src/index.ts'],
bundle: true,
outfile: 'dist/out.js',
minify: true,
});Cas d'usage : Pour les outils CLI, les librairies ou comme transpileur rapide dans la toolchain de dev.
Linter JavaScript/TypeScript qui analyse statiquement le code pour détecter les erreurs, les mauvaises pratiques et les violations de style. Entièrement configurable par règles et plugins.
Comme un correcteur orthographique pour le code : il souligne les erreurs avant que vous ne les envoyiez.
// eslint.config.js (flat config)
import js from '@eslint/js';
export default [
js.configs.recommended,
{
rules: {
'no-unused-vars': 'error',
'no-console': 'warn',
},
},
];Cas d'usage : Dans chaque projet JS/TS pour attraper les bugs et maintenir un style de code cohérent dans l'équipe.
Fonction qui génère des objets de test avec des valeurs par défaut sensibles et la possibilité de surcharger certains champs. Plus flexible que les fixtures statiques.
Comme un moule a gâteau avec des options : le moule donne la forme de base, mais vous choisissez la garniture pour chaque gâteau.
// factories/user.ts
export const createUser = (overrides = {}) => ({
id: faker.string.uuid(),
name: faker.person.fullName(),
email: faker.internet.email(),
role: 'user',
...overrides,
});
// Usage: createUser({ role: 'admin' })Cas d'usage : Pour générer des données de test variées sans dupliquer la création d'objets dans chaque test.
Implémentation de HMR spécifique a React par Meta. Préserve l'état des hooks (useState, useRef) lors des modifications de composants, même en cas d'erreur de syntaxe.
Comme un peintre qui retouche un tableau en direct : les couleurs changent instantanément sans avoir a reposer le cadre.
// Fast Refresh est actif automatiquement
// dans Next.js, Vite + React, CRA
// Regles pour que ca marche:
// 1. Un composant par fichier
// 2. Exports nommes (pas default + named)
// 3. Les fichiers non-React causent un
// rechargement complet (full reload)Cas d'usage : Actif par défaut dans les projets React modernes pour un feedback instantané lors du développement.
Données de test prédéfinies utilisées pour mettre en place un état initial connu et reproductible avant chaque test. Peut être un fichier JSON, un seed de base de données, etc.
Comme les décors d'une scène de théâtre : mis en place avant chaque représentation pour un contexte identique.
// fixtures/users.json
// [{ "id": 1, "name": "Alice", "role": "admin" }]
beforeEach(async () => {
await db.seed(require('./fixtures/users.json'));
});
afterEach(async () => {
await db.cleanup();
});Cas d'usage : Pour les tests d'intégration nécessitant un état de base de données connu et reproductible.
Test non déterministe qui passe ou échoue de manière aléatoire sans changement de code. Causes fréquentes : timing, ordre d'exécution, état partage, dépendances externes.
Comme un détecteur de fumée qui sonne parfois sans raison : on finit par l'ignorer, même quand il y a un vrai incendie.
// FLAKY: depend du timing
test('shows notification', async () => {
triggerNotification();
// Mauvais: delai fixe fragile
await sleep(500);
expect(screen.getByText('Done')).toBeVisible();
});
// FIX: utiliser waitFor
await waitFor(() => {
expect(screen.getByText('Done')).toBeVisible();
});Cas d'usage : Pour identifier et corriger les tests instables qui minent la confiance de l'équipe dans la CI.
Fast Node Manager, gestionnaire de versions Node.js écrit en Rust. Plus rapide que nvm, supporte .node-version et .nvmrc. Léger et cross-platform.
Comme nvm mais avec un moteur turbo : même fonction, mais le switch de version est instantané.
# Installation et usage
fnm install 20
fnm use 20
fnm default 20
# Auto-switch avec .node-version
echo "20" > .node-version
# fnm use --install-if-missing
# Shell integration (.zshrc)
eval "$(fnm env --use-on-cd)"Cas d'usage : Comme alternative rapide a nvm pour gérer les versions Node.js avec auto-switch par projet.
Format de description des tests issu du BDD : Given (contexte initial), When (action), Then (résultat attendu). Équivalent de AAA en langage métier.
Comme raconter une histoire : 'Étant donne que... Quand... Alors...' — même votre PO peut comprendre le test.
// Given-When-Then en Gherkin
// Given un panier avec 3 articles
// When l'utilisateur applique le code PROMO10
// Then le total est reduit de 10%
test('PROMO10 reduces total by 10%', () => {
const cart = createCart({ items: 3, total: 100 });
const result = applyPromo(cart, 'PROMO10');
expect(result.total).toBe(90);
});Cas d'usage : Pour les tests d'acceptance et BDD ou le langage métier doit être compréhensible par les non-techniques.
Tests complètement auto-contenus sans aucune dépendance externe (réseau, API tierces, horloge système). Tout est contrôlé et reproductible a 100%.
Comme un laboratoire en salle blanche : l'environnement est totalement contrôle, rien de l'extérieur ne peut influencer le résultat.
// Hermetique : controle du temps
vi.useFakeTimers();
vi.setSystemTime(new Date('2024-01-01'));
// Hermetique : mock reseau
const server = setupServer(
http.get('/api/data', () => HttpResponse.json({}))
);
// Aucune requete reelle ne sortCas d'usage : Pour les tests en CI/CD qui doivent fonctionner identiquement sur n'importe quelle machine sans accès réseau.
Technologie qui remplace les modules modifies dans le navigateur sans recharger la page, préservant l'état de l'application. Accélère considérablement le cycle de développement.
Comme changer une roue sur une voiture en mouvement : vous remplacez la pièce sans arrêter le moteur ni perdre votre position.
// Vite: HMR natif, rien a configurer
// Modifiez un fichier -> mise a jour instantanee
// React Fast Refresh preserve l'etat
// des hooks et composants
// Webpack: necessite config + plugin HMR
// Vite: marche out-of-the-boxCas d'usage : Pendant le développement pour voir instantanément les changements sans perdre l'état de l'app (formulaires, navigation).
Husky exécuté des gît hooks (pre-commit, pre-push) et lint-staged applique des commandes (lint, format) uniquement sur les fichiers stages. Ensemble, ils garantissent la qualité avant chaque commit.
Comme un vigile a l'entrée d'un club : il vérifie la tenue de chaque personne (fichier) avant de la laisser entrer (commiter).
// package.json
{
"lint-staged": {
"*.{js,ts}": ["eslint --fix", "prettier --write"],
"*.css": ["prettier --write"]
}
}
// .husky/pre-commit
// npx lint-stagedCas d'usage : Pour bloquer automatiquement les commits contenant des erreurs de lint ou de formatage.
Test qui vérifie que plusieurs modules ou services fonctionnent correctement ensemble. Il valide les interactions entre composants réels (API, base de données, etc.).
Comme vérifier que le moteur, la boite de vitesse et les roues fonctionnent ensemble, pas juste chacun séparément.
// user.integration.test.js
test('creates user and retrieves it', async () => {
const res = await request(app)
.post('/users')
.send({ name: 'Alice' });
expect(res.status).toBe(201);
const user = await db.users.findById(res.body.id);
expect(user.name).toBe('Alice');
});Cas d'usage : Pour valider que l'API, le service métier et la base de données collaborent correctement.
Framework de test JavaScript créé chez Meta, tout-en-un : runner, assertions, mocks et couverture. Jest 30, publié le 4 juin 2025, est annoncé plus rapide et moins gourmand en mémoire (jusqu'à 37 % de temps et 77 % de mémoire en moins sur une grosse base TypeScript), abandonne Node 14, 16, 19 et 21, exige TypeScript 5.4 minimum et passe à jsdom 26.
Comme une boite a outils complète : vous avez le marteau, le tournevis et le mètre dans le même kit, sans rien installer de plus.
// math.test.js (Jest 30)
describe('Math utils', () => {
test('multiply', () => {
expect(multiply(3, 4)).toBe(12);
});
test('spy auto-restauré (mot-clé using, Jest 30)', () => {
using spy = jest.spyOn(console, 'warn');
doSomething();
expect(spy).toHaveBeenCalled();
}); // le spy est restauré à la fin du bloc
});Cas d'usage : Projets React ou Node.js existants qui veulent un framework complet et une compatibilité maximale avec l'écosystème (Babel, CommonJS).
Outil de test de charge open source de Grafana Labs : les scénarios s'écrivent en JavaScript ou TypeScript, exécutés par un moteur Go très économe (des milliers d'utilisateurs virtuels par machine, sans Node.js). La version 1.0, publiée le 7 mai 2025, apporte le TypeScript natif, le versionnage sémantique et un module navigateur stable. Les « thresholds » transforment le test en garde-fou CI.
Une simulation d'ouverture des portes un jour de soldes : on envoie une foule virtuelle et on regarde quelles caisses saturent.
// load.js → k6 run load.js
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [{ duration: '1m', target: 50 }, { duration: '3m', target: 50 }, { duration: '30s', target: 0 }],
thresholds: {
http_req_duration: ['p(95)<300'], // p95 sous 300 ms sinon échec
http_req_failed: ['rate<0.01'], // < 1 % d'erreurs
},
};
export default function () {
const res = http.get('https://api.example.com/products');
check(res, { 'status 200': (r) => r.status === 200 });
sleep(1);
}Cas d'usage : Vérifier avant une mise en production qu'un endpoint tient le trafic attendu, et détecter les régressions de performance en CI.
Test qui simule une charge utilisateur réaliste sur le système pour mesurer ses performances (temps de réponse, débit, utilisation des ressources) sous conditions normales et pics.
Comme tester un pont en y faisant passer progressivement de plus en plus de camions pour vérifier sa charge maximale.
// k6 load test
import http from 'k6/http';
export const options = {
vus: 100, // 100 utilisateurs virtuels
duration: '30s',
};
export default function () {
http.get('https://api.myapp.com/products');
}Cas d'usage : Avant un lancement ou un evenement marketing pour vérifier que l'infrastructure tient la charge prévue.
Fichier (package-lock.json, pnpm-lock.yaml, yarn.lock) qui enregistre les versions exactes de toutes les dépendances installées. Garantit des installations reproductibles.
Comme une photo de votre étagère d'ingrédients avec les marques et dates exactes : la prochaine fois, vous achetez exactement la même chose.
// TOUJOURS commiter le lock file
git add package-lock.json
// En CI: utiliser npm ci (pas npm install)
// npm ci = install exactement le lock file
// npm install = peut modifier le lock file
// Ne JAMAIS .gitignore le lock fileCas d'usage : Pour garantir que tous les devs et la CI installent exactement les mêmes versions de dépendances.
Gestionnaire polyglotte de versions d'outils (ex-rtx, successeur d'asdf en Rust). Gère Node, Python, Go, Rust et 400+ outils avec un seul fichier .mise.toml.
Comme un couteau suisse pour les versions d'outils : un seul outil remplace nvm, pyenv, goenv et tous les autres.
# .mise.toml
[tools]
node = "20.11"
python = "3.12"
[env]
DATABASE_URL = "postgres://localhost/myapp"
# Terminal
mise install # installe tout
mise use node@20 # switch versionCas d'usage : Pour les équipes polyglotte qui veulent un seul outil pour gérer toutes les versions de runtime.
Mocha est un runner de tests flexible pour Node.js, et Chai une librairie d'assertions expressive. Ensemble ils forment un duo classique plus modulaire que Jest.
Comme acheter son moteur et sa carrosserie séparément : plus de flexibilité mais plus de choix a faire.
const { expect } = require('chai');
describe('User', () => {
it('should have a name', () => {
const user = new User('Alice');
expect(user.name).to.equal('Alice');
expect(user).to.have.property('email');
});
});Cas d'usage : Pour les projets Node.js backend qui préfèrent une approche modulaire avec choix des plugins.
Le stub fournit des réponses prédéfinies sans vérifier les appels. Le mock vérifié en plus que les interactions attendues ont bien eu lieu (nombre d'appels, arguments).
Le stub est un distributeur automatique (il donne la réponse), le mock est un serveur de restaurant qui note ce que vous commandez ET vérifie que vous avez bien commande.
// Stub : on ne verifie pas l'appel
vi.spyOn(api, 'fetch').mockReturnValue({ data: 'ok' });
// Mock : on verifie l'interaction
const sendEmail = vi.fn();
await registerUser('[email protected]');
expect(sendEmail).toHaveBeenCalledWith('[email protected]');
expect(sendEmail).toHaveBeenCalledTimes(1);Cas d'usage : Utiliser des stubs pour les queries (get data) et des mocks pour les commands (send email, write DB).
Outils pour gérer plusieurs packages/apps dans un seul repo (Turborepo, Nx, Lerna). Offrent caching, parallélisme et graphes de dépendances intelligents.
Comme un chef de chantier qui coordonne plusieurs équipes sur un même site : il optimise l'ordre des travaux et évite les doublons.
// turbo.json (Turborepo 2 : "tasks" remplace "pipeline")
{
"$schema": "https://turborepo.dev/schema.json",
"tasks": {
"build": { "dependsOn": ["^build"], "outputs": ["dist/**"] },
"test": { "dependsOn": ["build"] },
"dev": { "cache": false, "persistent": true }
}
}Cas d'usage : Pour les organisations avec plusieurs packages partageant du code (design system, shared utils, apps).
Mock Service Worker intercepte les requêtes réseau (Service Worker côté navigateur, interception côté Node.js) pour simuler des API sans toucher au code applicatif. Depuis MSW 2.0, publié le 23 octobre 2023, l'API repose sur les primitives Fetch : « rest » devient « http », et le resolver reçoit ({ request }) et renvoie une Response ou HttpResponse.json().
Comme un standardiste qui intercepte les appels et répond a la place du destinataire, sans que l'appelant ne le sache.
// handlers.js (MSW 2.x : primitives Fetch)
import { http, HttpResponse } from 'msw';
export const handlers = [
http.get('/api/users', ({ request }) => {
// request est une vraie Request Fetch
return HttpResponse.json([{ id: 1, name: 'Alice' }]);
}),
];Cas d'usage : Pour mocker les API externes dans les tests frontend et le développement local sans backend disponible.
Technique qui modifie volontairement le code source (mutations) pour vérifier que les tests détectent bien ces changements. Si un mutant survit, les tests sont insuffisants.
Comme vérifier qu'un détecteur de fumée fonctionne en allumant une petite flamme : s'il ne sonne pas, il est défaillant.
// Stryker mutation testing
// Original: return a + b;
// Mutant 1: return a - b; // test doit echouer
// Mutant 2: return a * b; // test doit echouer
// Si un mutant SURVIT => test manquant
// npx stryker runCas d'usage : Pour évaluer la qualité réelle des tests au-delà du simple code coverage qui peut donner un faux sentiment de sécurité.
Dossier contenant toutes les dépendances installées d'un projet Node.js. Peut devenir très volumineux (facilement 500Mo+). Toujours dans le .gitignore.
Comme un entrepôt géant rempli de toutes les pièces nécessaires a votre usine : énorme mais indispensable.
# .gitignore (OBLIGATOIRE)
node_modules/
# Taille typique
# du -sh node_modules => 500M+ facilement
# Alternatives sans node_modules:
# - Yarn PnP (Plug'n'Play)
# - pnpm (liens symboliques vers store global)Cas d'usage : Structure par défaut pour stocker les dépendances npm, utilisée par tous les outils Node.js.
Node Package Manager, le gestionnaire de paquets par défaut de Node.js. Gère les dépendances, les scripts et le registre de packages le plus vaste au monde.
Comme un supermarché géant ou vous trouvez tous les ingrédients (packages) pour votre recette (projet).
npm init -y # creer package.json
npm install express # ajouter une dep
npm install -D jest # dep de dev
npm run test # lancer un script
npm ci # install propre en CI
npm audit # scanner les vulnsCas d'usage : Comme gestionnaire de paquets standard pour tout projet Node.js, surtout en CI avec npm ci.
npx exécuté des packages binaires sans les installer globalement, en les telechargant temporairement. npm exec est l'équivalent moderne intégré a npm depuis v7.
Comme louer un outil pour un jour au lieu de l'acheter : vous l'utilisez une fois et il disparaît.
# Execute sans installer
npx create-react-app my-app
npx eslint --init
# Equivalent moderne
npm exec -- create-react-app my-app
# Avec pnpm
pnpm dlx create-next-appCas d'usage : Pour exécuter des CLI ponctuels (scaffolding, init) sans polluer les dépendances globales.
Node Version Manager, le gestionnaire de versions Node.js historique en bash. Permet d'installer et switcher entre plusieurs versions de Node.js. Lent mais universellement connu.
Comme le veterane fiable : tout le monde le connaît, il fait le job, mais les jeunes (fnm, volta) sont plus rapides.
# Usage
nvm install 20
nvm use 20
nvm alias default 20
# .nvmrc pour fixer par projet
echo "20" > .nvmrc
nvm use # lit .nvmrc
# Lenteur au demarrage du shell
# -> preferer fnm ou voltaCas d'usage : Pour gérer les versions Node.js sur les systèmes Unix, surtout quand l'équipe l'utilise déjà.
Framework de test E2E de Microsoft couvrant Chromium, Firefox et WebKit, avec attente automatique, traces et parallélisme natif. Les notes de version 1.62 indiquent que les anciens paquets expérimentaux de test de composants (@playwright/expérimental-ct-react, -ct-react17, -ct-vue) ne sont plus mis à jour ; la version courante documentée est 1.63.
Comme un pilote automatique polyglotte : il conduit sur Chrome, Firefox et Safari avec la même aisance.
// login.spec.ts
import { test, expect } from '@playwright/test';
test('login flow', async ({ page }) => {
await page.goto('/login');
await page.fill('#email', '[email protected]');
await page.fill('#password', 'secret');
await page.click('button[type=submit]');
await expect(page).toHaveURL('/dashboard');
});Cas d'usage : Pour les tests E2E nécessitant du multi-navigateur, du parallélisme avance ou de la capture de traces.
Gestionnaire de paquets rapide et économe en disque (store global + liens), strict par défaut. Depuis pnpm 10 (janvier 2025), les scripts de cycle de vie des dépendances ne s'exécutent plus à l'installation sans autorisation explicite. pnpm 11 exige Node.js 22+ et bloque par défaut les versions publiées depuis moins d'un jour (minimumReleaseAge). pnpm 12, publié le 26 août 2026, est une réécriture en Rust compatible avec les commandes et le lockfile de la v11.
Comme une bibliothèque municipale : un seul exemplaire de chaque livre, et chaque habitant y accède par référence plutôt que par copie.
pnpm install # installe (scripts des deps bloqués par défaut)
pnpm approve-builds # autoriser explicitement un postinstall
pnpm add express # ajouter une dépendance
pnpm add -D vitest # dépendance de dev
pnpm dlx create-next-app # équivalent de npx
pnpm --filter @app/web test # monorepo
pnpm self-update # mettre pnpm à jourCas d'usage : Pour les monorepos et les projets avec beaucoup de dépendances, offrant rapidité et rigueur.
Outil de transformation CSS via plugins. Autoprefixer (ajout de préfixes vendeur) et Tailwind CSS sont ses plugins les plus connus. Babel équivalent pour le CSS.
Comme une chaîne de montage pour le CSS : chaque plugin ajoute une transformation spécifique a votre feuille de style.
// postcss.config.js
module.exports = {
plugins: [
require('tailwindcss'),
require('autoprefixer'),
require('cssnano')({ preset: 'default' }),
],
};Cas d'usage : Pour ajouter automatiquement les préfixes vendeur et optimiser le CSS en production.
Fichier template (.github/pull_request_template.md) qui pre-remplit la description de chaque PR avec des sections standardisées (description, tests, screenshots, checklist).
Comme un formulaire médical pre-imprime : le médecin remplit les champs au lieu de partir d'une page blanche.
<!-- .github/pull_request_template.md -->
## Description
<!-- Quoi et pourquoi -->
## Type of change
- [ ] Bug fix
- [ ] New feature
## Tests
- [ ] Tests unitaires ajoutes
- [ ] Tests E2E mis a jourCas d'usage : Pour standardiser les PR et garantir que les reviewers ont toutes les informations nécessaires.
Formateur de code opinionne qui reformate automatiquement JS, TS, CSS, JSON, HTML et Markdown. Éliminé les débats de style en imposant un format unique.
Comme un repasseur automatique pour vos vêtements : peu importe comment vous les pliez, ils ressortent tous identiques.
// .prettierrc
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5"
}
// npx prettier --write .Cas d'usage : Pour standardiser automatiquement le formatage du code et éliminer les discussions de style en code review.
Approche de test ou au lieu de cas spécifiques, on définit des propriétés que le code doit toujours respecter, et le framework génère automatiquement des centaines d'entrées aléatoires.
Comme dire a un crash-test 'la voiture doit protéger le passager peu importe l'angle de l'impact' plutôt que tester 3 angles spécifiques.
// fast-check
import fc from 'fast-check';
test('sort is idempotent', () => {
fc.assert(
fc.property(fc.array(fc.integer()), (arr) => {
const sorted = arr.sort();
expect(sorted.sort()).toEqual(sorted);
})
);
});Cas d'usage : Pour les fonctions pures et les algorithmes ou les edge cases sont difficiles a anticiper manuellement.
Test qui vérifie qu'une modification du code n'a pas casse une fonctionnalité existante. La suite de tests existante sert naturellement de filet de régression.
Comme vérifier que la réparation de la plomberie dans la cuisine n'a pas provoque une fuite dans la salle de bain.
// Apres fix du bug #423
test('regression: prix negatif ne crash plus', () => {
const result = calculateTotal(-5, 2);
expect(result).toBe(0); // fix applique
});
// Ce test empeche le bug de reapparaitreCas d'usage : A chaque bug fixe, ajouter un test de régression pour garantir qu'il ne reviendra jamais.
Bots qui créent automatiquement des PR pour mettre a jour les dépendances. Renovate est plus configurable, Dependabot est intégré nativement dans GitHub.
Comme un assistant qui vérifie chaque jour si vos fournisseurs ont de nouvelles versions et vous prépare les bons de commande.
// renovate.json
{
"extends": ["config:recommended"],
"packageRules": [
{
"matchUpdateTypes": ["minor", "patch"],
"automerge": true
}
],
"schedule": ["every weekend"]
}Cas d'usage : Pour maintenir les dépendances a jour automatiquement et éviter l'accumulation de dette technique de sécurité.
Bundler JavaScript spécialisé dans la génération de librairies avec un excellent tree-shaking. Produit des bundles ESM et CJS propres. Utilise par Vite pour le build de production.
Comme un couturier sur mesure : il taille le tissu au plus juste sans gaspillage, parfait pour les librairies.
// rollup.config.js
export default {
input: 'src/index.ts',
output: [
{ file: 'dist/index.cjs', format: 'cjs' },
{ file: 'dist/index.mjs', format: 'es' },
],
plugins: [typescript(), terser()],
};Cas d'usage : Pour bundler des librairies JavaScript avec un tree-shaking optimal et des sorties multi-formats.
Outil qui automatise entièrement le versioning sémantique (semver) et la publication npm a partir des messages de commit conventionnels. Zéro intervention manuelle.
Comme un robot comptable qui analyse vos factures et génère automatiquement le bilan : pas d'erreur humaine possible.
// .releaserc.json
{
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/npm",
"@semantic-release/github"
]
}
// feat: => minor, fix: => patch, BREAKING: => majorCas d'usage : Pour les librairies publiées sur npm qui veulent un versioning 100% automatise et fiable.
Test rapide et superficiel qui vérifie que les fonctionnalités principales de l'application fonctionnent après un déploiement. Ne teste pas en profondeur.
Comme tourner la clé de contact pour vérifier que le moteur démarre, sans faire un tour complet du circuit.
// smoke.test.js
test('homepage loads', async () => {
const res = await fetch('https://myapp.com');
expect(res.status).toBe(200);
});
test('API health check', async () => {
const res = await fetch('https://api.myapp.com/health');
expect(res.ok).toBe(true);
});Cas d'usage : Après chaque déploiement pour détecter immédiatement si quelque chose de fondamental est casse.
Variante du test de snapshot où la valeur sérialisée est écrite directement dans le fichier de test (toMatchInlineSnapshot) au lieu d'un fichier .snap séparé. Le framework (Jest, Vitest) remplit l'argument au premier passage et le met à jour avec l'option -u. La valeur attendue est visible à côté du code, ce qui rend la revue de code plus honnête et évite les fichiers .snap acceptés à l'aveugle.
Coller la photo de référence dans le cahier, à côté de l'exercice, plutôt que dans une pochette au fond du tiroir qu'on n'ouvre jamais.
import { test, expect } from 'vitest';
import { formatPrice } from './price';
test('formate en euros', () => {
// 1er run : vitest écrit la valeur ici ; -u pour la mettre à jour
expect(formatPrice(1234.5, 'fr-FR')).toMatchInlineSnapshot(`"1 234,50 €"`);
});
test('erreur structurée', () => {
expect(parseOrder('{}')).toMatchInlineSnapshot(`
{
"ok": false,
"errors": ["items: requis"],
}
`);
});Cas d'usage : Petites sorties (messages d'erreur, objets courts, HTML rendu réduit) où voir la valeur attendue dans le test aide le relecteur.
Test qui capture la sortie d'un composant (HTML, JSON) et la compare a une référence enregistrée. Toute différence inattendue fait échouer le test.
Comme prendre une photo de votre salon et comparer chaque jour : si un meuble a bouge, vous le détectez immédiatement.
// Button.test.jsx
import { render } from '@testing-library/react';
test('Button matches snapshot', () => {
const { container } = render(
<Button variant="primary">Click</Button>
);
expect(container).toMatchSnapshot();
});Cas d'usage : Pour détecter les changements involontaires dans le rendu des composants UI.
Plateforme d'analyse continue de la qualité du code qui détecte les bugs, vulnérabilités, code smells et la dette technique. Fournit un quality gâté configurable.
Comme un bilan de santé complet pour votre codebase : il analyse tout et vous donne un rapport détaillé avec un score global.
// sonar-project.properties
sonar.projectKey=my-app
sonar.sources=src
sonar.tests=tests
sonar.coverage.exclusions=**/*.test.ts
// Quality Gate: Coverage > 80%
// Duplications < 3%
// No new bugsCas d'usage : Pour suivre la qualité du code en continu et bloquer les PR qui dégradent les métriques définies.
Fichiers .map qui relient le code minifie/bundle au code source original. Permettent de debugger en production avec les fichiers originaux dans le navigateur.
Comme un plan de correspondance entre les noms de code et les vrais noms : quand une erreur survient, vous retrouvez le vrai fichier.
// vite.config.ts
export default defineConfig({
build: {
sourcemap: true, // genere .js.map
},
});
// Les source maps NE doivent PAS
// etre servies en public (securite)
// Les uploader vers Sentry/Datadog a la placeCas d'usage : Pour debugger les erreurs en production avec les numéros de ligne et fichiers originaux.
Outil de développement isole pour composants UI. Permet de documenter, visualiser et tester chaque composant indépendamment dans un catalogue interactif.
Comme un showroom de meubles : chaque pièce est exposée individuellement pour être examinée sous tous les angles.
// Button.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';
const meta: Meta<typeof Button> = { component: Button };
export default meta;
export const Primary: StoryObj = {
args: { variant: 'primary', children: 'Click' },
};Cas d'usage : Pour développer et documenter un design system avec un catalogue vivant de tous les composants.
Test qui pousse le système au-delà de ses limites normales pour identifier le point de rupture et vérifier son comportement en dégradation gracieuse.
Comme remplir un ascenseur au maximum et au-delà pour voir a quel moment il refuse de fermer les portes plutôt que de tomber.
// k6 stress test
export const options = {
stages: [
{ duration: '2m', target: 100 },
{ duration: '5m', target: 1000 }, // pic extreme
{ duration: '2m', target: 2000 }, // au-dela
{ duration: '5m', target: 0 }, // recovery
],
};Cas d'usage : Pour connaître les limites réelles du système et planifier le scaling avant qu'un incident ne se produise.
Librairie de test HTTP pour Node.js qui permet de tester les endpoints d'une API Express/Fastify sans démarrer un vrai serveur.
Comme tester un interphone sans sortir de l'immeuble : vous simulez l'appel de l'extérieur depuis l'intérieur.
const request = require('supertest');
const app = require('../app');
test('GET /users returns 200', async () => {
const res = await request(app)
.get('/users')
.expect(200);
expect(res.body).toHaveLength(3);
});Cas d'usage : Pour tester rapidement les routes d'une API Node.js dans les tests d'intégration sans serveur réel.
Compilateur JavaScript/TypeScript écrit en Rust, alternative ultra-rapide a Babel. Utilise par Next.js et peut servir de transpileur dans Vite ou Jest.
Comme remplacer un traducteur humain par un traducteur IA instantané : même résultat, vitesse décuplée.
// .swcrc
{
"jsc": {
"parser": { "syntax": "typescript", "tsx": true },
"transform": {
"react": { "runtime": "automatic" }
},
"target": "es2022"
}
}Cas d'usage : Pour remplacer Babel dans les projets ou le temps de transpilation est un goulot d'étranglement.
Test-Driven Development : méthodologie ou on écrit le test AVANT le code, en cycle Red-Green-Refactor. Force a designer l'API avant l'implémentation.
Comme écrire la liste de courses avant de cuisiner : vous savez exactement ce dont vous avez besoin avant de commencer.
// 1. RED: ecrire un test qui echoue
test('isPalindrome returns true', () => {
expect(isPalindrome('kayak')).toBe(true);
});
// 2. GREEN: code minimal pour passer
const isPalindrome = (s) => s === s.split('').reverse().join('');
// 3. REFACTOR: ameliorer sans casserCas d'usage : Pour le code métier complexe (algorithmes, règles de gestion) ou le design émerge naturellement des tests.
Alternative a la pyramide qui met l'accent sur les tests d'intégration. Forme de losange : peu de unit tests, beaucoup d'intégration, peu d'E2E. Adapte aux architectures microservices.
Comme tester surtout les connexions entre les pièces d'un puzzle plutôt que chaque pièce individuellement.
// Distribution diamant
// E2E: ~10%
// /\
// / \
// Integration: ~60% <- focus ici
// \ /
// \/
// Unit: ~30%Cas d'usage : Pour les systèmes distribues ou les bugs surviennent surtout aux frontières entre services.
Terme générique pour tout objet utilise a la place d'une dépendance réelle dans un test. Comprend 5 types : Dummy, Stub, Spy, Mock et Fake.
Comme une doublure au cinéma : elle remplace l'acteur principal pour les scènes dangereuses, chaque type de doublure a un role précis.
// Dummy: juste pour remplir un parametre
const dummyLogger = { log() {} };
// Stub: retourne une valeur fixe
const stubApi = { getUser: () => ({ name: 'Alice' }) };
// Spy: enregistre les appels
const spy = vi.fn();
// Mock: spy + comportement programme
// Fake: implementation simplifiee (in-memory DB)Cas d'usage : Pour isoler l'unité testée de ses dépendances (API, DB, services) et rendre les tests déterministes.
Principe ou chaque test est complètement indépendant des autres : il setup son propre état, s'exécute seul et nettoie après lui. Aucun test ne dépend de l'ordre d'exécution.
Comme des cabines d'essayage individuelles : chacune a son propre miroir, ses propres vêtements, et est nettoyée après chaque utilisation.
// Bonne isolation
beforeEach(() => {
db = createFreshDatabase();
});
afterEach(() => {
db.destroy();
});
// Chaque test a sa propre DB
// Pas de leaking d'etat entre testsCas d'usage : Pour garantir que les tests sont reproductibles et peuvent être exécutés dans n'importe quel ordre.
Modèle de stratégie de test en pyramide : beaucoup de tests unitaires (base), moins de tests d'intégration (milieu), et peu de tests E2E (sommet). Optimise le rapport coût/fiabilité.
Comme une pyramide alimentaire : les légumes (unit tests) en grande quantité a la base, les sucreries (E2E) en petite quantité au sommet.
// Proportions recommandees
// E2E: ~10% (lents, fragiles)
// /\
// / \
// Integration: ~20% (moderement rapides)
// / \
// / \
// Unit: ~70% (rapides, stables)
// ============Cas d'usage : Comme guide stratégique pour équilibrer les différents types de tests dans un projet.
Modèle de Kent C. Dodds en forme de trophée : static analysis en base, puis unit, puis intégration (le plus gros), puis E2E au sommet. Privilégié les tests d'intégration.
Comme un trophée sportif : la base fine (linting), le corps large (intégration) et la coupe fine en haut (E2E).
// Distribution trophee
// E2E: ~5% (sommet)
// Integration: ~40% (le gros du trophee)
// Unit: ~25% (tige)
// Static: ~30% (base: ESLint, TS)
// Plus de confiance par dollar investiCas d'usage : Pour les applications React/frontend ou les tests d'intégration avec Testing Library offrent le meilleur ROI.
Bibliothèque (Node.js, Java, Go, Python…) qui démarre à la volée de vrais services dans des conteneurs Docker jetables pour les tests d'intégration : PostgreSQL, Redis, Kafka, MongoDB… Le test obtient un port aléatoire, tourne contre le même moteur qu'en production, puis le conteneur est détruit. Fini les mocks de base de données et les bases « in-memory » qui divergent de la vraie.
Louer une cuisine équipée à l'heure pour répéter le plat exact, plutôt que de faire semblant avec des ustensiles en plastique.
import { PostgreSqlContainer } from '@testcontainers/postgresql';
import { beforeAll, afterAll, test, expect } from 'vitest';
let pg;
beforeAll(async () => {
pg = await new PostgreSqlContainer('postgres:16-alpine').start();
process.env.DATABASE_URL = pg.getConnectionUri(); // port aléatoire
await runMigrations();
}, 60_000);
afterAll(() => pg.stop());
test('crée un utilisateur', async () => {
const user = await userRepo.create({ email: '[email protected]' });
expect(user.id).toBeDefined(); // vraie contrainte UNIQUE, vrai SQL
});Cas d'usage : Tester des requêtes SQL, des migrations, des transactions ou un consommateur Kafka contre le moteur réel.
Famille de librairies (React, Vue, DOM) qui encourage a tester les composants comme un utilisateur les utilise, en ciblant les éléments par role, label ou texte plutôt que par sélecteur CSS.
Comme tester une télécommande en appuyant sur les boutons comme un utilisateur, sans démonter le boîtier pour vérifier les circuits.
import { render, screen, fireEvent } from '@testing-library/react';
test('shows greeting on click', () => {
render(<Greeter />);
fireEvent.click(screen.getByRole('button', { name: /say hi/i }));
expect(screen.getByText('Hello!')).toBeInTheDocument();
});Cas d'usage : Pour tester les composants React/Vue en se concentrant sur le comportement utilisateur plutôt que l'implémentation.
axe-core est le moteur open source de Deque qui vérifie une page contre les règles WCAG (contrastes, attributs ARIA, labels, ordre des titres). Intégré à Playwright via @axe-core/playwright (classe AxeBuilder : include, exclude, withTags, disableRules, analyze), il transforme l'accessibilité en assertion de test. Il ne détecte qu'une partie des problèmes : la gestion du focus et la pertinence des textes alternatifs restent à vérifier à la main.
Le correcteur orthographique d'un texte : il attrape les fautes mécaniques, pas le sens ; il faut encore relire.
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';
test('la page panier est accessible', async ({ page }) => {
await page.goto('/panier');
const results = await new AxeBuilder({ page })
.withTags(['wcag2a', 'wcag2aa', 'wcag21aa']) // niveau visé
.exclude('#widget-chat-tiers') // hors périmètre
.analyze();
// Chaque violation contient la règle, l'impact et les nœuds fautifs
expect(results.violations).toEqual([]);
});Cas d'usage : Empêcher qu'une régression d'accessibilité (bouton sans nom, contraste insuffisant) arrive en production, sur les parcours critiques.
Bundler incrémental écrit en Rust par Vercel. Depuis Next.js 16 (21 octobre 2025), Turbopack est stable et utilisé par défaut pour next dev et next build ; Vercel annonce des builds de production 2 à 5 fois plus rapides. Un projet avec configuration webpack personnalisée doit passer --webpack ou migrer sa configuration.
Comme un Webpack avec un moteur de Formule 1 : même philosophie de bundling mais avec une performance brute incomparable.
// next.config.js (Next.js 16+)
module.exports = {
// Turbopack est le défaut pour dev ET build : rien à activer
turbopack: {
// options éventuelles (alias, resolveExtensions...)
},
};
// Repli temporaire si config webpack héritée :
// next dev --webpack && next build --webpackCas d'usage : Tout projet Next.js 16+ : Turbopack est le défaut, plus besoin de drapeau --turbopack.
Test qui vérifie le comportement d'une seule unité de code (fonction, méthode, composant) de manière isolée. C'est la base de toute stratégie de test automatise.
Comme vérifier chaque ingrédient individuellement avant de cuisiner : le sel est bien du sel, la farine n'est pas périmée.
// sum.test.js
import { sum } from './sum';
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
test('handles negatives', () => {
expect(sum(-1, 1)).toBe(0);
});Cas d'usage : Pour valider chaque fonction métier indépendamment lors du développement quotidien.
Test qui compare des captures d'écran pixel par pixel pour détecter les changements visuels involontaires dans l'interface. Utilise des outils comme Chromatic ou Percy.
Comme superposer deux photos d'un tableau et chercher la moindre différence de couleur ou de position.
// Avec Storybook + Chromatic
// 1. Ecrire les stories
export const Primary = () => <Button primary>OK</Button>;
// 2. Chromatic capture automatiquement
// 3. Toute diff visuelle => review requise
// npx chromatic --project-token=xxxCas d'usage : Pour les design systems et applications ou la cohérence visuelle pixel-perfect est critique.
Outil de build nouvelle génération par Evan You (créateur de Vue). Dev server ultra-rapide base sur ESM natif, build de production avec Rollup. Standard moderne.
Comme passer d'un four traditionnel a un micro-ondes : le résultat est le même, mais la vitesse est incomparable.
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
server: { port: 3000 },
build: { sourcemap: true },
});Cas d'usage : Pour tout nouveau projet frontend (React, Vue, Svelte) nécessitant un dev server rapide et un build optimise.
Framework de test propulsé par Vite, compatible avec l'API de Jest, avec ESM, TypeScript et JSX sans configuration. Vitest 4.0, publié le 22 octobre 2025, rend le mode navigateur stable (fournisseurs séparés @vitest/browser-playwright, @vitest/browser-webdriverio, @vitest/browser-preview), ajoute la régression visuelle (toMatchScreenshot) et le support des traces Playwright. VoidZero, l'entreprise qui porte Vite et Vitest, a rejoint Cloudflare le 4 juin 2026 ; les outils restent sous licence MIT.
Comme Jest mais avec un moteur turbo : même volant, mêmes pédales, mais ca va beaucoup plus vite.
// vitest.config.ts (Vitest 4)
import { defineConfig } from 'vitest/config';
import { playwright } from '@vitest/browser-playwright';
export default defineConfig({
test: {
globals: true,
// Mode navigateur stable depuis Vitest 4.0
browser: {
enabled: true,
provider: playwright(),
instances: [{ browser: 'chromium' }],
},
},
});Cas d'usage : Pour tout nouveau projet utilisant Vite comme bundler, offrant une DX supérieure a Jest.
Mode de Vitest qui exécute les tests dans un vrai navigateur (via Playwright ou WebDriverIO) au lieu de simuler le DOM avec jsdom ou happy-dom. Stable depuis Vitest 4.0 (22 octobre 2025), il s'installe avec un fournisseur dédié (@vitest/browser-playwright, @vitest/browser-webdriverio, @vitest/browser-preview) et apporte la régression visuelle (toMatchScreenshot) et les traces Playwright, avec la même API de test.
Tester une voiture sur une vraie route (navigateur) plutôt que sur un banc qui imite la route (jsdom) : mêmes essais, mais on découvre les nids-de-poule réels.
// Button.test.tsx – tourne dans Chromium, pas dans jsdom
import { render } from 'vitest-browser-react';
import { page } from 'vitest/browser';
import { expect, test } from 'vitest';
import { Button } from './Button';
test('clic → état actif', async () => {
await render(<Button>Payer</Button>);
const btn = page.getByRole('button', { name: 'Payer' });
await btn.click(); // vrai événement navigateur
await expect.element(btn).toHaveAttribute('aria-pressed', 'true');
await expect(btn).toMatchScreenshot(); // régression visuelle (Vitest 4)
});Cas d'usage : Composants dépendant de vraies API navigateur (layout, IntersectionObserver, CSS, canvas) que jsdom ne reproduit pas fidèlement.
Gestionnaire de versions Node.js écrit en Rust, ultra-rapide. Épingle la version Node.js et npm dans package.json pour toute l'équipe automatiquement.
Comme un thermostat qui ajuste la température automatiquement dans chaque pièce : chaque projet a sa version Node.js sans intervention.
// Installation + pin
volta install node@20
volta pin [email protected]
volta pin npm@10
// package.json (automatique)
"volta": {
"node": "20.11.0",
"npm": "10.2.0"
}Cas d'usage : Pour garantir que toute l'équipe utilise la même version Node.js sans configuration manuelle.
Bundler JavaScript historique et très configurable (loaders, plugins). Toujours maintenu, mais concurrencé : Rspack 1.0 (août 2024) est un bundler Rust compatible avec l'API webpack, et Next.js 16 (21 octobre 2025) utilise Turbopack par défaut en développement et en production, ne gardant webpack qu'en repli (next build --webpack).
Comme une usine d'assemblage automobile : extrêmement flexible et puissante, mais complexe a configurer et maintenir.
// webpack.config.js
module.exports = {
entry: './src/index.js',
output: { filename: 'bundle.[contenthash].js' },
module: {
rules: [
{ test: /\.tsx?$/, use: 'ts-loader' },
{ test: /\.css$/, use: ['style-loader', 'css-loader'] }
]
},
};Cas d'usage : Pour les projets legacy ou les cas nécessitant une configuration fine du bundling avec des plugins spécifiques.
Gestionnaire de paquets alternatif a npm. Yarn Classic (v1) a popularise le lock file. Yarn Berry (v3+) utilise Plug'n'Play (PnP) sans node_modules.
Comme un concurrent d'Amazon qui a innove avec la livraison rapide, forçant l'original a s'améliorer.
yarn install # install deps
yarn add express # ajouter une dep
yarn add -D vitest # dep de dev
yarn test # lancer un script
yarn dlx create-next-app # equivalent npx
yarn workspaces foreach test # monorepoCas d'usage : Pour les équipes ayant investi dans l'écosystème Yarn, notamment avec PnP pour des installs plus rapides.