Les tests de schéma dbt standard — unique, not_null, accepted_values — détectent les défaillances du pipeline de données. Ils ne détectent pas les défaillances du tracking GA4. Une propriété GA4 peut exporter des données avec succès tout en perdant silencieusement des données de conversion, en mal-attribuant des sessions, ou en générant des sessions fantômes depuis du trafic bot. Les tests spécifiques à GA4 détectent ces cas.
Fraîcheur des sources
La première ligne de défense est le monitoring de la fraîcheur des sources. Si le pipeline d’export GA4 se bloque, vous voulez le savoir avant vos parties prenantes.
sources: - name: ga4 database: "{{ var('ga4_project_id') }}" schema: "{{ var('ga4_dataset') }}"
tables: - name: events identifier: "events_*" freshness: warn_after: {count: 24, period: hour} error_after: {count: 48, period: hour} loaded_at_field: "TIMESTAMP_MICROS(event_timestamp)"L’export quotidien de GA4 se termine généralement 6 à 12 heures après la fin de la journée. Une fenêtre d’avertissement de 24 heures signale les retards sans se déclencher sur les variations normales de timing. Le seuil d’erreur de 48 heures détecte les pannes réelles.
Tests de schéma sur le modèle de base
Sur base__ga4__events, les tests critiques portent sur les champs dont tout le reste dépend :
models: - name: base__ga4__events columns: - name: event__key tests: - unique - not_null
- name: user__pseudo_id tests: - not_null
- name: event__timestamp_utc tests: - not_null
- name: session__key tests: - not_nullLe test d’unicité event__key est le plus important — il détecte les événements dupliqués provenant de fenêtres incrémentales qui se chevauchent ou de bugs dans la génération de la clé de substitution. Le test not_null sur session__key détecte le cas où l’extraction de ga_session_id est cassée (retournant null, rendant la clé composite nulle).
Test singulier : événements session_start manquants
Les sessions qui ont plusieurs événements mais aucun session_start indiquent un problème d’implémentation du tracking. Certaines causes sont bénignes (utilisateurs avec des bloqueurs de publicités supprimant le premier événement), mais un taux élevé indique un problème avec votre code de tracking.
-- tests/singular/test_sessions_missing_session_start.sql
WITH session_stats AS ( SELECT session__key, COUNT(*) AS session__events, MAX(CASE WHEN event__name = 'session_start' THEN 1 ELSE 0 END) AS session__has_start FROM {{ ref('int__ga4__events_sessionized') }} WHERE event__date >= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY) GROUP BY session__key)
SELECT session__key, session__events, session__has_startFROM session_statsWHERE session__has_start = 0 AND session__events > 3 -- Sessions multi-événements légitimes sans démarrageLIMIT 100Le seuil session__events > 3 filtre les cas limites à événement unique. Une session avec 10 événements et aucun session_start est presque certainement un problème de tracking ; une session avec 2 événements pourrait simplement être un artefact de timing.
Ce test retourne des lignes si la condition est remplie, ce qui dans dbt signifie un échec. Configurez avec severity: warn pour signaler les problèmes de tracking sans bloquer les exécutions du pipeline.
Test singulier : transactions orphelines
Les événements d’achat sans contexte de session valide produisent des données de chiffre d’affaires qui ne peuvent pas être attribuées à un canal ou une campagne. Cela indique souvent des implémentations Measurement Protocol qui ne passent pas correctement le contexte de session.
-- tests/singular/test_purchase_without_session.sql
SELECT event__key, event__date, session__ga_id, user__pseudo_idFROM {{ ref('base__ga4__events') }}WHERE event__name = 'purchase' AND transaction__id IS NOT NULL AND (session__ga_id IS NULL OR user__pseudo_id IS NULL) AND event__date >= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)LIMIT 100Toute transaction orpheline devrait échouer bruyamment — elle représente du chiffre d’affaires qui sera invisible dans les rapports d’attribution par canal. Contrairement au test session_start (où un certain taux est attendu), les transactions orphelines devraient être à zéro.
Tests de schéma pour la table sessionisée
La table sessionisée large contient des colonnes qui ne sont pas de simples vérifications not_null — elles ont des plages attendues et des valeurs acceptées :
models: - name: int__ga4__events_sessionized columns: - name: event__key tests: - unique - not_null
- name: session__key tests: - not_null
- name: session__landing_page description: "Première URL de page dans la session" tests: - not_null: where: "event__name = 'page_view'"
- name: session__pageviews tests: - dbt_utils.accepted_range: min_value: 0 max_value: 1000
- name: session__duration_seconds tests: - dbt_utils.accepted_range: min_value: 0 max_value: 86400
- name: session__channel_grouping tests: - accepted_values: values: - 'Direct' - 'Organic Search' - 'Paid Search' - 'Paid Social' - 'Organic Social' - 'Email' - 'Referral' - 'Display' - 'Affiliates' - 'Other'Page d’entrée conditionnelle not_null : La clause where restreint la vérification not_null aux seuls événements page_view. Les événements non-page_view n’ont légitimement pas de page d’entrée. C’est plus précis que de vérifier tous les événements (ce qui échouerait correctement pour les page_views avec des données manquantes, mais signalerait aussi chaque événement d’achat).
Test de plage de pages vues : Les sessions avec plus de 1 000 pages vues sont presque certainement des bots. Le test de plage les signale — utile pour détecter le trafic bot qui a échappé aux filtres de GA4.
Plage de durée : Les sessions de plus de 24 heures (86 400 secondes) indiquent un bug de collision de clé de session ou un problème de qualité des données. Les sessions d’utilisateurs réels ne s’étendent pas sur des jours.
Valeurs acceptées pour le regroupement des canaux : Détecte les bugs dans la macro de regroupement des canaux qui produisent des noms de canaux inattendus.
Stratégie de sévérité des tests
Tous les tests ne devraient pas bloquer la production :
tests: +severity: warn +store_failures: trueDéfinir globalement severity: warn signifie que les tests échouent doucement — ils apparaissent dans les résultats des tests sans bloquer les modèles en aval ni déclencher des alertes. store_failures: true écrit les lignes en échec dans l’entrepôt pour que vous puissiez les investiguer.
Remplacez pour les tests critiques qui doivent bloquer :
columns: - name: event__key tests: - unique: severity: error - not_null: severity: errorLes violations d’unicité sur event__key indiquent un bug fondamental du pipeline. Les transactions orphelines doivent être des erreurs si la précision du chiffre d’affaires est critique pour l’entreprise. Les problèmes de taux de session_start doivent être des avertissements — ils indiquent des problèmes de tracking qui méritent investigation, mais ne devraient pas bloquer le reporting.
Ce que ces tests ne détectent pas
Ces tests détectent les problèmes de qualité des données dans votre pipeline. Ils ne détectent pas :
- L’écart de 1 à 2 % avec l’interface GA4 — Attendu et documenté. Consultez Écarts de chiffres entre GA4 et BigQuery.
- Les différences de modèle d’attribution — Votre regroupement des canaux différera de l’interface GA4. Acceptez et documentez cet écart.
- Les conversions tardives — La fenêtre de lookback statique gère la plupart de ces cas, mais les conversions qui arrivent après la fenêtre de lookback apparaîtront sur de mauvaises dates. Surveillez via des comparaisons périodiques.
Couverture de tests recommandée pour un projet GA4 : fraîcheur de la source, unicité des clés, tests singuliers pour les défaillances de tracking spécifiques à GA4, et tests de plage sur les métriques sessionisées.