Experimentation ou deux variantes (A et B) sont presentees a des groupes d'utilisateurs differents pour mesurer laquelle performe le mieux selon des metriques definies.
Comme un restaurant qui teste deux recettes de dessert sur deux tables differentes et mesure laquelle est la plus commandee.
// 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 decisions produit basees sur des donnees reelles plutot que des opinions (boutons, textes, parcours).
Pattern de structuration des tests en 3 phases : Arrange (preparer les donnees), Act (executer l'action), Assert (verifier le resultat). Rend les tests lisibles et uniformes.
Comme une recette de cuisine : preparer les ingredients (Arrange), cuisiner (Act), gouter et verifier (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 lisibilite et la coherence.
Test qui verifie qu'une fonctionnalite repond aux criteres d'acceptation definis par le Product Owner ou le client. Souvent ecrit en langage naturel (Gherkin).
Comme la checklist du client lors de la reception d'une maison neuve : chaque point du cahier des charges est verifie.
// En Gherkin (Cucumber)
// Feature: Connexion utilisateur
// Scenario: Login reussi
// Given un utilisateur inscrit "alice@test.com"
// 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 criteres d'acceptation du Product Owner en tests executables.
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 necessitant des transformations custom ou un support navigateurs tres anciens.
Fichiers index.ts qui re-exportent tout un dossier. Pratique pour les imports mais cause des problemes de tree-shaking et de performance en chargeant du code inutilise.
Comme une porte d'entree unique pour un centre commercial : pratique pour trouver, mais vous devez traverser tout le batiment meme 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 publiees, mais a eviter dans le code applicatif pour les performances.
Behavior-Driven Development : extension du TDD qui exprime les tests en langage metier (Given-When-Then) pour favoriser la collaboration entre devs, QA et PO.
Comme ecrire le scenario d'un film avant de le tourner : tout le monde (realisateur, 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 equipes techniques et metier est critique pour la qualite.
Regles GitHub/GitLab sur les branches protegees (main, develop) : requiert reviews, CI verte, signatures, et interdit les force push. Filet de securite essentiel.
Comme les barrieres de securite sur une autoroute : elles empechent les vehicules de sortir de la route meme 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 proteger 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 dependances lourdes et les opportunites 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 detecter les dependances qui gonflent inutilement le bundle.
Strategie de deploiement ou la nouvelle version est deployee sur un petit pourcentage du trafic pour detecter les problemes avant un rollout complet.
Comme le canari dans la mine de charbon : s'il s'arrete de chanter, on sait qu'il y a un probleme 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 deployer en production avec un filet de securite, en limitant l'impact d'un bug a 5% des utilisateurs.
Outil de gestion de versions pour monorepos. Chaque PR ajoute un fichier changeset decrivant le changement et son semver, puis l'outil genere le changelog et publie automatiquement.
Comme un carnet de bord de modifications : chaque mecanicien note ce qu'il a change, et le systeme 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 necessitant un versioning et changelog automatises.
Discipline qui consiste a injecter volontairement des pannes (reseau, serveur, latence) en production pour verifier la resilience du systeme. Popularisee par Netflix (Chaos Monkey).
Comme un exercice d'evacuation incendie : on simule la catastrophe pour verifier que tout le monde sait reagir 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 systemes distribues critiques afin de decouvrir les failles de resilience avant qu'elles ne causent des incidents reels.
Metrique qui mesure le pourcentage de code execute par les tests (lignes, branches, fonctions). Utile comme indicateur mais trompeur comme objectif unique.
Comme mesurer le pourcentage de pieces visitees 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 detecter les zones non testees, avec un seuil raisonnable (70-80%).
Pratique ou un ou plusieurs pairs examinent le code soumis avant son integration. Ameliore la qualite, partage les connaissances et detecte les bugs humainement.
Comme la relecture d'un manuscrit par un editeur : il detecte les fautes et les incoherences 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 qualite et partager les connaissances dans l'equipe.
Fichier GitHub qui assigne automatiquement des reviewers aux PR en fonction des fichiers modifies. Garantit que les experts appropriees reviewent chaque changement.
Comme un organigramme de responsabilites : chaque zone du batiment a un responsable attitre 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 equipes 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 accedez 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 equipes distribuees voulant un setup zero-config.
Outil qui verifie que les messages de commit respectent un format conventionnel (Conventional Commits). Permet l'automatisation du changelog et du versioning semantique.
Comme un formulaire avec des champs obligatoires : votre message de commit doit respecter le modele pour etre 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 verifie que l'interface (contrat) entre un consommateur et un fournisseur d'API est respectee. Chaque cote teste independamment sa conformite au contrat.
Comme un contrat de location : le locataire et le proprietaire verifient chacun que les clauses sont respectees 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 equipes peuvent deployer independamment sans casser les integrations.
Framework de test E2E et composant qui s'execute directement dans le navigateur, offrant un time-travel debugger visuel et une DX excellente.
Comme une camera de surveillance dans votre app : vous voyez chaque clic, chaque requete, et vous pouvez rembobiner.
// login.cy.js
describe('Login', () => {
it('logs in successfully', () => {
cy.visit('/login');
cy.get('#email').type('alice@test.com');
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.
Specification permettant de definir un environnement de developpement reproductible dans un conteneur Docker. Supporte par VS Code, GitHub Codespaces et JetBrains.
Comme un bureau portable pre-equipe : ou que vous alliez, vous retrouvez exactement le meme 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 developpeur en 5 minutes avec un environnement identique a toute l'equipe.
Outil qui charge et decharge automatiquement des variables d'environnement quand vous entrez ou sortez d'un repertoire. Base sur un fichier .envrc versionne.
Comme un badge d'acces 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 gerer automatiquement les variables d'environnement par projet sans .env global.
Fichiers de configuration commencant 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 preferences personnelles (siege, 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 reel d'un utilisateur a travers l'application complete (navigateur, API, BDD). Valide le systeme dans son ensemble.
Comme un client mystere qui entre dans un restaurant, commande, mange et paye pour verifier toute l'experience.
// 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', 'test@mail.com');
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 definit les regles basiques d'edition (indentation, fin de ligne, charset) pour tous les editeurs et IDE.
Comme une regle commune pour toute la classe : que vous utilisiez un stylo bleu ou noir, tout le monde ecrit sur les memes 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 equipe avec differents editeurs.
Bundler et transpileur JavaScript ecrit 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 regional : meme destination, mais la vitesse est dans une autre categorie.
// 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 detecter les erreurs, les mauvaises pratiques et les violations de style. Entierement configurable par regles 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 coherent dans l'equipe.
Fonction qui genere des objets de test avec des valeurs par defaut sensibles et la possibilite de surcharger certains champs. Plus flexible que les fixtures statiques.
Comme un moule a gateau avec des options : le moule donne la forme de base, mais vous choisissez la garniture pour chaque gateau.
// 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 generer des donnees de test variees sans dupliquer la creation d'objets dans chaque test.
Implementation de HMR specifique a React par Meta. Preserve l'etat des hooks (useState, useRef) lors des modifications de composants, meme en cas d'erreur de syntaxe.
Comme un peintre qui retouche un tableau en direct : les couleurs changent instantanement 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 defaut dans les projets React modernes pour un feedback instantane lors du developpement.
Donnees de test predefinies utilisees pour mettre en place un etat initial connu et reproductible avant chaque test. Peut etre un fichier JSON, un seed de base de donnees, etc.
Comme les decors d'une scene de theatre : mis en place avant chaque representation 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'integration necessitant un etat de base de donnees connu et reproductible.
Test non deterministe qui passe ou echoue de maniere aleatoire sans changement de code. Causes frequentes : timing, ordre d'execution, etat partage, dependances externes.
Comme un detecteur de fumee qui sonne parfois sans raison : on finit par l'ignorer, meme 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'equipe dans la CI.
Fast Node Manager, gestionnaire de versions Node.js ecrit en Rust. Plus rapide que nvm, supporte .node-version et .nvmrc. Leger et cross-platform.
Comme nvm mais avec un moteur turbo : meme fonction, mais le switch de version est instantane.
# 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 gerer les versions Node.js avec auto-switch par projet.
Format de description des tests issu du BDD : Given (contexte initial), When (action), Then (resultat attendu). Equivalent de AAA en langage metier.
Comme raconter une histoire : 'Etant donne que... Quand... Alors...' — meme 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 metier doit etre comprehensible par les non-techniques.
Tests completement auto-contenus sans aucune dependance externe (reseau, API tierces, horloge systeme). Tout est controle et reproductible a 100%.
Comme un laboratoire en salle blanche : l'environnement est totalement controle, rien de l'exterieur ne peut influencer le resultat.
// 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 acces reseau.
Technologie qui remplace les modules modifies dans le navigateur sans recharger la page, preservant l'etat de l'application. Accelere considerablement le cycle de developpement.
Comme changer une roue sur une voiture en mouvement : vous remplacez la piece sans arreter 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 developpement pour voir instantanement les changements sans perdre l'etat de l'app (formulaires, navigation).
Husky execute des git hooks (pre-commit, pre-push) et lint-staged applique des commandes (lint, format) uniquement sur les fichiers stages. Ensemble, ils garantissent la qualite avant chaque commit.
Comme un vigile a l'entree d'un club : il verifie 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 verifie que plusieurs modules ou services fonctionnent correctement ensemble. Il valide les interactions entre composants reels (API, base de donnees, etc.).
Comme verifier que le moteur, la boite de vitesse et les roues fonctionnent ensemble, pas juste chacun separement.
// 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 metier et la base de donnees collaborent correctement.
Framework de test JavaScript par Meta, tout-en-un avec runner, assertions, mocking et coverage integres. Standard de facto pour les projets React.
Comme une boite a outils complete : vous avez le marteau, le tournevis et le metre dans le meme kit, sans rien installer de plus.
// math.test.js
describe('Math utils', () => {
test('multiply', () => {
expect(multiply(3, 4)).toBe(12);
});
test('async fetch', async () => {
const data = await fetchUser(1);
expect(data).toHaveProperty('name');
});
});Cas d'usage : Pour tout projet React ou Node.js necessitant un framework de test complet et bien documente.
Test qui simule une charge utilisateur realiste sur le systeme pour mesurer ses performances (temps de reponse, debit, utilisation des ressources) sous conditions normales et pics.
Comme tester un pont en y faisant passer progressivement de plus en plus de camions pour verifier 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 verifier que l'infrastructure tient la charge prevue.
Fichier (package-lock.json, pnpm-lock.yaml, yarn.lock) qui enregistre les versions exactes de toutes les dependances installees. Garantit des installations reproductibles.
Comme une photo de votre etagere d'ingredients avec les marques et dates exactes : la prochaine fois, vous achetez exactement la meme 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 memes versions de dependances.
Gestionnaire polyglotte de versions d'outils (ex-rtx, successeur d'asdf en Rust). Gere 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 equipes polyglotte qui veulent un seul outil pour gerer 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 separement : plus de flexibilite 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 preferent une approche modulaire avec choix des plugins.
Le stub fournit des reponses predefinies sans verifier les appels. Le mock verifie en plus que les interactions attendues ont bien eu lieu (nombre d'appels, arguments).
Le stub est un distributeur automatique (il donne la reponse), le mock est un serveur de restaurant qui note ce que vous commandez ET verifie 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('alice@mail.com');
expect(sendEmail).toHaveBeenCalledWith('alice@mail.com');
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 gerer plusieurs packages/apps dans un seul repo (Turborepo, Nx, Lerna). Offrent caching, parallelisme et graphes de dependances intelligents.
Comme un chef de chantier qui coordonne plusieurs equipes sur un meme site : il optimise l'ordre des travaux et evite les doublons.
// turbo.json (Turborepo)
{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"test": {
"dependsOn": ["build"]
}
}
}Cas d'usage : Pour les organisations avec plusieurs packages partageant du code (design system, shared utils, apps).
Mock Service Worker intercepte les requetes reseau au niveau du Service Worker (navigateur) ou de Node.js pour simuler des API sans modifier le code applicatif.
Comme un standardiste qui intercepte les appels et repond a la place du destinataire, sans que l'appelant ne le sache.
// handlers.js
import { http, HttpResponse } from 'msw';
export const handlers = [
http.get('/api/users', () => {
return HttpResponse.json([
{ id: 1, name: 'Alice' }
]);
}),
];Cas d'usage : Pour mocker les API externes dans les tests frontend et le developpement local sans backend disponible.
Technique qui modifie volontairement le code source (mutations) pour verifier que les tests detectent bien ces changements. Si un mutant survit, les tests sont insuffisants.
Comme verifier qu'un detecteur de fumee fonctionne en allumant une petite flamme : s'il ne sonne pas, il est defaillant.
// 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 evaluer la qualite reelle des tests au-dela du simple code coverage qui peut donner un faux sentiment de securite.
Dossier contenant toutes les dependances installees d'un projet Node.js. Peut devenir tres volumineux (facilement 500Mo+). Toujours dans le .gitignore.
Comme un entrepot geant rempli de toutes les pieces necessaires a votre usine : enorme 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 defaut pour stocker les dependances npm, utilisee par tous les outils Node.js.
Node Package Manager, le gestionnaire de paquets par defaut de Node.js. Gere les dependances, les scripts et le registre de packages le plus vaste au monde.
Comme un supermarche geant ou vous trouvez tous les ingredients (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 execute des packages binaires sans les installer globalement, en les telechargant temporairement. npm exec est l'equivalent moderne integre a npm depuis v7.
Comme louer un outil pour un jour au lieu de l'acheter : vous l'utilisez une fois et il disparait.
# 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 executer des CLI ponctuels (scaffolding, init) sans polluer les dependances 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 connait, 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 gerer les versions Node.js sur les systemes Unix, surtout quand l'equipe l'utilise deja.
Framework de test E2E par Microsoft supportant Chromium, Firefox et WebKit avec auto-wait, traces et parallelisme natif. Plus puissant que Cypress pour le multi-navigateur.
Comme un pilote automatique polyglotte : il conduit sur Chrome, Firefox et Safari avec la meme aisance.
// login.spec.ts
import { test, expect } from '@playwright/test';
test('login flow', async ({ page }) => {
await page.goto('/login');
await page.fill('#email', 'alice@test.com');
await page.fill('#password', 'secret');
await page.click('button[type=submit]');
await expect(page).toHaveURL('/dashboard');
});Cas d'usage : Pour les tests E2E necessitant du multi-navigateur, du parallelisme avance ou de la capture de traces.
Gestionnaire de paquets rapide et economique en espace disque grace a un store global et des liens symboliques. Strict par defaut, empechant l'acces aux dependances fantomes.
Comme une bibliotheque municipale : un seul exemplaire de chaque livre, et chaque habitant y accede par reference plutot que par copie.
pnpm install # install deps
pnpm add express # ajouter une dep
pnpm add -D vitest # dep de dev
pnpm run test # lancer un script
pnpm dlx create-next-app # equivalent npx
pnpm --filter @app/web test # monorepoCas d'usage : Pour les monorepos et les projets avec beaucoup de dependances, offrant rapidite et rigueur.
Outil de transformation CSS via plugins. Autoprefixer (ajout de prefixes vendeur) et Tailwind CSS sont ses plugins les plus connus. Babel equivalent pour le CSS.
Comme une chaine de montage pour le CSS : chaque plugin ajoute une transformation specifique 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 prefixes 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 standardisees (description, tests, screenshots, checklist).
Comme un formulaire medical pre-imprime : le medecin 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 necessaires.
Formateur de code opinionne qui reformate automatiquement JS, TS, CSS, JSON, HTML et Markdown. Elimine les debats de style en imposant un format unique.
Comme un repasseur automatique pour vos vetements : 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 eliminer les discussions de style en code review.
Approche de test ou au lieu de cas specifiques, on definit des proprietes que le code doit toujours respecter, et le framework genere automatiquement des centaines d'entrees aleatoires.
Comme dire a un crash-test 'la voiture doit proteger le passager peu importe l'angle de l'impact' plutot que tester 3 angles specifiques.
// 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 verifie qu'une modification du code n'a pas casse une fonctionnalite existante. La suite de tests existante sert naturellement de filet de regression.
Comme verifier que la reparation 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 regression pour garantir qu'il ne reviendra jamais.
Bots qui creent automatiquement des PR pour mettre a jour les dependances. Renovate est plus configurable, Dependabot est integre nativement dans GitHub.
Comme un assistant qui verifie chaque jour si vos fournisseurs ont de nouvelles versions et vous prepare les bons de commande.
// renovate.json
{
"extends": ["config:recommended"],
"packageRules": [
{
"matchUpdateTypes": ["minor", "patch"],
"automerge": true
}
],
"schedule": ["every weekend"]
}Cas d'usage : Pour maintenir les dependances a jour automatiquement et eviter l'accumulation de dette technique de securite.
Bundler JavaScript specialise dans la generation 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 entierement le versioning semantique (semver) et la publication npm a partir des messages de commit conventionnels. Zero intervention manuelle.
Comme un robot comptable qui analyse vos factures et genere 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 publiees sur npm qui veulent un versioning 100% automatise et fiable.
Test rapide et superficiel qui verifie que les fonctionnalites principales de l'application fonctionnent apres un deploiement. Ne teste pas en profondeur.
Comme tourner la cle de contact pour verifier que le moteur demarre, 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 : Apres chaque deploiement pour detecter immediatement si quelque chose de fondamental est casse.
Test qui capture la sortie d'un composant (HTML, JSON) et la compare a une reference enregistree. Toute difference inattendue fait echouer le test.
Comme prendre une photo de votre salon et comparer chaque jour : si un meuble a bouge, vous le detectez immediatement.
// 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 detecter les changements involontaires dans le rendu des composants UI.
Plateforme d'analyse continue de la qualite du code qui detecte les bugs, vulnerabilites, code smells et la dette technique. Fournit un quality gate configurable.
Comme un bilan de sante complet pour votre codebase : il analyse tout et vous donne un rapport detaille 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 qualite du code en continu et bloquer les PR qui degradent les metriques definies.
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 numeros de ligne et fichiers originaux.
Outil de developpement isole pour composants UI. Permet de documenter, visualiser et tester chaque composant independamment dans un catalogue interactif.
Comme un showroom de meubles : chaque piece est exposee individuellement pour etre examinee 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 developper et documenter un design system avec un catalogue vivant de tous les composants.
Test qui pousse le systeme au-dela de ses limites normales pour identifier le point de rupture et verifier son comportement en degradation gracieuse.
Comme remplir un ascenseur au maximum et au-dela pour voir a quel moment il refuse de fermer les portes plutot 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 connaitre les limites reelles du systeme 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 demarrer un vrai serveur.
Comme tester un interphone sans sortir de l'immeuble : vous simulez l'appel de l'exterieur depuis l'interieur.
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'integration sans serveur reel.
Compilateur JavaScript/TypeScript ecrit 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 instantane : meme resultat, vitesse decuplee.
// .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'etranglement.
Test-Driven Development : methodologie ou on ecrit le test AVANT le code, en cycle Red-Green-Refactor. Force a designer l'API avant l'implementation.
Comme ecrire 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 metier complexe (algorithmes, regles de gestion) ou le design emerge naturellement des tests.
Alternative a la pyramide qui met l'accent sur les tests d'integration. Forme de losange : peu de unit tests, beaucoup d'integration, peu d'E2E. Adapte aux architectures microservices.
Comme tester surtout les connexions entre les pieces d'un puzzle plutot que chaque piece individuellement.
// Distribution diamant
// E2E: ~10%
// /\
// / \
// Integration: ~60% <- focus ici
// \ /
// \/
// Unit: ~30%Cas d'usage : Pour les systemes distribues ou les bugs surviennent surtout aux frontieres entre services.
Terme generique pour tout objet utilise a la place d'une dependance reelle dans un test. Comprend 5 types : Dummy, Stub, Spy, Mock et Fake.
Comme une doublure au cinema : elle remplace l'acteur principal pour les scenes dangereuses, chaque type de doublure a un role precis.
// 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'unite testee de ses dependances (API, DB, services) et rendre les tests deterministes.
Principe ou chaque test est completement independant des autres : il setup son propre etat, s'execute seul et nettoie apres lui. Aucun test ne depend de l'ordre d'execution.
Comme des cabines d'essayage individuelles : chacune a son propre miroir, ses propres vetements, et est nettoyee apres 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 etre executes dans n'importe quel ordre.
Modele de strategie de test en pyramide : beaucoup de tests unitaires (base), moins de tests d'integration (milieu), et peu de tests E2E (sommet). Optimise le rapport cout/fiabilite.
Comme une pyramide alimentaire : les legumes (unit tests) en grande quantite a la base, les sucreries (E2E) en petite quantite au sommet.
// Proportions recommandees
// E2E: ~10% (lents, fragiles)
// /\
// / \
// Integration: ~20% (moderement rapides)
// / \
// / \
// Unit: ~70% (rapides, stables)
// ============Cas d'usage : Comme guide strategique pour equilibrer les differents types de tests dans un projet.
Modele de Kent C. Dodds en forme de trophee : static analysis en base, puis unit, puis integration (le plus gros), puis E2E au sommet. Privilegie les tests d'integration.
Comme un trophee sportif : la base fine (linting), le corps large (integration) 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'integration avec Testing Library offrent le meilleur ROI.
Famille de librairies (React, Vue, DOM) qui encourage a tester les composants comme un utilisateur les utilise, en ciblant les elements par role, label ou texte plutot que par selecteur CSS.
Comme tester une telecommande en appuyant sur les boutons comme un utilisateur, sans demonter le boitier pour verifier 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 plutot que l'implementation.
Bundler incremental ecrit en Rust par Vercel, successeur spirituel de Webpack. Optimise pour les tres grands projets avec du caching granulaire au niveau des fonctions.
Comme un Webpack avec un moteur de Formule 1 : meme philosophie de bundling mais avec une performance brute incomparable.
// next.config.js (Next.js 15+)
module.exports = {
// Turbopack active par defaut en dev
// next dev --turbopack
};
// Pas de config separee:
// Turbopack est integre a Next.jsCas d'usage : Pour les projets Next.js de grande taille ou le dev server Webpack est devenu trop lent.
Test qui verifie le comportement d'une seule unite de code (fonction, methode, composant) de maniere isolee. C'est la base de toute strategie de test automatise.
Comme verifier chaque ingredient individuellement avant de cuisiner : le sel est bien du sel, la farine n'est pas perimee.
// 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 metier independamment lors du developpement quotidien.
Test qui compare des captures d'ecran pixel par pixel pour detecter 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 difference 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 coherence visuelle pixel-perfect est critique.
Outil de build nouvelle generation par Evan You (createur 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 resultat est le meme, 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) necessitant un dev server rapide et un build optimise.
Framework de test ultra-rapide compatible avec l'API Jest, propulse par Vite. Support natif d'ESM, TypeScript et JSX sans configuration supplementaire.
Comme Jest mais avec un moteur turbo : meme volant, memes pedales, mais ca va beaucoup plus vite.
// vite.config.ts
export default defineConfig({
test: {
globals: true,
environment: 'jsdom',
},
});
// API identique a Jest
// test, expect, vi.fn(), vi.mock()Cas d'usage : Pour tout nouveau projet utilisant Vite comme bundler, offrant une DX superieure a Jest.
Gestionnaire de versions Node.js ecrit en Rust, ultra-rapide. Epingle la version Node.js et npm dans package.json pour toute l'equipe automatiquement.
Comme un thermostat qui ajuste la temperature automatiquement dans chaque piece : chaque projet a sa version Node.js sans intervention.
// Installation + pin
volta install node@20
volta pin node@20.11.0
volta pin npm@10
// package.json (automatique)
"volta": {
"node": "20.11.0",
"npm": "10.2.0"
}Cas d'usage : Pour garantir que toute l'equipe utilise la meme version Node.js sans configuration manuelle.
Bundler JavaScript historique et ultra-configurable. Transforme les modules, assets et dependances en bundles optimises pour le navigateur. Ecosysteme de plugins et loaders tres riche.
Comme une usine d'assemblage automobile : extremement 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 necessitant une configuration fine du bundling avec des plugins specifiques.
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, forcant l'original a s'ameliorer.
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 equipes ayant investi dans l'ecosysteme Yarn, notamment avec PnP pour des installs plus rapides.
Autres stacks