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 utilisateurTest B
Modifier le profil utilisateurTest C
Supprimer l’utilisateurTant que les tests s’exécutent dans cet ordre :
- création
- modification
- suppression
tout semble fonctionner.
Mais si le pipeline exécute :
Test C avant Test Aalors :
- 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.



