dbt offre un contrôle fin sur quels tests unitaires s’exécutent et quand. Le mécanisme clé est le sélecteur test_type:unit, qui sépare les tests unitaires des tests de données dans toutes les commandes CLI. Cette séparation est fondamentale pour l’intégration des tests unitaires dans votre workflow — ils s’exécutent dans des contextes différents (CI vs production) et servent des objectifs différents (vérification de la logique vs santé des données).
Exécuter les tests unitaires
# Exécuter tous les tests unitairesdbt test --select test_type:unit
# Exécuter tous les tests de données (génériques + singuliers)dbt test --select test_type:data
# Exécuter tous les tests (unitaires + données)dbt testLes sélecteurs test_type:unit et test_type:data sont le principal moyen de séparer les deux catégories. Dans votre workflow quotidien, vous exécuterez généralement les tests unitaires pendant le développement (pour vérifier vos modifications de logique) et les tests de données après la construction des modèles (pour vérifier la santé des données).
Filtrer les tests unitaires
La syntaxe de sélection de dbt fonctionne de la même manière pour les tests unitaires que pour tout le reste :
# Exécuter les tests unitaires pour un modèle spécifiquedbt test --select mrt__core__customers,test_type:unit
# Exécuter les tests unitaires avec un tag spécifiquedbt test --select tag:critical,test_type:unit
# Exécuter un test unitaire spécifique par son nomdbt test --select test_mrt_core_customers_email_validationLa virgule agit comme une intersection — mrt__core__customers,test_type:unit signifie « tests associés à mrt__core__customers ET qui sont des tests unitaires ». Sans le qualificateur test_type:unit, vous obtiendriez aussi les tests de données génériques du modèle.
Exécuter un test par son nom ne nécessite pas le qualificateur test_type puisque le nom est déjà unique.
Le filtrage par tags est particulièrement utile pendant le développement. Si vous avez étiqueté vos tests par domaine (finance, marketing, core), vous pouvez exécuter uniquement les tests pertinents à votre travail en cours :
# Exécuter uniquement les tests unitaires liés à la financedbt test --select tag:finance,test_type:unitConstruire et tester ensemble
La commande dbt build exécute les modèles et les tests dans l’ordre du DAG. Par défaut, elle inclut les tests unitaires et les tests de données :
# Construire les modèles et exécuter tous les tests (unitaires + données)dbt build
# Construire sans les tests unitairesdbt build --exclude-resource-type unit_testLe flag --exclude-resource-type (dbt 1.9+) est la manière propre de sauter les tests unitaires lors des builds de production. Vous pouvez aussi définir cela comme variable d’environnement pour les environnements de production :
export DBT_EXCLUDE_RESOURCE_TYPES=unit_testdbt buildC’est important car les tests unitaires utilisent des données mockées et n’ont aucune valeur en production. Ils appartiennent au CI et au développement local uniquement. Les exécuter en production gaspille du compute et peut créer de la confusion lorsque des tests ne voyant que des données propres rencontrent la complexité du monde réel.
Interpréter la sortie
Un test qui passe est simple :
PASS test_mrt_core_customers_email_validationUn test en échec affiche un diff entre la sortie attendue et la sortie réelle :
FAIL test_mrt_core_customers_email_validationGot: customer_id | is_valid_email 1 | falseExpected: customer_id | is_valid_email 1 | trueLe format diff indique immédiatement ce qui ne va pas. Dans ce cas, le modèle a retourné false pour is_valid_email alors que le test attendait true. Soit la logique du modèle a un bug, soit l’attente du test est incorrecte.
Pour les échecs plus complexes — notamment lorsque le problème se situe dans le SQL généré plutôt que dans la logique — ajoutez --debug :
dbt test --select test_mrt_core_customers_email_validation --debugLe flag --debug affiche le SQL complet généré, y compris les CTEs que dbt crée pour vos données mockées. C’est précieux pour diagnostiquer :
- Les incompatibilités de types entre les données mock et la sortie du modèle
- Les problèmes de comparaison STRUCT/ARRAY dans BigQuery
- Les colonnes manquantes que le modèle attend mais que le mock ne fournit pas
- Le comportement de surcharge des macros
Le prérequis de build préalable
Les tests unitaires ont besoin que les schémas de leurs modèles amont existent dans la base de données. Si vous exécutez des tests unitaires dans un environnement vierge (comme un nouveau runner CI), vous obtiendrez des erreurs « Not able to get columns for unit test ».
La solution : construire d’abord les modèles amont avec --empty :
# Créer des versions schéma-uniquement de tous les modèles amontdbt run --select +test_type:unit --empty
# Exécuter maintenant les tests unitairesdbt test --select test_type:unitLe sélecteur +test_type:unit (notez le préfixe +) sélectionne tous les modèles en amont des modèles qui ont des tests unitaires. Le flag --empty construit des tables avec les schémas corrects mais zéro ligne, ce qui est peu coûteux et rapide.
Ce pattern en deux étapes — construire vide, puis tester — est l’approche standard pour les pipelines CI/CD.
Combinaisons de sélecteurs courantes
| Objectif | Commande |
|---|---|
| Tous les tests unitaires | dbt test --select test_type:unit |
| Tous les tests de données | dbt test --select test_type:data |
| Tests unitaires pour un modèle | dbt test --select model_name,test_type:unit |
| Tests unitaires critiques uniquement | dbt test --select tag:critical,test_type:unit |
| Un test spécifique | dbt test --select test_name |
| Build sans tests unitaires | dbt build --exclude-resource-type unit_test |
| Construire les schémas amont pour les tests | dbt run --select +test_type:unit --empty |
Ces combinaisons couvrent 95 % de l’utilisation quotidienne. La syntaxe de sélection est composable — vous pouvez combiner des noms de modèles, des tags, des types de tests et des opérateurs de graphe (+ pour amont/aval) pour cibler exactement les tests dont vous avez besoin.