L’écart entre avoir des tests dbt et avoir un système de test efficace est le routage : acheminer les échecs vers les personnes qui peuvent les corriger, au bon niveau d’urgence, sans générer un volume tel que les alertes deviennent du bruit de fond.
Le problème de la vitre brisée
La théorie de la vitre brisée appliquée aux données : quand une équipe accepte quelques échecs de tests perpétuels, elle en accepte rapidement davantage. En quelques mois, toute la suite de tests est du bruit de fond. Les vrais problèmes passent à travers parce que le rapport signal/bruit s’est effondré.
La discipline est simple mais nécessite de l’application : ne jamais tolérer les tests qui échouent chroniquement. Quand un test échoue, vous avez exactement quatre options :
- Corriger le problème sous-jacent dans les données ou la logique de transformation
- Mettre à jour les attentes du test si le seuil initial était incorrect ou si la définition métier a changé
- Étiqueter comme en cours d’investigation avec une échéance spécifique et un propriétaire nommé
- Supprimer le test s’il se déclenche sur des conditions connues comme acceptables et ne fournit aucune valeur actionnable
Ce que vous ne pouvez pas faire, c’est le laisser échouer indéfiniment et passer à autre chose. C’est le choix qui brise le système.
L’option 4 — la suppression — est sous-utilisée. Les équipes ont souvent le sentiment que supprimer un test revient à admettre une défaite. Ce n’est pas le cas. Un test qui échoue toujours est pire qu’aucun test : il normalise l’état d’échec, conditionne l’équipe à ignorer les alertes et masque les vrais échecs quand ils surviennent. Si un test se déclenche régulièrement sur des conditions que vous avez décidé d’accepter, supprimez-le et écrivez le test que vous voulez réellement.
Sévérité conditionnelle
La distinction error vs. warn est importante. Une erreur bloque l’exécution ; un avertissement enregistre un message et continue. Le pattern qui fonctionne en pratique : erreur en CI, avertissement en production.
data_tests: - unique: config: severity: "{{ 'error' if target.name == 'ci' else 'warn' }}"Cela vous donne des échecs bloquants lors des revues de code — quand vous pouvez effectivement corriger la cause — sans interrompre les pipelines de production pour des conditions qui peuvent être transitoires ou attendues.
Pour les tests où des seuils d’avertissement précoce et d’échec dur ont tous deux du sens, des seuils de sévérité conditionnels créent un système à deux étapes :
data_tests: - not_null: config: severity: error error_if: ">1000" warn_if: ">10"Cela déclenche un avertissement quand vous dépassez 10 valeurs nulles (mérite investigation) et une erreur dure quand vous dépassez 1000 (quelque chose est vraiment cassé). Les seuils doivent refléter ce qui est normal pour vos données : un modèle avec 10 millions de lignes peut avoir un taux de valeurs nulles acceptable différent d’un modèle avec 1000 lignes.
Propriété via les tags meta
Acheminer les alertes vers la bonne équipe nécessite des métadonnées de propriété. Taguez les modèles avec propriétaire et criticité dans leur configuration meta :
models: - name: mrt__finance__revenue config: meta: owner: "finance-analytics" criticality: "high" - name: mrt__marketing__campaigns config: meta: owner: "marketing-analytics" criticality: "medium"Ces champs meta sont interrogeables — soit directement dans votre entrepôt via les tables dbt_models (si vous utilisez Elementary) soit via les artefacts dbt. Ils constituent la base de la logique de routage dans votre infrastructure d’alertes.
Routage des alertes par palier
Avec les métadonnées de propriété en place, une structure de routage par palier dirige les alertes vers le bon canal à la bonne urgence :
| Criticité | Mode d’échec | Routage |
|---|---|---|
| Critique | Erreur lors de l’exécution du pipeline | PagerDuty / rotation d’astreinte |
| Élevé | Échec de test sur un modèle mart | Canal Slack + message direct au propriétaire |
| Moyen | Échec de test sur un modèle intermediate | Canal Slack de l’équipe |
| Faible | Test de sévérité avertissement | Email de digest quotidien |
La logique de routage dépend de votre configuration de surveillance. Avec Elementary, le champ meta.channel contrôle quel canal Slack reçoit les alertes par modèle, et alert_suppression_interval empêche les alertes répétées pour le même échec persistant.
Sans Elementary, vous pouvez construire un routage de base en analysant l’artefact run_results.json de dbt après l’exécution et en envoyant des alertes basées sur les métadonnées du modèle. C’est plus de travail d’ingénierie mais produit le même effet.
L’objectif du routage par palier n’est pas la bureaucratie — c’est la qualité du signal. Si tout le monde reçoit chaque alerte, personne n’agit sur aucune alerte. Si l’équipe finance ne voit que les alertes sur les modèles finance, et que ces alertes arrivent en un volume qu’elle peut traiter, elle y répondra réellement.
Fraîcheur des sources liée aux SLAs
Les vérifications de fraîcheur des sources sont une catégorie spécifique où la configuration de sévérité doit refléter les engagements réels envers les parties prenantes. Si vous avez promis des données à 6 heures, le seuil d’erreur doit être de 6 heures — pas de 24 heures parce que « c’est ce qu’on a défini partout ».
Le pattern : vérifiez la fraîcheur au moins deux fois aussi souvent que votre SLA le plus bas. Si vous vous engagez à une fraîcheur de 6 heures, exécutez des vérifications de fraîcheur toutes les 3 heures minimum. Cela vous donne le temps de diagnostiquer et corriger les problèmes avant que la violation du SLA ne devienne visible par les clients.
sources: - name: salesforce freshness: warn_after: {count: 4, period: hour} # avertir à 4h, erreur au SLA de 6h error_after: {count: 6, period: hour} tables: - name: opportunities loaded_at_field: systemmodstampLes seuils de fraîcheur qui ne correspondent pas aux SLAs réels ne sont que des chiffres arbitraires. Ancrez-les dans ce que vous avez réellement promis, puis définissez le seuil d’avertissement légèrement avant le seuil d’erreur pour avoir le temps de réagir.
Couverture de tests pilotée par les incidents
Quand un outil d’observabilité signale une anomalie non couverte par un test existant, convertissez-la en test dbt permanent. Le cycle : l’outil de détection d’anomalies signale un problème → l’astreinte enquête → cause racine identifiée → test dbt explicite rédigé → test ajouté à la suite permanente.
Cela fait passer la couverture de tests du spéculatif (qu’est-ce qui pourrait casser ?) à l’empirique (qu’est-ce qui a cassé ?). Écrire le test avant de fermer le ticket est ce qui fait croître la suite vers les modes d’échec réels du pipeline.