Man working on code on a laptop in an office, showcasing modern remote work setup.

Flaky Tests en CI/CD : Causes, Impacts et Solutions

Introduction

Dans de nombreuses équipes de développement modernes, les pipelines CI/CD sont devenus le cœur du cycle de livraison logicielle. Chaque commit déclenche automatiquement des builds, des analyses, des tests et parfois même des déploiements en production.

Pourtant, un problème continue de ralentir les équipes techniques malgré les progrès des outils d’automatisation : les flaky tests.

Un flaky test est un test qui échoue de manière aléatoire sans qu’aucune modification réelle du code n’ait été introduite. Il peut réussir une fois puis échouer au prochain lancement, sans raison apparente.

Ce phénomène est souvent sous-estimé. Beaucoup d’équipes considèrent ces instabilités comme « normales » ou temporaires. En réalité, les flaky tests peuvent progressivement détruire la fiabilité d’un pipeline CI/CD, ralentir les développeurs, augmenter les coûts d’infrastructure et réduire la confiance dans l’automatisation.

Dans cet article, nous allons voir :

  • ce qu’est réellement un flaky test
  • pourquoi ils apparaissent
  • leur impact sur les pipelines CI/CD
  • les causes techniques les plus fréquentes
  • les meilleures pratiques pour les éliminer durablement

Qu’est-ce qu’un Flaky Test ?

Un flaky test est un test automatisé dont le résultat varie sans changement fonctionnel du code.

Autrement dit :

  • le test passe parfois ;
  • le test échoue parfois ;
  • le comportement est imprévisible.

Exemple classique :

  • un test Selenium réussit localement ;
  • le même test échoue dans GitLab CI ;
  • un relancement du pipeline le fait repasser au vert.

Ce type de comportement crée rapidement de la confusion dans les équipes.

Les principaux types de flaky tests

1. Les flaky tests liés au timing

Les plus fréquents.

Le test dépend d’un délai d’exécution variable :

  • chargement d’une page
  • appel API
  • animation frontend
  • rendu asynchrone
  • synchronisation base de données

Exemple :

await page.click('#submit')
await page.locator('.success').isVisible()

Si le message met plus de temps à apparaître dans certains environnements, le test devient instable.

2. Les flaky tests liés à l’environnement

L’une des causes les plus fréquentes des flaky tests provient des différences entre l’environnement local du développeur et l’environnement d’exécution du pipeline CI/CD.

Un test peut fonctionner parfaitement sur la machine d’un développeur, mais devenir instable une fois exécuté dans GitLab CI, GitHub Actions, Jenkins ou Azure DevOps.

Pourquoi ? Parce que les conditions d’exécution sont souvent très différentes.

Des ressources machines plus limitées

Dans un environnement local, un développeur dispose généralement :

  • d’un processeur performant
  • d’une bonne quantité de mémoire
  • d’un navigateur graphique complet
  • d’un système peu chargé

Dans un pipeline CI/CD, la situation change complètement.

Les runners CI exécutent souvent plusieurs jobs simultanément avec des ressources limitées :

  • CPU partagé
  • mémoire réduite
  • conteneurs Docker légers
  • machines virtuelles mutualisées

Conséquence : certaines opérations deviennent plus lentes.

Par exemple :

  • une page met plus de temps à charger ;
  • une animation frontend prend quelques millisecondes supplémentaires ;
  • un appel API répond plus lentement.

Un test mal synchronisé peut alors échouer de manière aléatoire.

Exemple classique :

await page.click('#login')
await expect(page.locator('.dashboard')).toBeVisible()

Localement, le dashboard apparaît immédiatement.

En CI/CD, la page peut nécessiter davantage de temps à cause des ressources limitées.
Le test devient alors flaky.

3. Les flaky tests liés aux données

Les données de test représentent l’une des principales causes de flaky tests dans les pipelines CI/CD modernes.

Même lorsque les scripts de test sont correctement développés, des données mal gérées peuvent provoquer des comportements imprévisibles et rendre les pipelines instables.

Dans beaucoup d’équipes, ce problème est sous-estimé jusqu’à ce que les tests deviennent impossibles à maintenir.

Pourquoi les données provoquent des flaky tests

Un test automatisé doit toujours s’exécuter dans un contexte prévisible.

Or, lorsque plusieurs tests :

  • partagent les mêmes données
  • modifient une même base
  • utilisent les mêmes comptes utilisateurs
  • dépendent d’un état déjà existant

les résultats deviennent aléatoires.

Le test peut alors :

  • réussir une fois
  • échouer au pipeline suivant
  • dépendre de l’ordre d’exécution
  • échouer uniquement en parallèle

C’est précisément la définition d’un flaky test.

4. Les flaky tests liés à l’ordre d’exécution

Les flaky tests liés à l’ordre d’exécution apparaissent lorsqu’un test dépend involontairement d’un autre scénario exécuté avant lui.

Ce type de problème est particulièrement fréquent dans les suites de tests automatisés devenues trop grandes ou mal isolées.

Au départ, les tests semblent fonctionner correctement.

Mais dès que :

  • l’ordre d’exécution change
  • la parallélisation est activée
  • un scénario échoue
  • un pipeline devient plus rapide

des échecs aléatoires commencent à apparaître.

Ces comportements rendent les pipelines CI/CD imprévisibles et difficiles à maintenir.

Pourquoi l’ordre d’exécution devient un problème

Un test automatisé doit toujours être :

  • indépendant
  • reproductible
  • autonome

Autrement dit, il doit pouvoir être exécuté :

  • seul
  • dans n’importe quel ordre
  • sur n’importe quelle machine
  • en parallèle

Le problème apparaît lorsque les tests partagent :

  • des données
  • des sessions
  • des états applicatifs
  • des utilisateurs
  • des configurations

Dans ce cas, certains scénarios commencent à dépendre implicitement d’autres tests exécutés auparavant.

Le pipeline devient alors fragile.

Exemple concret

Imaginons les scénarios suivants :

Test A

Créer un utilisateur

Test B

Modifier le profil utilisateur

Test C

Supprimer l’utilisateur

Tant que les tests s’exécutent dans cet ordre :

  1. création
  2. modification
  3. suppression

tout semble fonctionner.

Mais si le pipeline exécute :

Test C avant Test A

alors :

  • l’utilisateur n’existe plus
  • le scénario échoue
  • le test devient flaky

Le problème ne vient pas du code applicatif, mais de la dépendance cachée entre les tests.

Pourquoi Les Flaky Tests Sont Dangereux

Les flaky tests ne sont pas seulement un problème technique mineur.

Ils impactent directement :

  • la productivité
  • la qualité logicielle
  • la vitesse de livraison
  • la confiance des équipes

1. Ils ralentissent les développeurs

Quand un pipeline échoue à cause d’un test instable :

  • les développeurs relancent les jobs
  • les merges sont retardés
  • les reviews prennent plus de temps
  • les équipes perdent du temps à investiguer de faux problèmes

Sur des projets importants, cela peut représenter plusieurs heures perdues chaque semaine.

2. Ils détruisent la confiance dans les tests

C’est probablement la conséquence la plus grave.

Quand les pipelines échouent régulièrement sans vraie régression :

  • les développeurs ignorent les alertes
  • les échecs deviennent « normaux »
  • certains tests sont désactivés
  • les équipes perdent confiance dans l’automatisation

À ce stade, le pipeline CI/CD cesse d’être un véritable filet de sécurité.

3. Ils augmentent les coûts CI/CD

Chaque relancement de pipeline consomme :

  • du temps machine
  • des runners CI
  • des ressources cloud
  • du temps humain

Dans les grandes organisations utilisant GitHub Actions, GitLab CI ou Jenkins à grande échelle, les flaky tests peuvent générer des coûts importants.

4. Ils ralentissent les déploiements

Les pipelines deviennent moins fiables.

Conséquences :

  • merges bloqués
  • releases retardées
  • hotfixes ralentis
  • validation plus longue

L’objectif du CI/CD est alors compromis.

Les Causes Techniques Les Plus Fréquentes

1. Les mauvais waits

L’utilisation de délais fixes est une cause classique.

Exemple à éviter :

await page.waitForTimeout(5000)

Pourquoi c’est dangereux :

  • trop court → le test échoue
  • trop long → pipeline lent
  • comportement variable selon la machine

Bonne pratique :

await expect(page.locator('.success')).toBeVisible()

Les attentes intelligentes sont beaucoup plus fiables.

2. Les sélecteurs fragiles

Exemple mauvais :

button:nth-child(3)

Exemple recommandé :

[data-testid="submit-button"]

Les sélecteurs CSS trop dépendants de la structure HTML rendent les tests instables.

3. Les dépendances réseau

Les tests dépendant d’APIs externes sont souvent instables.

Causes fréquentes :

  • latence
  • timeout
  • indisponibilité
  • limitations réseau

Solution :

  • utiliser des mocks
  • virtualiser les services
  • isoler les dépendances externes

4. La parallélisation mal maîtrisée

Les pipelines modernes exécutent souvent les tests en parallèle.

Mais cela peut provoquer :

  • collisions de données
  • conflits utilisateurs
  • concurrence base de données
  • pollution d’environnement

Chaque test doit être indépendant.

5. Les environnements instables

Un environnement de test mal maintenu peut provoquer :

  • données incohérentes
  • services indisponibles
  • lenteurs
  • erreurs aléatoires

La stabilité des environnements est essentielle pour réduire les flaky tests.

Comment Identifier Les Flaky Tests

1. Observer les échecs intermittents

Un test qui :

  • échoue puis réussit sans modification
  • passe localement mais échoue en CI
  • échoue uniquement la nuit
  • dépend de la charge machine

est probablement flaky.

2. Mesurer le taux de flakiness

Certaines équipes suivent un indicateur dédié :

Flaky Rate = nombre d’échecs aléatoires / nombre total d’exécutions

Un taux élevé indique un problème de fiabilité global.

3. Utiliser les outils d’analyse CI

Plusieurs plateformes permettent d’identifier les tests instables :

  • GitLab CI
  • GitHub Actions
  • Jenkins
  • CircleCI
  • Azure DevOps

Des outils comme :

  • Allure Report
  • ReportPortal
  • Playwright Trace Viewer
  • Cypress Dashboard

facilitent également l’analyse.

Comment Éliminer Les Flaky Tests

1. Supprimer les waits fixes

Évitez autant que possible :

wait(5000)

Préférez :

  • les assertions intelligentes
  • les retries contrôlés
  • les événements applicatifs
  • les attentes explicites

2. Rendre les tests indépendants

Chaque test automatisé doit pouvoir être exécuté :

  • seul
  • dans n’importe quel ordre
  • en parallèle

Un test ne doit jamais dépendre :

  • d’un autre scénario
  • d’une session existante
  • d’une donnée déjà créée
  • d’un état laissé par un précédent test

Les données utilisées doivent également être isolées afin d’éviter :

  • les comportements imprévisibles.
  • les collisions
  • les conflits

Exemple de mauvais test dépendant

Dans cet exemple, le test dépend d’un utilisateur déjà existant dans l’environnement de test.

Le scénario suppose que :

  • le compte existe encore
  • le mot de passe n’a pas changé
  • aucun autre test ne modifie cet utilisateur

Ce type de dépendance rend les tests fragiles et provoque souvent des flaky tests dans les pipelines CI/CD, surtout lorsque plusieurs scénarios sont exécutés en parallèle.

test('modifier le profil utilisateur', async ({ page }) => {
  await page.goto('/login')
  await page.fill('#email', 'qa@test.com')
  await page.fill('#password', '123456')
  await page.click('#login')
  await page.goto('/profile')
  await page.fill('#lastname', 'Dupont')
  await page.click('#save')

})

Pourquoi ce test est fragile :

  • l’utilisateur peut avoir été supprimé
  • un autre test peut modifier son mot de passe
  • plusieurs pipelines peuvent utiliser le même compte
  • le test devient instable en parallélisation

Exemple de bon test indépendant

Dans cette version, le test crée ses propres données avant exécution.

Chaque scénario utilise un utilisateur unique et totalement isolé des autres tests.

Cette approche permet :

  • de rendre le test totalement autonome.
  • d’éviter les conflits
  • de sécuriser la parallélisation
  • d’améliorer la stabilité du pipeline AQ
  • Qu’est-ce qu’un flaky test ?
  • Un flaky test est un test automatisé qui échoue de manière aléatoire sans modification du code.
  • Pourquoi les flaky tests sont-ils dangereux ?
  • Ils réduisent la confiance dans les pipelines CI/CD, ralentissent les développeurs et augmentent les coûts d’infrastructure.
  • Comment détecter un flaky test ?
  • Un test qui passe puis échoue sans changement fonctionnel est généralement considéré comme flaky.
  • Comment réduire les flaky tests ?
  • Les meilleures pratiques incluent :
  • supprimer les waits fixes ;
  • stabiliser les sélecteurs ;
  • isoler les données ;
  • limiter les dépendances externes ;
  • améliorer les environnements de test.
  • Quel framework réduit le mieux les flaky tests ?
  • Playwright est aujourd’hui considéré comme l’un des frameworks les plus robustes grâce à son système d’auto-waiting et son isolation native.
test('modifier le profil utilisateur', async ({ page }) => {
  const uniqueEmail = `user-${Date.now()}@test.com`

  await createUser({
    email: uniqueEmail,
    password: '123456'
  })
  await page.goto('/login')
  await page.fill('#email', uniqueEmail)
  await page.fill('#password', '123456')
  await page.click('#login')
  await page.goto('/profile')
  await page.fill('#lastname', 'Dupont')
  await page.click('#save')
})

Pourquoi ce test est plus fiable :

  • il ne dépend d’aucun autre scénario
  • les données sont uniques
  • il peut être exécuté en parallèle
  • il reste stable dans le pipeline CI/CD

3. Utiliser des données de test propres

Bonnes pratiques :

  • générer des utilisateurs uniques
  • nettoyer les données après exécution
  • réinitialiser les environnements
  • utiliser des fixtures

4. Réduire les tests E2E inutiles

Beaucoup d’équipes ont trop de tests end-to-end.

Or :

  • les tests E2E sont lents
  • ils sont plus fragiles
  • ils dépendent de nombreux composants

Il est préférable de respecter la pyramide des tests :

  • beaucoup de tests unitaires
  • des tests d’intégration
  • peu de tests E2E

5. Utiliser les retries intelligemment

Les retries peuvent être utiles temporairement.

Mais attention :

  • ils masquent parfois les vrais problèmes
  • ils ne doivent pas devenir une solution permanente

Un retry doit servir à détecter un flaky test, pas à l’ignorer

Les Meilleurs Outils Pour Réduire Les Flaky Tests

Playwright

Playwright propose :

  • auto-waiting
  • isolation navigateur
  • retries intégrés
  • traces détaillées
  • parallélisation robuste

C’est aujourd’hui l’un des frameworks les plus efficaces contre les flaky tests.

Cypress

Cypress inclut également :

  • retry automatique
  • attentes intelligentes
  • debugging visuel

Mais certains scénarios complexes restent parfois limités.

Selenium

Très utilisé historiquement.

Cependant, Selenium nécessite souvent davantage de configuration pour limiter les instabilités.

Exemple Réel d’Impact Dans Une Équipe

Prenons une équipe avec :

  • 2000 tests automatisés
  • 15 pipelines par jour
  • 8 % de flaky tests

Conséquences possibles :

  • plusieurs pipelines relancés quotidiennement
  • ralentissement des merges
  • fatigue des développeurs
  • perte de confiance dans les alertes

Après réduction des flaky tests :

  • pipelines plus rapides
  • déploiements plus fluides
  • moins de debugging inutile
  • meilleure qualité logicielle

Bonnes Pratiques Pour Un Pipeline CI/CD Fiable

Checklist recommandée

Tests

  • éviter les waits fixes
  • limiter les tests E2E
  • rendre les tests indépendants
  • utiliser des assertions robustes

Infrastructure

  • stabiliser les environnements
  • isoler les données
  • surveiller les performances CI

Équipe

  • corriger rapidement les flaky tests
  • ne jamais ignorer les instabilités
  • suivre les métriques qualité

Conclusion

Les flaky tests représentent l’un des plus grands ennemis des pipelines CI/CD modernes.

Même si leur impact semble parfois mineur au départ, ils peuvent progressivement :

  • ralentir les développeurs
  • augmenter les coûts
  • bloquer les déploiements
  • détruire la confiance dans l’automatisation

La bonne nouvelle est qu’ils ne sont pas une fatalité.

Avec :

  • Des meilleurs frameworks
  • une stratégie de test adaptées
  • une isolation correcte
  • des environnements stables
  • des bonnes pratiques CI/CD

il est possible de réduire drastiquement les flaky tests et d’améliorer la fiabilité globale des pipelines.

Dans les équipes modernes, la qualité des tests automatisés est devenue aussi importante que la qualité du code lui-même.