Skip to content
Back to skills

Testing Dbt Projects

ASecurity

Add data quality tests to a dbt project — generic tests (unique, not_null, accepted_values, relationships), singular tests, unit tests, dbt-utils and dbt-expectations packages, and source freshness. Use when adding tests to dbt models, catching data quality regressions, validating assumptions, or setting up source freshness checks.

  • 15 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 1, 2026
ai-agentssqlexpresstesting

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 1, 2026

npx -y skills add Unknown-333/awesome-data-engineering-skills --skill testing-dbt-projects --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Testing Dbt Projects?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Testing Dbt Projects
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/unknown-333-testing-dbt-projects/badge)](https://www.skillsdirectory.com/skills/unknown-333-testing-dbt-projects)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: testing-dbt-projects
description: Add data quality tests to a dbt project — generic tests (unique, not_null, accepted_values, relationships), singular tests, unit tests, dbt-utils and dbt-expectations packages, and source freshness. Use when adding tests to dbt models, catching data quality regressions, validating assumptions, or setting up source freshness checks.
---

# Testing dbt Projects

## When to use

- Adding or improving tests on dbt models and sources.
- Guarding a known assumption (grain, referential integrity, value ranges).
- Validating transformation logic with fixed inputs (unit tests).
- Setting up source freshness monitoring.
- Do NOT use for optimizing model SQL (use `building-dbt-models`).

## Workflow

```
- [ ] Add grain test: unique + not_null on the primary/surrogate key
- [ ] Add relationships tests for every foreign key
- [ ] Add accepted_values / range tests for constrained columns
- [ ] Add singular/unit tests for critical business logic
- [ ] Configure source freshness
- [ ] Run: dbt test (and dbt build to test as you materialize)
```

1. **Test the grain first** — `unique` + `not_null` on the key catches the most
   common and most damaging bug (fan-out duplicates).
2. **Test relationships** — every foreign key should point to an existing parent.
3. **Constrain values** — `accepted_values` for enums, range checks for numerics.
4. **Unit-test logic** — for tricky CASE/window/dedup logic, assert exact output
   from fixed input (dbt 1.8+ `unit_tests`).
5. **Freshness** — alert when a source stops updating before models run stale.

## Patterns

**Generic tests in schema.yml:**

```yaml
models:
  - name: fct_orders
    columns:
      - name: order_id
        tests: [unique, not_null]
      - name: customer_id
        tests:
          - relationships:
              to: ref('dim_customer')
              field: customer_id
      - name: status
        tests:
          - accepted_values:
              values: ["placed", "shipped", "delivered", "cancelled"]
```

**Range/expression test (dbt-utils / dbt-expectations):**

```yaml
- name: amount
  tests:
    - dbt_expectations.expect_column_values_to_be_between:
        min_value: 0
```

**Unit test (fixed input → expected output):**

```yaml
unit_tests:
  - name: test_net_amount_excludes_tax
    model: fct_orders
    given:
      - input: ref('stg_orders')
        rows:
          - { order_id: 1, gross: 110, tax: 10 }
    expect:
      rows:
        - { order_id: 1, net_amount: 100 }
```

**Source freshness:**

```yaml
sources:
  - name: shop
    freshness:
      warn_after: { count: 12, period: hour }
      error_after: { count: 24, period: hour }
    loaded_at_field: _loaded_at
```

## Common pitfalls

- **No uniqueness test on the grain** — duplicates slip through and inflate metrics.
- **Testing only staging** — bugs are introduced in joins; test marts too.
- **Warn severity on critical tests** — set `severity: error` (or thresholds) so
  bad data actually blocks the run.
- **Slow tests on huge tables** — add `where`/`limit` config or sampling; use
  `store_failures` to inspect offenders.
- **Unit tests over real data** — unit tests must use fixed `given` rows, not
  live tables.

## References

- [Recommended test coverage per layer](references/COVERAGE.md)

Files in this skill

  • SKILL.md3.2 KB
  • references/COVERAGE.md993 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…