When are dbt tests enough, and when does a small team need more?

dbt tests are enough when your problems live inside dbt models you own and you can hand-write a test for every column that matters. dbt ships four built-in generic tests: unique, not_null, accepted_values, and relationships. You need more when coverage outgrows your typing, data breaks before it reaches dbt, or you need monitors that learn from history.

Key points

  • dbt ships four built-in generic tests (unique, not_null, accepted_values, relationships) plus the dbt source freshness command for sources; everything past those you write yourself in YAML or SQL, or pull from a package such as dbt-utils.
  • dbt build interleaves models and tests, so a failed test stops the model downstream of it; that makes a dbt test a working pipeline tripwire inside dbt.
  • Hand-written coverage doesn't scale: a bronze layer of 100 tables averaging 10 columns needs roughly 200 table tests and 2,000 column tests, a full Medallion architecture needs about 5,000, and hand-writing half of them at 30 minutes each takes 1,250 hours.
  • dbt sees only what runs through dbt; vendor files, Airflow tasks, Python scripts, and BI extracts sit outside its view.
  • DataKitchen estimates that DataOps TestGen generates about 80 percent of the tests you need from a data profile and runs them alongside dbt, leaving people to write the business rules.

dbt’s testing has one property worth keeping. Tests live in git next to the models, they get code review, and dbt build interleaves models and tests, so a failed test stops the model downstream of it. That’s a real pipeline gate. Keep it.

The question is what it leaves uncovered.

What dbt tests cover, and what they leave to you

dbt ships four built-in generic tests: unique, not_null, accepted_values, and relationships. For sources, the dbt source freshness command checks how long ago each one last loaded. Everything past those you write yourself, for every column, in YAML or SQL, or configure from a package such as dbt-utils.

Needdbt out of the boxWhat fills the gap
Primary key is unique and presentunique, not_nullNothing needed
Codes are on the allowed listaccepted_valuesNothing needed
Foreign keys resolverelationshipsNothing needed
Values in a sane range, dates not in the futureWrite each oneA generic test package, or generated tests
A column went from 2% null to 40% nullWrite a threshold you guessed in advanceA test or monitor that learns from history
Table stopped loading, row count halved, column vanisheddbt source freshness catches a stale source against limits you set; row counts and dropped columns aren’t built inTable monitors that learn from history
Vendor file broke before dbt ranOutside dbtTests on the file or the landing table
Business rule, such as shipped never exceeding orderedWrite itSomeone who knows the business writes it, in any tool

The last row doesn’t go away with any tool. Business rules are always yours.

dbt tests are enough when

Your problems live inside models you own. Your project is small enough that you can name every important column. Your sources are stable, or someone else watches them. And a failure that stops dbt build is the behavior you want. For a team running a few dozen models off one warehouse, that is a real and honest stopping point.

You need more when

The math stops working

In Where to Actually Start with DataOps in 2026, DataKitchen works it through: a bronze layer of 100 tables averaging 10 columns needs roughly 200 table tests and 2,000 column tests, and silver and gold want their own. The Guide to DataOps Tests totals a Medallion architecture at roughly 5,000 tests and prices it: writing half of them by hand, 2,500 tests at 30 minutes each, is 1,250 hours. So the keys get tested and the rest doesn’t.

Data breaks before dbt sees it

Vendor CSV files, API pulls, and loads from other teams arrive upstream of your models. dbt tests the models it builds, and your data also passes through Airflow, Python scripts, and BI extracts.

You need history, not a guess

A hand-set threshold is a number you typed. A monitor derives the expected row count or null rate from each table’s own past, which is the only way to cover thousands of tables. dbt’s built-ins don’t do that. Even dbt source freshness compares the last load against limits you set; it doesn’t learn them. Packages like Elementary add anomaly detection on top of dbt, and Boomi bought Elementary on October 19, 2026; Elementary says the open-source package continues.

Adding to dbt without replacing it

Keep your dbt tests as the gate inside dbt build. Then point a generator at the same database. DataOps TestGen profiles every column across 55 characteristics, generates tests from 34 test types, and adds freshness, volume, and schema monitors, all running as SQL in your warehouse. DataKitchen’s estimate is that generation covers about 80 percent of the tests you need. The remaining 20 percent is business logic, and that part you were always going to write.

Frequently asked questions

Short answers to the follow-up questions people ask next.

What tests come with dbt out of the box?

dbt ships four built-in generic tests: unique, not_null, accepted_values, and relationships. They cover primary keys, required fields, allowed values, and foreign keys. The dbt source freshness command flags a source whose last load is older than warn and error limits you set. Every other check, such as value ranges, date sanity, row-count trends, or business rules, you write yourself in YAML or SQL, or configure from a package such as dbt-utils, model by model.

Are dbt tests enough for data quality?

They are enough for a small, stable set of dbt models you own, where you can hand-write a test for every column that matters. They stop being enough when you have hundreds of tables, when bad data arrives before dbt runs, or when you need to know a column went from 2 percent null to 40 percent null, which a hand-set rule rarely anticipates.

How many dbt tests would I need to cover my warehouse?

More than anyone types. A bronze layer of 100 tables averaging 10 columns needs roughly 200 table tests and 2,000 column tests, and silver and gold want their own, for about 5,000 tests across a Medallion architecture. At 30 minutes per test, hand-writing just half of them, 2,500 tests, takes 1,250 hours. That arithmetic is why most dbt projects test the keys and stop.

Can I use TestGen with dbt?

Yes. TestGen connects to the same database dbt builds into, profiles the tables, generates tests, and runs them as SQL inside that database, without replacing dbt. DataOps Observability ships a dbt Core agent, so dbt runs show up next to Airflow, Fivetran, and Power BI in one view of the pipeline.

What happened to Elementary, the dbt observability package?

Boomi acquired Elementary Data on October 19, 2026. Elementary says the open-source dbt package continues. Elementary began in 2022 as a dbt-native observability project and raised about $8.5 million in seed money, according to DataKitchen's post on venture-funded open source.

Try it on your own data

DataOps TestGen is free and open source. Profile a table and generate its tests this afternoon.