The difference is the order of operations. dbt and Great Expectations start with you: you decide what could break, then write a test for it. TestGen starts with the data. It profiles every column, and the tests come out of what it finds.
That sounds like a small distinction until you count.
Three tools, side by side
dbt rows come from DataKitchen’s Microsoft data quality review, which covers dbt jobs; the two cells marked “DataKitchen’s reading” are our description, not dbt’s documentation. GX Core rows come from the TestGen vs GX OSS comparison, reviewed June 11, 2026. TestGen rows come from the product page, as of October 2026. We sell TestGen, so check the TestGen column against your own install.
| dbt tests | GX Core | DataOps TestGen | |
|---|---|---|---|
| Who writes each test | You, in YAML or SQL, per model | You, as Python expectations | Generated from a profile; you add business rules |
| Starting set | Four built-in generic tests: unique, not_null, accepted_values, relationships | Expectations you choose and configure | 34 generated test types, 32 hygiene detectors, 19 configurable test types |
| Profiles the data first | Not part of dbt’s built-in tests (DataKitchen’s reading) | Profiling, but tests aren’t generated from it | Yes, 55 characteristics per column |
| Anomaly monitors | Not built in; packages such as Elementary, now owned by Boomi, add them | Rule-based | Freshness, volume, schema, and custom metric monitors that learn from history |
| Where results live | Run artifacts; the tests sit in git next to the models (DataKitchen’s reading) | Wherever you send them: you wire up the runner and build the dashboard | Web UI with test results, scorecards, and a catalog |
| Stops a pipeline | Yes: dbt build halts the downstream model | When you wire it into the pipeline | Runs on a schedule or on demand |
| Best at | Gating the models you own | Checks as code next to a pipeline step | Coverage across many tables |
The second row is the one that matters. A starting set of four tests is a vocabulary. A starting set of 34 generated types, applied to every column the profile finds, is coverage.
Why the order of operations matters
dbt and GX Core assume you can anticipate every failure. Usually you can’t, and when you can, you don’t have time to type it. DataKitchen’s Medallion testing post does the arithmetic. A three-layer Medallion needs about 5,000 tests. Hand-writing just half of them at 30 minutes each is 1,250 hours, or about 7.2 months of a senior engineer doing nothing else. So the keys get tested and the rest waits.
The argument for generating 80 percent is that dbt, GX, and Soda Core are all domain-specific languages. They make each test faster to write. Every test still starts as code. TestGen’s answer is to skip the writing for the mechanical checks (nulls, ranges, lengths, patterns, uniqueness) and put a UI in front of the results, so a data steward who doesn’t write Python can review them.
Where dbt and GX Core still win
dbt’s tests live in git, get code review, and stop a bad model from building. TestGen doesn’t replace that gate. Keep it, and point TestGen at the same database. When dbt tests are enough covers the cases where you need nothing else.
GX Core wins when your checks belong in Python next to the step they guard, and when you have several engineers and no budget. GX Core software costs $0 at any team size. Open-source TestGen is free for one user, one connection, and one project; a second user needs Enterprise at $100 per user and $100 per connection per month, per the pricing page. TestGen or Great Expectations has that head-to-head, including how GX Cloud shut down on June 1, 2026.
What generated tests can’t do
They learn the data in front of them, including what’s normally wrong. In DataKitchen’s NYC taxi run, 62 generated tests passed on a 300,000-row sample. The minimum-fare test had set its floor at negative $367, the lowest fare present. Somebody has to write the rule that a fare is never negative. Can AI write your data quality tests covers what happened when an AI drafted those rules and they ran on the full month.
So the honest split is 80 and 20. Generation writes the 80. The 20 is business logic, and in dbt, GX, or TestGen, that part is yours.