Data · Guide

Data Quality Testing

Tests, contracts and freshness checks — catching a wrong number before it reaches a decision.

— min read Data

Wrong Is Worse Than Missing

A broken pipeline is an incident someone notices. A pipeline that quietly produces wrong numbers is a decision made on them — and nobody finds out until a quarter later, if at all.

Data quality work is the discipline of making incorrect data loud. The measures are unglamorous — counts, ranges, uniqueness, freshness — and they catch the overwhelming majority of real problems, because most data incidents are not subtle.

DimensionQuestion
CompletenessIs anything missing that should be here
AccuracyDoes it match reality
ConsistencyDo two systems agree
TimelinessIs it recent enough to use
UniquenessIs anything duplicated
ValidityDoes it satisfy the rules — types, ranges, enums

Tests In The Pipeline

Tests belong in the run, not in a report someone reads afterwards. A failing test should stop the pipeline before the bad table is published, in the same way a failing unit test stops a deploy.

# dbt: tests declared next to the model they defend
models:
  - name: revenue_daily
    columns:
      - name: date_day
        tests: [unique, not_null]
      - name: revenue
        tests:
          - dbt_utils.accepted_range: { min_value: 0 }
      - name: store_id
        tests:
          - relationships: { to: ref('dim_store'), field: store_key }
TestCatches
Not null on a keyA broken join upstream
Unique on the grainDuplicate loads and fan-out
ReferentialOrphan facts pointing at nothing
Accepted rangeNegative revenue, ages of 400
Row-count deltaA source that returned half the data
Test the grain with a uniqueness check on the key you claim is unique. It is one line, and it is the single most effective test in a warehouse because duplication is the most common way totals go wrong.

Data Contracts

Most breakages start upstream: a producing team renames a column, changes a unit, or starts sending nulls, with no idea anyone was reading it. A data contract makes that dependency explicit — a declared schema, types, semantics and guarantees, versioned and checked in the producer's CI.

Contract statesSo that
Schema and typesA rename fails the producer's build, not your dashboard
Semantics and units"amount" is pence, gross, and excludes refunds
Freshness guaranteeConsumers know what "current" means
OwnershipThere is someone to ask
Change processBreaking changes are versioned, not surprises

The cultural part matters more than the tooling: a contract works because a producing team accepts that other people depend on their output. Without that, it is a document that describes what used to be true.

Freshness, Volume & Anomalies

Tests assert what you already know to check. Monitoring watches for the shape of the data changing in ways nobody predicted.

SignalCatches
FreshnessA feed that stopped — the most common incident
VolumeHalf the rows, or ten times too many
Null rate per columnAn upstream field quietly emptying
Distribution driftA currency or unit change, a new category
Schema changeColumns appearing or disappearing
Alert on the few signals that mean something and route them to an owner. A wall of quality alerts nobody triages is indistinguishable from no monitoring at all — the failure mode is identical to a flaky test suite.

Publish freshness where consumers can see it. A dashboard that states "data as of 06:14 today" prevents the entire class of incident where someone acts on yesterday's numbers believing they are live.

Interview Questions

Why is wrong data worse than missing data?

Missing data is visible and stops work. Wrong data is invisible and gets acted on — the incident surfaces long after the decision, if at all.

Which single test earns its place most?

Uniqueness on the declared grain. Duplication is the most common cause of wrong totals, and the test is one line.

Where should quality tests run?

Inside the pipeline, blocking publication. A report generated afterwards means the bad table was already available to consumers.

What is a data contract?

An explicit agreement between producer and consumer covering schema, types, semantics, freshness and ownership, checked in the producer's CI so a breaking change fails their build rather than your dashboard.

Tests or monitoring?

Both. Tests assert what you know to check; monitoring watches freshness, volume, null rates and distributions for changes nobody anticipated.

Why publish freshness to consumers?

It prevents the whole class of incident where someone acts on stale data believing it is current — the cheapest quality control there is.

Quick Quiz

1. The most common data incident is…
2. Quality tests should run…
3. A uniqueness test on the grain catches…
4. A data contract is enforced most usefully in…
5. A wall of untriaged quality alerts is…