Test data that
can't contradict itself.
Most fake-data tools fill each field on its own, so a record can be valid field by field and impossible as a whole. TDC builds the record instead of the fields — and gives you the very same rows in TypeScript, Python, Java, C# and Rust.
A record that makes sense
Fill every field independently and each value is fine on its own — while the record they add up to is impossible. A patient who is female and carries a diagnosis only men get. A Fiat with a model that belongs to a Nissan. A city from one state wearing the postcode of another.
Nothing is technically wrong, so nothing complains. You find out later: a test fails and looks like an application bug until someone opens the fixture, or a load test spends its whole run in the validator instead of in the feature it was supposed to measure.
TDC works the other way round. A field can be tied to a field chosen before it, and it then draws only from what that choice leaves reachable. The wrong list is not filtered out afterwards — it was never in reach.
The proportions you asked for
Ask a seeded generator for a 60/40 split and you get roughly 60/40 — usually. Over ten rows "roughly" can mean seven and three, and the edge case you were trying to cover is simply not in the data.
TDC allocates whole rows to groups before it fills any of them, so a 60/40 split over ten rows is six and four. Every run. The same holds several levels down: shares inside a group are applied inside that group, so a rule like "half of the men, a quarter of the women" comes out exact on both sides.
A signal you can draw
Ready-made distributions come in fixed shapes — a bell, a decaying tail. Real data often has a shape that is not on that list: demand that climbs toward noon and falls at night, two seasonal peaks where the second one is higher, the silhouette of a chart somebody screenshotted for you.
So draw it. Hand TDC a drawing or a picture of a curve, and its outline becomes the shape of your data, stretched across however many rows you asked for — ten thousand or ten million. Nothing is pre-rendered; each row works out its own point on the line.
The same data in five languages
A Java service, a Python pipeline and a TypeScript test suite usually agree on what the test data should look like, and then each of them builds its own. The three sets drift, and the bug that only reproduces in one of them costs a day to find.
TDC is one engine written five times over — TypeScript, Python, Java, C# and Rust — and held to a single shared suite of cases. One description and one seed produce the same rows in all five, down to the byte. That is checked on every change rather than promised.
And a few more problems it takes off your hands
All of it described in a short file, and none of it written in code.
-
Parent and child tables, linked
A customer with three orders comes out as one customer row and three order rows, each carrying the key back to its parent. One description, both tables, nothing orphaned.
-
Shared records, not loose values
Thirty doctors exist before the first patient does, and a patient row references a whole doctor — name, surname and room together — instead of drawing three unrelated values that happen to sit side by side.
-
Any shape of output
Not a fixed list of exporters. CSV, JSON, SQL inserts, YAML, a log format your parser expects — you describe the shape you want and get exactly that. Typed output goes to Parquet.
-
Millions of rows without the RAM
Large runs stream to disk instead of being assembled in memory, so the size of the dataset stops being a question of how much memory the machine has.
-
Anomalies and gaps, on purpose
Outliers, missing values and duplicates placed deliberately and in known quantities — so the path that handles bad data actually gets exercised.
-
Ten languages of source data
People, places, medical records and documents in ten languages, plus national ID formats for more than ninety countries, each with the right check-digit rule.
Take a look
The documentation is where all of this is actually explained.