DE//AGENT
Explore
Tutorial Lesson 6 of 10 · The Warehousing Series community beginner

Write the minimum dbt test set for a model

Start from the model's grain, then rank dbt tests by the cost of the failure they prevent: uniqueness and not-null on the grain key, relationships on foreign keys, accepted values on enums, and freshness on sources. You add one custom singular test, wire freshness on a source, and finish by running the set in data-aware CI against a staging schema.

At a glance

When A model's test set does not protect its grain key; A source has no freshness check while the extractor can stall silently
Where dbt
Why Uniqueness and freshness failures are the silent outages, and a test set ranked by blast radius catches them before consumers do.

Learning objectives

  • Rank dbt tests by blast radius instead of by effort
  • Add a singular test for a rule schema.yml cannot express
  • Wire freshness on a source and read its result

What you need

  • A dbt project with at least one model
  • models/schema.yml for generic tests
  • [object Object]

Steps

  1. State a model's grain and match it to its unique key test. (from skill-dbt-model-review )
  2. Rank tests by the cost of the failure they prevent. (from skill-dbt-test-writer )
  3. Write a custom singular test. (from skill-dbt-test-writer )
  4. Wire freshness on a source. (from skill-dbt-test-writer )
  5. Run data-aware CI against a staging schema. (from project-dbt-warehouse-tests )

Check yourself

  • schema.yml has unique + not_null on the declared grain key, and dbt test passes on the dev target.
  • The source block carries freshness thresholds, and dbt source freshness runs green.

Worked example

Install the dbt-test-writer skill — from skill-dbt-test-writer

npx de-agent-platform add dbt-test-writer

Test set ranked by blast radius in schema.yml — from skill-dbt-test-writer

# Rank by blast radius, not by effort
models:
  - name: <model>
    columns:
      - name: <grain key>      # 1. unique + not_null - the model is meaningless without it
        tests:
          - unique
          - not_null
      - name: <foreign key>    # 2. relationships - catches broken joins upstream
        tests:
          - relationships:
              to: ref('<dimension model>')
      - name: <enum column>    # 3. accepted_values - catches upstream renames
        tests:
          - accepted_values:
              values: [<allowed values>]

Run the test set with dbt build on the dev target — from project-dbt-warehouse-tests

dbt deps && dbt seed
dbt build --target dev

Sourced from

Security scan

Last sweep 2026-10-24: 0 finding(s), 0 marked as examples.

Common gotchas

  • Row-count equality tests on raw sources: they flake.
  • Testing a column nobody reads.
  • `warn` severity on a correctness test nobody will see.

Production considerations

  • Freshness on sources catches a stalled extractor, the #1 silent outage — run it on a schedule.
  • Keep warn severity off correctness tests nobody will see.

Diagram

dbt test set
   |
   |- state grain --> unique + not_null on grain key
   |
   |- rank by blast radius --> relationships --> accepted_values --> freshness
   |
   |- singular test --> run in data-aware CI on staging schema

Registry stats

Verification community · Oct 21, 2026
Completeness 81
Trust multiplier ×1.25
Composite 34.15 · adequate
Freshness 3 days since last source check
Difficulty beginner
Version 0.1.0
License CC-BY-4.0
Security flags none