500 sites d’un même réseau WordPress multisite, à raison de 40 secondes par site pour la suite d’intégration : un peu plus de cinq heures et demie de calcul, sans compter les échecs qui ralentissent encore l’ensemble. C’est ce calcul qui a permis de comprendre qu’exécuter la suite complète à chaque push n’était tout simplement pas une option viable pour ce client, un réseau de sites de franchises partageant une même extension de réservation.
L’extension gérait un système de réservation de créneaux, avec des règles métier qui variaient légèrement d’un site à l’autre selon des options activées site par site : horaires d’ouverture, capacité maximale, intégration à un CRM local. Chaque site représentait potentiellement une combinaison de configuration unique, et un bug pouvait n’apparaître que sur une combinaison précise.
Pourquoi le tout-exhaustif ne fonctionne pas
Deux problèmes distincts empêchaient l’exhaustivité à chaque exécution :
- Le temps d’exécution dépassait largement la fenêtre acceptable d’une CI (l’objectif interne était de rester sous 15 minutes).
- Les 500 sites n’étaient pas tous également représentatifs : une grande partie partageait exactement la même configuration, et les tester tous n’apportait aucune information supplémentaire.
Construire un échantillon stratifié plutôt qu’aléatoire
Un tirage purement aléatoire de 20 sites sur 500 aurait pu, par malchance, ignorer des combinaisons de configuration rares mais réellement utilisées en production. La stratégie retenue classe d’abord les sites par profil de configuration, puis tire un échantillon dans chaque strate.

tests/
├── strategie-echantillonnage/
│ ├── classer-sites-par-profil.php # regroupe les 500 sites en profils de config
│ ├── selectionner-echantillon.php # tire N sites par profil, N proportionnel à la taille
│ └── historique-anomalies.json # sites ayant échoué récemment, toujours inclus
├── SuiteReservationTest.php
└── bootstrap-multisite.php
Les trois strates retenues pour ce réseau
- Sites avec configuration par défaut (environ 340 sites) : échantillon de 10 sites, tiré aléatoirement à chaque exécution.
- Sites avec CRM local personnalisé (environ 140 sites) : échantillon de 15 sites, car la variabilité y est plus forte.
- Sites en anomalie récente ou en configuration atypique (environ 20 sites) : tous inclus systématiquement, sans tirage.
Le code d’échantillonnage
function selectionner_echantillon(array $sites_par_profil, array $historique_anomalies): array
{
$echantillon = $historique_anomalies;
foreach ($sites_par_profil as $profil => $sites) {
$taille = $profil === 'crm_local' ? 15 : 10;
$tirage = array_rand(array_flip($sites), min($taille, count($sites)));
$echantillon = array_merge($echantillon, (array) $tirage);
}
return array_unique($echantillon);
}
Le point important de cette fonction n’est pas la mécanique de tirage elle-même, plutôt banale, mais la garantie que les sites déjà en anomalie entrent systématiquement dans l’échantillon suivant, tant que l’anomalie n’est pas résolue et confirmée par deux exécutions consécutives sans échec.
Compléter par une exécution exhaustive nocturne
L’échantillonnage réduit le risque sans l’éliminer : un bug rarissime, propre à un seul site jamais tiré, peut passer inaperçu pendant plusieurs semaines. La parade retenue a été une exécution complète des 500 sites une fois par nuit, hors des heures de développement, avec alerte automatique en cas d’échec plutôt qu’un blocage de merge.
- Exécution rapide (échantillon) à chaque push, bloquante pour le merge.
- Exécution exhaustive nocturne, non bloquante mais alertante par messagerie interne.
- Tout site en échec nocturne rejoint automatiquement l’échantillon du lendemain.
Tester 500 sites à chaque build n’est pas un gage de rigueur : c’est souvent un signe que personne n’a encore réfléchi à quelle information chaque test apporte réellement.
Notre verdict
Une architecture de tests multi-tenant à grande échelle ne se résout pas en accélérant l’exécution : elle se résout en repensant ce qui doit réellement être vérifié à chaque build, versus ce qui peut l’être une fois par jour. Un échantillon stratifié, complété d’une exécution exhaustive régulière, offre un compromis tenable entre confiance et rapidité de retour.