Data Quality Testing
Tests, contracts and freshness checks — catching a wrong number before it reaches a decision.
Wrong Is Worse Than Missing
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.
| Dimension | Question |
|---|---|
| Completeness | Is anything missing that should be here |
| Accuracy | Does it match reality |
| Consistency | Do two systems agree |
| Timeliness | Is it recent enough to use |
| Uniqueness | Is anything duplicated |
| Validity | Does 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 }
| Test | Catches |
|---|---|
| Not null on a key | A broken join upstream |
| Unique on the grain | Duplicate loads and fan-out |
| Referential | Orphan facts pointing at nothing |
| Accepted range | Negative revenue, ages of 400 |
| Row-count delta | A source that returned half the data |
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 states | So that |
|---|---|
| Schema and types | A rename fails the producer's build, not your dashboard |
| Semantics and units | "amount" is pence, gross, and excludes refunds |
| Freshness guarantee | Consumers know what "current" means |
| Ownership | There is someone to ask |
| Change process | Breaking 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.
| Signal | Catches |
|---|---|
| Freshness | A feed that stopped — the most common incident |
| Volume | Half the rows, or ten times too many |
| Null rate per column | An upstream field quietly emptying |
| Distribution drift | A currency or unit change, a new category |
| Schema change | Columns appearing or disappearing |
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.