La sévérité des tests dbt et leur planification déterminent si un échec bloque le pipeline et quand les tests s’exécutent. Une sévérité mal configurée ou une exécution de tests non contrainte conduit soit à des échecs silencieux, soit à des pipelines qui s’arrêtent inutilement.
Niveaux de sévérité
dbt supporte deux niveaux de sévérité pour les tests : error (la valeur par défaut) et warn.
error arrête le pipeline. Si vous exécutez dbt build, un échec de test de sévérité erreur empêche les modèles en aval de s’exécuter. Utilisez cela pour les problèmes qui produiraient des données incorrectes si le pipeline continuait :
- Violations de clé primaire (les doublons causent des explosions de jointures)
- Échecs de fraîcheur sur les tables critiques (des données obsolètes sont pires qu’aucune donnée)
- Valeurs NULL dans les champs requis qui alimentent les tableaux de bord
- Plages de valeurs où les violations indiquent une corruption des données
warn enregistre l’échec mais laisse le pipeline continuer. Utilisez cela pour les problèmes qui nécessitent une investigation mais ne devraient pas bloquer la production :
columns: - name: order_value tests: - dbt_expectations.expect_column_mean_to_be_between: min_value: 50 max_value: 200 config: severity: warnLes tests statistiques comme expect_column_mean_to_be_between sont des candidats naturels pour la sévérité warn. Un décalage dans la valeur moyenne des commandes peut signaler un vrai problème, ou refléter une tendance saisonnière, une promotion réussie ou une évolution du marché. Vous souhaitez une visibilité sans interrompre la production pendant que vous investigez.
Recommandations de sévérité par type de test
| Catégorie de test | Sévérité recommandée | Raisonnement |
|---|---|---|
Clé primaire (unique, not_null) | error | Les doublons et valeurs nulles dans les clés corrompent toutes les jointures en aval |
Fraîcheur (expect_row_values_to_have_recent_data) | error sur les tables critiques, warn sur les autres | Des données obsolètes dans un mart finance est une urgence ; dans une table de staging marketing, ça peut attendre |
Format (expect_column_values_to_match_regex) | error | Les formats invalides indiquent typiquement des changements de schéma en amont |
Plage (expect_column_values_to_be_between) | error | Les valeurs hors plage indiquent généralement une corruption des données |
Statistique (expect_column_mean_to_be_between) | warn | Les décalages de distribution nécessitent une investigation, pas des interruptions de pipeline |
Volume (expect_table_row_count_to_be_between) | warn ou error | Dépend de la précision avec laquelle vous pouvez définir les bornes attendues |
Complétude (expect_row_values_to_have_data_for_every_n_datepart) | warn | Les jours manquants peuvent refléter des délais source, pas des échecs |
L’objectif est une suite de tests où error signifie « tout arrêter et corriger maintenant » et warn signifie « regarder ça aujourd’hui ». Si votre équipe ignore les avertissements, vous en avez trop. Si votre pipeline s’arrête quotidiennement, vous avez trop d’erreurs sur des tests volatils.
Performance sur BigQuery
Les tests de qualité des données exécutent du SQL sur votre entrepôt. Avec la tarification à la demande de BigQuery, chaque test scanne des données et coûte de l’argent. Certains tests sont peu coûteux (un COUNT(*) avec un filtre de partition). D’autres sont coûteux (un calcul statistique sur table entière). Gérer ce coût est une préoccupation de premier ordre.
Filtrer sur les colonnes de partition
Si votre table est partitionnée par date, utilisez toujours le paramètre row_condition pour filtrer sur la colonne de partition :
- dbt_expectations.expect_column_values_to_be_between: min_value: 0 max_value: 1000000 row_condition: "event_date >= current_date() - 30"Sans ce filtre, BigQuery scanne toute la table. Avec ce filtre, BigQuery élague aux 30 dernières partitions. Sur une table avec plusieurs années de données d’événements, cela peut réduire les octets scannés — et le coût — de 90% ou plus.
C’est particulièrement important pour ces tests, qui tendent à être les plus coûteux :
expect_row_values_to_have_data_for_every_n_datepart(génère une date spine et fait une jointure)expect_column_mean_to_be_between(agrège sur toutes les lignes)expect_column_values_to_match_regex(évalue une fonction sur chaque ligne)expect_table_row_count_to_equal_other_table(comptage complet sur deux tables)
Exécuter les tests coûteux uniquement en production
Certains tests apportent de la valeur en production mais sont du gaspillage en développement ou en CI. Utilisez la configuration enabled de dbt avec du Jinja sensible à la cible :
- dbt_expectations.expect_column_mean_to_be_between: min_value: 50 max_value: 200 config: enabled: "{{ target.name == 'prod' }}"Cela compile le test uniquement lors de l’exécution sur la cible prod. En développement et en CI, le test est entièrement ignoré — pas de compilation, pas de requête sur l’entrepôt, pas de coût.
Utilisez ce pattern pour :
- Les tests statistiques qui nécessitent des données à l’échelle de la production pour être significatifs
- Les vérifications de volume où les datasets de développement sont intentionnellement petits
- Les comparaisons cross-tables où les deux tables doivent être entièrement matérialisées
Planification des tests basée sur les tags
Pour les tests qui devraient s’exécuter selon un calendrier plutôt qu’à chaque build, utilisez les tags dbt :
- dbt_expectations.expect_row_values_to_have_data_for_every_n_datepart: date_col: event_date date_part: day config: tags: ['slow', 'daily']Puis dans votre pipeline CI, excluez les tests lents :
dbt test --exclude tag:slowEt dans votre exécution quotidienne en production, incluez tout :
dbt testOu exécutez les tests lents selon leur propre calendrier :
dbt test --select tag:slowCela vous donne un retour CI rapide (moins de 5 minutes) tout en exécutant une validation complète quotidiennement. Les noms de tags sont arbitraires — slow, daily, weekly, expensive, nightly — choisissez la convention que votre équipe utilisera réellement.
Estimer les coûts des tests
Un cadre approximatif pour la tarification à la demande BigQuery (6,25 $ par To scanné en 2026) :
| Type de test | Scan typique | Coût sur une table de 100 Go |
|---|---|---|
unique / not_null (colonne unique) | Colonne uniquement | ~0,01 $ |
expect_column_values_to_be_between (avec filtre de partition) | Partition filtrée | ~0,001 $ |
expect_column_values_to_be_between (sans filtre) | Colonne complète | ~0,01 $ |
expect_column_mean_to_be_between (table entière) | Colonne complète | ~0,01 $ |
expect_row_values_to_have_data_for_every_n_datepart (table entière) | Table entière + date spine | ~0,06 $ |
expect_table_row_count_to_equal_other_table | Deux tables entières | ~0,12 $ |
Les tests individuels sont peu coûteux. Le coût s’accumule quand vous avez 200+ tests qui s’exécutent plusieurs fois par jour sur des dizaines de modèles. Le filtrage de partition et la planification basée sur les tags sont les deux optimisations les plus rentables.
Placement des tests par couche
L’endroit où vous placez les tests dans votre architecture trois couches affecte à la fois la couverture et le coût.
Sources et modèles base : Concentrez-vous sur la fraîcheur, la validation du schéma et les vérifications de format de base. C’est là que les problèmes entrent dans votre pipeline. Les détecter ici prévient les échecs en cascade en aval.
models: - name: base__ga4__events tests: - dbt_expectations.expect_row_values_to_have_recent_data: datepart: hour interval: 48 columns: - name: user_pseudo_id tests: - dbt_expectations.expect_column_values_to_match_regex: regex: '^[0-9]+\\.[0-9]+$'Modèles intermediate : Concentrez-vous sur l’intégrité des jointures et la validation des transformations. Vérifiez que les jointures n’éliminent ou ne dupliquent pas les lignes de façon inattendue. Ces tests sont souvent le premier signal que quelque chose a cassé en amont.
Marts : Concentrez-vous sur les règles métier et les vérifications de cohérence des agrégations. Ces tests protègent vos sorties finales — les tables que les outils BI interrogent et sur lesquelles les parties prenantes s’appuient.
models: - name: mrt__marketing__campaign_performance columns: - name: roas tests: - dbt_expectations.expect_column_values_to_be_between: min_value: 0 max_value: 100 row_condition: "spend > 0"Le principe général : l’intensité des tests doit augmenter vers les bords de votre DAG. Les sources sont là où les problèmes entrent. Les marts sont là où ils atteignent les consommateurs. Les couches intermédiaires reçoivent une couverture plus légère axée sur l’intégrité des jointures.
Point de départ pour les nouveaux projets
Lors de l’ajout de dbt-expectations à un projet existant, un ensemble minimal de trois tests sur le modèle le plus important couvre les lacunes les plus courantes que les tests natifs dbt manquent :
- Fraîcheur :
expect_row_values_to_have_recent_datasur la colonne de timestamp principale - Format :
expect_column_values_to_match_regexsur une colonne d’identifiant clé - Plage :
expect_column_values_to_be_betweensur une colonne KPI numérique
Élargissez à partir de là en fonction des échecs qui se produisent réellement en production.