ServicesÀ proposNotesContact Me contacter →
EN FR
Note

Limitations du testing Dataform

Les assertions intégrées de Dataform couvrent trois scénarios — unicité, contrôles de nullité et conditions de ligne. Tout le reste requiert une implémentation personnalisée.

Planté
dataformbigquerydbttestingdata quality

Le testing est la lacune de capacité la plus significative entre Dataform et dbt. Dataform fournit trois types d’assertions intégrées. L’écosystème dbt propose des dizaines de types de tests à travers plusieurs packages, plus des tests unitaires natifs. La différence est structurelle, pas incrémentale.

Ce que Dataform fournit

Le système d’assertions de Dataform est configuré directement dans le bloc config SQLX :

config {
type: "table",
assertions: {
uniqueKey: ["customer_id"],
nonNull: ["customer_id", "email"],
rowConditions: ['email LIKE "%@%.%"']
}
}

uniqueKey valide que la colonne spécifiée (ou la combinaison de colonnes) ne contient pas de doublons. C’est l’équivalent du test générique unique de dbt.

nonNull garantit que les colonnes listées ne contiennent pas de valeurs nulles. Équivalent du test not_null de dbt.

rowConditions évalue des expressions SQL arbitraires contre chaque ligne. Toute ligne où la condition est fausse est signalée. C’est le plus flexible des trois, approximativement comparable à expression_is_true de dbt-utils.

Voilà le vocabulaire de testing intégré complet. Trois types d’assertions couvrant les vérifications de qualité des données les plus basiques.

Ce que Dataform n’a pas

Comparons avec ce que l’écosystème de testing dbt fournit :

Intégrité référentielle

Le test relationships de dbt valide que les valeurs de clés étrangères existent dans leur table parente. Dataform n’a pas d’équivalent intégré. Pour vérifier l’intégrité référentielle, il faut écrire un fichier d’assertion personnalisée — une requête SQL séparée qui retourne les lignes violant la relation. Pour un projet avec des dizaines de relations de clés étrangères, cela signifie des dizaines de fichiers d’assertions maintenus manuellement.

Validation statistique et par pattern

Le package dbt_expectations fournit plus de 50 tests portés depuis la bibliothèque Python Great Expectations :

  • expect_column_values_to_be_between — validation de plage détectant les valeurs impossibles comme un revenu négatif ou un taux de conversion supérieur à 1,0
  • expect_column_values_to_match_regex — validation par pattern pour les emails, SKU, numéros de téléphone
  • expect_column_mean_to_be_between — détection de dérive de distribution où les valeurs individuelles passent mais les agrégats signalent des problèmes
  • expect_row_values_to_have_recent_data — vérifications de fraîcheur sur n’importe quel modèle

Aucun de ces tests n’a d’équivalent Dataform. Chacun d’eux doit être écrit de zéro sous forme d’assertion personnalisée.

Détection d’anomalies

Elementary fournit une détection d’anomalies adaptative basée sur des patterns historiques plutôt que des seuils statiques :

  • volume_anomalies — déviation du nombre de lignes par rapport aux patterns historiques
  • freshness_anomalies — surveillance adaptative de la fréquence de mise à jour
  • column_anomalies — suivi statistique des métriques au niveau des colonnes
  • schema_changes — ajouts, suppressions ou changements de type de colonnes inattendus

Cette catégorie entière de testing des “inconnues inconnues” n’existe pas dans l’univers Dataform.

Tests unitaires

dbt 1.8 a introduit des tests unitaires natifs qui valident la logique de transformation avec des entrées mockées avant que les données ne touchent l’entrepôt :

unit_tests:
- name: test_discount_calculation
model: mrt__finance__orders
given:
- input: ref('base__shopify__orders')
rows:
- {order_id: 1, subtotal: 100, discount_code: "SAVE20"}
expect:
rows:
- {order_id: 1, discount_amount: 20, final_total: 80}

Les tests unitaires répondent à la question “mon SQL est-il correct ?” plutôt que “mes données sont-elles saines ?”. Dataform n’a aucun mécanisme équivalent. Il est impossible de tester la logique de transformation de manière isolée sans l’exécuter contre des données réelles.

Les assertions personnalisées dans Dataform

La porte de sortie de Dataform est le fichier d’assertion personnalisée. On crée un fichier .sqlx avec type: "assertion" qui retourne les lignes violant une condition :

config {
type: "assertion",
schema: "assertions"
}
-- Échoue si un client a une valeur vie négative
SELECT customer_id, lifetime_value
FROM ${ref("mrt_customers")}
WHERE lifetime_value < 0

Si la requête retourne des lignes, l’assertion échoue. C’est l’équivalent des tests singuliers de dbt. Cela fonctionne, mais chaque assertion est un fichier séparé avec du SQL écrit à la main. Il n’y a pas de paramétrage, pas de pattern de réutilisation, pas de bibliothèque de tests sur laquelle s’appuyer.

Le package dataform-assertions de Devoteam est l’une des rares options tierces disponibles, fournissant quelques patterns d’assertions réutilisables. Mais c’est un seul package communautaire face à l’écosystème de centaines de packages de dbt.

L’impact pratique

Pour les projets avec des besoins de testing basiques — unicité des clés primaires, contrôles de nullité, quelques règles métier — les assertions de Dataform sont adéquates. Beaucoup de petits projets n’ont genuinement pas besoin de tests de distribution statistique ou de détection d’anomalies.

L’écart devient douloureux à mesure que la complexité augmente. Un projet avec plus de 100 modèles, des dizaines de relations de clés étrangères, et des exigences de qualité des données critiques pour l’activité passera un temps d’ingénierie significatif à construire des assertions personnalisées que les équipes dbt obtiennent d’emblée. Ce temps d’ingénierie est un coût réel qui compense le prix zéro de la licence Dataform.

L’écart de testing est auto-renforçant. Les équipes manquant d’outils de testing faciles ont tendance à écrire moins de tests. La friction d’écrire des assertions personnalisées pour chaque nouveau type de test signifie que de nombreux tests valides ne sont jamais écrits. Dans dbt, ajouter un test relationships c’est une ligne de YAML. Dans Dataform, cela requiert un nouveau fichier avec une requête personnalisée. La différence de friction détermine la différence de couverture.