Introduction
« Ca marche sur ma machine. » Cette phrase, devenue un meme dans le monde du developpement, illustre un probleme fondamental : sans tests automatises, vous ne pouvez pas garantir que votre code fonctionne dans toutes les situations.
Les tests automatises sont des programmes qui verifient que votre code se comporte comme prevu. Ils s'executent en quelques secondes ou minutes et vous alertent immediatement en cas de regression — quand une modification casse une fonctionnalite existante.
Selon le rapport State of Testing 2024, 78 % des equipes de developpement utilisent des tests automatises, et les equipes qui testent regulierement rapportent 40 % de bugs en moins en production.
Les types de tests
Les tests unitaires
Un test unitaire verifie le comportement d'une fonction ou d'un composant isole. C'est la brique de base de la pyramide des tests.
// utils/formatPrice.js
function formatPrice(cents) {
return (cents / 100).toFixed(2) + ' euros';
}
// utils/formatPrice.test.js
describe('formatPrice', () => {
test('formate correctement un prix en centimes', () => {
expect(formatPrice(1999)).toBe('19.99 euros');
});
test('gere le prix zero', () => {
expect(formatPrice(0)).toBe('0.00 euros');
});
test('gere les grands montants', () => {
expect(formatPrice(100000)).toBe('1000.00 euros');
});
});Caracteristiques : rapides (millisecondes), nombreux, sans dependances externes.
Les tests d'integration
Un test d'integration verifie que plusieurs composants fonctionnent ensemble : un formulaire qui appelle une API, une page qui charge des donnees depuis une base, etc.
// integration/checkout.test.js
test('le parcours d'achat fonctionne', async () => {
// Rendre le composant avec un produit
render(<CheckoutPage product={mockProduct} />);
// Remplir le formulaire
await userEvent.type(screen.getByLabelText('Email'), '[email protected]');
await userEvent.type(screen.getByLabelText('Carte'), '4242424242424242');
// Soumettre
await userEvent.click(screen.getByText('Payer'));
// Verifier le resultat
expect(await screen.findByText('Paiement confirme')).toBeInTheDocument();
});Les tests end-to-end (E2E)
Un test E2E simule le parcours complet d'un utilisateur dans un navigateur reel : il clique, saisit du texte, navigue entre les pages et verifie le resultat final.
// e2e/login.spec.js (Playwright)
test('un utilisateur peut se connecter', async ({ page }) => {
await page.goto('https://monsite.fr/connexion');
await page.fill('input[name="email"]', '[email protected]');
await page.fill('input[name="password"]', 'motdepasse123');
await page.click('button[type="submit"]');
await expect(page).toHaveURL('/tableau-de-bord');
await expect(page.locator('h1')).toContainText('Bienvenue, Jean');
});Caracteristiques : lents (secondes a minutes), peu nombreux, fragiles mais tres realistes.
La pyramide des tests
La metaphore de la pyramide des tests (Mike Cohn, 2009) recommande :
- Beaucoup de tests unitaires (base large, rapides, fiables)
- Un nombre modere de tests d'integration
- Peu de tests E2E (sommet, lents, couteux)
Les outils en 2026
Pour JavaScript/TypeScript
- Vitest : le framework de test le plus rapide pour l'ecosysteme Vite. Compatible avec l'API de Jest. Notre recommandation pour les projets modernes.
- Jest : le standard historique, toujours tres utilise. Developpe par Meta.
- Testing Library : pour tester les composants React, Vue ou Angular du point de vue de l'utilisateur.
- Playwright : le meilleur outil E2E en 2026. Supporte Chromium, Firefox et WebKit. Developpe par Microsoft.
- Cypress : alternative a Playwright, tres populaire pour les tests E2E avec une interface visuelle.
Pour d'autres langages
- Python : pytest (le standard de facto)
- PHP : PHPUnit + Pest (syntaxe moderne)
- Go : package testing integre au langage
Les bonnes pratiques
1. Testez le comportement, pas l'implementation
// Mauvais : teste l'implementation interne
test('appelle setState avec la bonne valeur', () => { ... });
// Bon : teste le comportement observable
test('affiche le prix mis a jour quand on change la quantite', () => { ... });2. Un test = un scenario
Chaque test doit verifier un seul aspect. Si un test echoue, vous devez immediatement savoir ce qui est casse.
3. Nommez vos tests clairement
Le nom du test doit decrire le scenario en langage naturel :
- « affiche un message d'erreur quand l'email est invalide »
- « redirige vers la page de connexion si l'utilisateur n'est pas authentifie »
- « calcule correctement la TVA a 20 % »
4. Evitez les tests fragiles
Un test fragile echoue pour des raisons non liees au code teste (changement de CSS, ordre des elements, timing). Pour les eviter :
- Selectionnez les elements par role (
getByRole) ou par label (getByLabelText) plutot que par classe CSS - Utilisez des
waitForoufindBypour les elements asynchrones - Evitez les
sleepousetTimeoutdans vos tests
5. Integrez les tests au CI/CD
Les tests doivent s'executer automatiquement a chaque push ou pull request via votre pipeline CI/CD (GitHub Actions, GitLab CI, etc.). Un test qui n'est pas execute regulierement est un test inutile.
Conclusion
Les tests automatises sont un investissement qui se rentabilise rapidement : moins de bugs, plus de confiance pour refactorer et une documentation vivante de votre code. Commencez par des tests unitaires sur vos fonctions critiques, puis ajoutez progressivement des tests d'integration et quelques tests E2E pour les parcours essentiels.
