Vai al contenuto principale
Test e data quality - immagine ufficiale della lezione su GinnyTech, creata da AD

Test, contracts e fiducia nei modelli

Test, contracts e fiducia nei modelli. Lezione su come garantire la qualità dei dati con dbt.

AD
Creato da Andrii Dyshkantiuk
Lezione 163 / 216 Livello: Avanzato Durata: 18 min Prerequisiti: 1

Cosa imparerai

  • Comprendere il problema analitico e il contesto decisionale
  • Applicare esempi, metriche e controlli a casi reali

Test, contracts e fiducia nei modelli

Una metrica cambia perché una sorgente ha rinominato un campo, non perché il business è cambiato. Test, contracts e fiducia nei modelli mostra come proteggere il warehouse con test, aspettative e contratti che rendono visibili rotture e assunzioni.

Una scena da cui partire

Leggi la lezione come costruzione della fiducia tecnica. Un test utile non dimostra che tutto va bene: intercetta il tipo di errore che danneggerebbe una decisione o romperebbe un contratto a valle.

  • Contesto: Quale vincolo tecnico decide il disegno?
  • Metodo: Quale controllo ti direbbe che il risultato è affidabile?
  • Applicazione: Quale trade-off racconteresti prima di mettere in produzione?

La piramide dei test in dbt

dbt nativamente supporta test generici, test singolari, e test custom. La strategia è stratificata:

LivelloTipo di testCoperturaImpatto del fallimento
1 — Fondamentaliunique, not_null su primary keyOgni modelloBlocca la PR
2 — Businessaccepted_values, relationshipsOgni colonna criticaBlocca la PR
3 — VolumeRange di row count attesoModelli chiaveWarning
4 — Qualità statisticaMedia, deviazione standard, distribuzioneMetriche coreAlert

I test generici (built-in)

I quattro test generici di dbt coprono il 90% dei casi:

models:
  - name: mrt_finance__monthly_revenue
    columns:
      - name: revenue_date
        tests:
          - not_null
          - unique
      - name: country
        tests:
          - not_null
          - accepted_values:
              values: ['IT', 'FR', 'DE', 'ES', 'UK', 'US']
      - name: total_revenue
        tests:
          - not_null
      - name: currency
        tests:
          - not_null
          - relationships:
              to: ref('stg_reference__currencies')
              field: currency_code

Questi quattro test, applicati automaticamente a ogni modello, bloccano l’80% degli errori di produzione. not_null e unique sulla primary key sono il minimo non negoziabile. accepted_values blocca gli errori di enum (es. un nuovo status non previsto). relationships blocca le violazioni di integrità referenziale.

I test singolari (SQL custom)

Quando la logica è troppo specifica per un test generico, scrivi un test singolare: un file SQL che deve restituire zero righe per passare.

-- tests/assert_positive_revenue.sql
SELECT revenue_date, total_revenue
FROM {{ ref('mrt_finance__monthly_revenue') }}
WHERE total_revenue < 0

Se la query restituisce righe, il test fallisce e blocca il build. I test singolari sono potenti perché permettono qualsiasi logica SQL.

I test custom (generic tests riusabili)

Quando un pattern di test si ripete, si crea un test custom in Jinja:

-- tests/generic/test_greater_than.sql
{% test greater_than(model, column_name, threshold) %}
SELECT {{ column_name }}
FROM {{ model }}
WHERE {{ column_name }} <= {{ threshold }}
{% endtest %}

Utilizzo nel file YAML:

columns:
  - name: total_revenue
    tests:
      - greater_than:
          threshold: 0

I test custom sono il ponte verso una strategia di testing matura. Il team di dati di HubSpot ha oltre 40 test custom pubblici nel loro repository open source dbt.

Data contracts: il livello successivo

Un data contract è un accordo formale tra il produttore del dato (es. il team di engineering che gestisce l’API di Stripe) e il consumatore (es. il modello dbt che importa i dati Stripe). Definisce:

  • Schema (quali colonne, quali tipi)
  • Semantica (cosa significa ogni colonna)
  • Garanzie di qualità (quali test devono passare)
  • SLA di freschezza (entro quanto tempo il dato è disponibile)

dbt supporta i contratti nativamente dalla versione 1.5 con i model contracts:

models:
  - name: stg_stripe__payments
    config:
      contract:
        enforced: true
    columns:
      - name: payment_id
        data_type: string
        constraints:
          - type: not_null
          - type: primary_key
      - name: amount_eur
        data_type: numeric(10,2)
        constraints:
          - type: not_null
      - name: payment_date
        data_type: date
      - name: status
        data_type: string
        constraints:
          - type: not_null

Con contract.enforced = true, dbt verifica che ogni riga prodotta dal modello rispetti i tipi e i vincoli dichiarati. Se una colonna è definita come not_null e il modello produce NULL, il build fallisce. Questo sposta la validazione dal “speriamo che il dato sia corretto” al “il dato è garantito corretto o il build fallisce”.

Caso reale: il disastro dei dati senza contratti

Nel 2021, un e-commerce europeo usava dbt senza contratti. Un giorno, l’API di un payment provider cambiò il tipo di amount da stringa (“99.99”) a numero (99.99) in un aggiornamento minore. Il modello staging faceva CAST(amount AS NUMERIC), che funzionava con le stringhe ma troncava i decimali del numero. Il revenue mostrato in dashboard calò del 31%.

Il team finance passò 3 giorni a cercare l’errore. La causa fu trovata solo quando qualcuno confrontò manualmente i log del payment provider con i dati del warehouse. Dopo l’incidente, implementarono model contracts su tutti i modelli staging di fonte esterna. Un anno dopo, un cambiamento simile avvenne con un altro provider — il contratto bloccò il build, il team fu avvisato in 5 minuti, e il fix richiese 10 minuti.

Strategia di implementazione progressiva

Non serve testare tutto dal giorno 1. La strategia consigliata (dbt Labs, 2024) è:

  1. Settimana 1: not_null + unique su ogni primary key di ogni modello. È il 20% dello sforzo per l’80% del valore.

  2. Settimana 2: accepted_values su tutte le colonne di status, tipo, categoria. relationships su tutte le foreign key dei modelli marts.

  3. Mese 2: Test singolari per le regole di business critiche (es. “revenue non negativo”, “order_date > customer_signup_date”).

  4. Mese 3: Model contracts su tutti i modelli staging di fonti esterne (API, file, database terzi).

  5. Quarter 2+: Test custom riusabili per pattern ricorrenti. Test di qualità statistica su metriche core.

A ogni passo, la configurazione CI/CD deve eseguire i test automaticamente e bloccare la PR se falliscono. Senza enforcement CI, i test sono documentazione inutile.


Riferimenti:

  • dbt Labs. (2024). “Testing.” dbt Documentation.
  • McConaghy, T. & Satterfield, E. (2023). “Model Contracts: Enforcing Data Quality at Build Time.” dbt Developer Blog.
  • HubSpot. (2023). “Open Source dbt Packages.” GitHub: HubSpot/dbt-utils.

Controllo di qualità

Prima di usare test, contracts e fiducia nei modelli in una decisione, controlla sempre completezza, duplicati, timezone, definizioni cambiate e segmenti esclusi. Molte analisi apparentemente sofisticate falliscono perché il dato di partenza misura un comportamento diverso da quello che il team crede di osservare.

Interpretazione per segmenti

La media aggregata è solo il punto di partenza. Segmenta per canale, coorte, piano, paese, device e maturità dell’utente. Se due segmenti si muovono in direzioni opposte, la media non rappresenta nessuno dei due e può portare a una decisione sbagliata.

Decisione operativa

Ogni analisi deve terminare con una scelta possibile: continuare, fermare, iterare, investire, rimuovere o approfondire. Se test, contracts e fiducia nei modelli non cambia una decisione, probabilmente manca ancora il collegamento tra metrica e azione.

Problema reale

Nel dominio di analytics engineering, Test, contracts e fiducia nei modelli serve a risolvere questo problema: trasformare dati grezzi in modelli testati, documentati e riusabili dal business. La lezione non va trattata come teoria isolata, ma come un modo per migliorare una scelta concreta con dati, assunzioni esplicite e controlli minimi.

Obiettivo operativo: Comprendere il problema analitico e il contesto decisionale; Applicare esempi, metriche e controlli a casi reali. Se alla fine non sai indicare quale decisione cambia, quale dato osservi e quale errore vuoi evitare, la lezione non è ancora diventata competenza applicata.

Modello concettuale

FaseCosa chiarireOutput
DomandaQuale scelta reale deve migliorare?Decisione da prendere
MisuraQuale segnale osservabile rappresenta il problema?Metrica o dato sorgente
ControlloQuale baseline rende il risultato interpretabile?Confronto credibile
AzioneChe cosa cambia dopo l’analisi?Prossimo passo operativo

Il modello concettuale è intenzionalmente semplice: decisione, dato, controllo, azione. Ogni approfondimento tecnico deve rafforzare almeno uno di questi quattro punti.

Formalizzazione rigorosa

Per rendere Test, contracts e fiducia nei modelli analizzabile, definisci prima l’unità di lavoro: source, model, test, mart, metrica o esposizione. Poi collega questa unità a una metrica osservabile: freshness, lineage, test coverage, costo modello e fiducia stakeholder. Infine dichiara la decisione attesa: modello dbt, semantic layer, contratto, test o pipeline di release.

ElementoSpecifica richiesta
Unità di analisisource, model, test, mart, metrica o esposizione
Segnale principalefreshness, lineage, test coverage, costo modello e fiducia stakeholder
BaselinePeriodo precedente, gruppo comparabile, benchmark o scenario controfattuale
Decisionemodello dbt, semantic layer, contratto, test o pipeline di release
RischioScambiare un numero disponibile per una prova sufficiente

La formalizzazione e solida quando un altro analista può riprodurre la logica, criticare le assunzioni e ottenere la stessa decisione partendo dagli stessi dati.

Esempio o caso studio

Una source marketing smette di inviare campaign_id per una parte delle righe e il mart attribution continua a produrre numeri plausibili. Il caso mostra perché un contract e test di not-null, accepted values e relationship devono fallire presto, prima del dashboard.

Evidenza osservataLettura prudenteAzione consigliata
Il numero miglioraPotrebbe essere effetto reale o variazione normaleCercare confronto e segmento
Un segmento cambia più degli altriLa media aggregata nasconde una differenzaSeparare coorti o casi d’uso
Il costo cresce insieme al risultatoL’impatto va letto sul margineStimare trade-off e sostenibilità

Lab / esercizio

Livello base

Scrivi una scheda di una pagina per Test, contracts e fiducia nei modelli: decisione da supportare, metrica primaria, baseline, rischio principale e azione se il segnale e confermato.

Livello intermedio

Costruisci una tabella con tre segmenti, periodi o scenari. Per ciascuno indica cosa cambia, quale spiegazione alternativa e plausibile e quale controllo useresti prima di raccomandare un azione.

Livello research-grade

Prepara un decision memo: ipotesi, dati richiesti, criteri di esclusione, controlli di qualità, soglia decisionale, rischio residuo e piano di monitoraggio dopo la decisione.

Dataset e materiali consigliati

Usa dbt, warehouse, sorgenti CRM, eventi, marts, semantic layer e lineage. Se non hai accesso a dati reali, crea un dataset sintetico con almeno 200 righe, una dimensione temporale, una dimensione segmento e una metrica di outcome.

Errore tipico da evitare

L’errore più comune e usare Test, contracts e fiducia nei modelli come etichetta invece che come processo. Succede quando il team mostra un grafico senza decisione, una metrica senza baseline, o una conclusione senza indicare quale assunzione potrebbe invalidarla.

La domanda di controllo è: se questo risultato fosse instabile, quale scelta sbaglierei? Se la risposta non è concreta, manca ancora il collegamento tra analisi e azione.

Quiz o checkpoint

  1. Quale decisione concreta dovrebbe migliorare questa lezione?
  2. Quale unità di analisi rende il problema misurabile?
  3. Quale baseline useresti per evitare una lettura ingenua?
  4. Quale errore tipico potrebbe cambiare la conclusione?
  5. Quale output consegneresti a uno stakeholder non tecnico?

Riepilogo operativo

Test, contracts e fiducia nei modelli diventa utile quando produce una decisione più chiara, non quando aggiunge terminologia. Usa il framework problema, modello, formalizzazione, esempio, lab e checkpoint per trasformare la lezione in pratica verificabile. Categoria: Tecnico. Difficoltà: advanced. Tempo stimato: 18 min.