Test Data Generator
Generate repeatable synthetic test records from a field recipe and seed, with format-aware output and checks for blanks or normalized fields.{{ summaryTitle }}
{{ summaryLine }}
{{ summaryAnnouncement }}
{{ computation.values.output_text }}
The chart renderer is unavailable. The field counts remain available in the recipe ledger.
| Field | Type | Options | Blank rate | Example | Unique | Copy |
|---|---|---|---|---|---|---|
| {{ row.field }} | {{ row.type_label }} | {{ row.options_label }} | {{ row.blank_percent }}% | {{ displayCell(row.example) }} | {{ row.unique_count }} |
Introduction
Useful test data preserves the shapes that software must handle without borrowing real customer records. Field names, value types, optional blanks, date ranges, category choices, quoting, and row volume can all change whether an import or feature behaves correctly. The values themselves only need to be believable enough to exercise those paths.
A fixture is a saved set of test records. Small fixtures suit unit tests and focused interface checks because a person can inspect every row. Larger fixtures are better for pagination, bulk imports, sorting, and performance smoke tests. Starting small makes failures easier to explain; adding deliberate edge cases later reveals behavior that a tidy baseline cannot.
| Fixture choice | What it tests | Common mistake |
|---|---|---|
| Stable seed | Reproduces the same ordered records for a fixed recipe and row count. | Changing the data while investigating a regression. |
| Controlled blanks | Exercises optional fields, null handling, and import defaults. | Leaving every cell populated and missing recovery paths. |
| Fixed date range | Keeps generated dates valid and repeatable over time. | Using the current date and getting a different fixture next month. |
| Non-production domain | Keeps generated email addresses and links away from real recipients. | Using a customer or company domain in a fixture. |
Synthetic does not automatically mean representative or anonymous. A short built-in name list cannot model a population, and a copied production category can reveal business information even when personal names are removed. Security tests also need purpose-built values rather than ordinary sample strings.
Repeatability and variety solve different problems. Keep one stable baseline for regression checks, then create separate recipes for missing values, unusual ranges, quoting, and boundary conditions. That preserves a clear reference while still widening coverage.
How to Use This Tool:
Begin with the consumer of the fixture: a test runner, import path, seed script, or scratch table. Its expected field names and format determine the smallest useful recipe.
- Write one line per field in Field recipe using a name, type, and optional settings, such as
id:sequence:start=1001,step=5orplan:choice:Basic|Team|Enterprise. Load a text recipe when it is easier than pasting. - Set Rows, Output format, and a stable Seed. Keep the same seed, recipe text, and row count when another run must reproduce the same records.
- Use Advanced only for a real test need. Fix the date endpoints, choose a non-production email domain, add a blank rate, or change the default sequence start. SQL output also needs the destination table name and dialect.
- Read any warning before using the dataset. A renamed duplicate field or inferred type changes the schema even when generation succeeds, so confirm the normalized field names in Recipe ledger.
Interpreting Results:
The generated text is ready only when its field names and serialized values match the receiving system. Check the first record, then use Recipe ledger to confirm each normalized field, type, blank rate, example, and unique-value count. A warning means the generator recovered from ambiguous recipe text; it does not prove that the inferred schema is the one you intended.
The same canonical records feed CSV, JSON, NDJSON, and SQL output, so switching format does not create a new dataset. SQL output produces insert statements but does not inspect a live schema, enforce foreign keys, or prove that the statements will succeed in the target database.
Technical Details:
A field recipe is parsed before any record is generated. Blank lines and lines beginning with # are ignored. Field names are reduced to letters, numbers, and underscores; names that start with a number receive a safe prefix, and repeated names gain a numeric suffix. A missing or unknown type is inferred from the field name when possible and otherwise falls back to a word value.
Formula Core:
Sequence fields are the direct arithmetic path. Each row advances from the configured start by one fixed step, and sequence values never become blank.
- xi is the generated sequence value for a row.
- s is the field-level start, or the default sequence start when no field override is supplied.
- i is the zero-based row index and d is the integer step.
Transformation Core:
The transformation has four ordered stages. This order matters because the parsed recipe text and requested row count are part of the random stream.
- Parse: split each non-comment line into field name, type, and comma-separated options.
- Normalize: repair field names, resolve type aliases, de-duplicate names, and apply global or field-level defaults.
- Generate: create rows from a seeded pseudo-random stream derived from the seed, original parsed field lines, and row count.
- Serialize: render the same row objects as CSV, a JSON array, one JSON object per line, or SQL insert statements.
| Recipe behavior | Exact rule |
|---|---|
| Blank rate | Each non-sequence cell receives an independent seeded draw. A field-level blank option overrides the global rate. |
| Date | A whole calendar day is drawn from the fixed endpoints, including both dates. Reversed endpoints are treated as the same range. |
| Integer | The endpoints are reordered when necessary and both integer bounds are eligible. |
| Number and money | A value is drawn between the endpoints and rounded to 0 to 6 decimal places; the default is 2. |
| UUID | Sixteen seeded bytes are formatted with version 4 and RFC variant marker bits. These fixture UUIDs are repeatable, not cryptographic random tokens. |
Generation accepts 1 to 500 rows and no more than 24 parsed fields. The recipe may contain up to 32 KB, the seed up to 120 characters, and the global blank rate ranges from 0% through 100%. Changing the output format alone preserves the records; changing the recipe text, seed, or row count changes the seeded stream.
| Format | Serialization rule |
|---|---|
| CSV | Commas, quotes, and line breaks trigger double-quote wrapping; embedded quotes are doubled. Null values become empty cells. |
| JSON | Rows form an indented array under a normalized root key. An empty root currently becomes field_; null values remain null. |
| NDJSON | Each row is one complete JSON object on its own line; the JSON root setting does not apply. |
| SQL | Identifiers and boolean literals follow the selected dialect. Strings escape single quotes and blank values become NULL. |
Accuracy and Privacy Notes:
Recipes and generated records are processed in the browser. They are not submitted for remote generation. Treat copied files and shared links according to the data they contain, because a fixture can still reveal internal field names, categories, pricing, or workflow details.
- The embedded names, places, companies, and phrases are illustrative and are not statistically representative.
- Generated values are not suitable for production identities, credentials, authorization tokens, demographic studies, or compliance evidence.
- Use a domain such as
example.testfor generated addresses instead of a real customer or company domain.
References:
- RFC 2606: Reserved Top Level DNS Names, RFC Editor, June 1999.