Prompt template · Data
Test data generation prompt
Realistic fixtures that match your schema, with deliberate edge cases and clearly fake personal data. Free to copy, or open it in the prompt builder to fill the variables and get the exact API request.
203 tokens unfilled · 326 with the example below · o200k_base (GPT-4o and later)
Template
The prompt
Paste this into a chat window and replace each {{variable}}, or open it in the prompt builder to fill them in a form. Sections are marked with XML tags, which every major model reads well.
You generate realistic test data that exercises edge cases. You never produce real people’s personal data.
<context>
The schema and validation rules:
<schema>
{{schema}}
</schema>
</context>
<constraints>
- Every record must be valid against the schema and rules, unless it is listed as a deliberately invalid case.
- Include these edge cases: {{edge_cases}}.
- Vary values realistically: lengths, distributions, character sets (including non-ASCII names), dates across years and time zones.
- Personal data must be clearly fake: emails at example.com, phone numbers from reserved test ranges where they exist, no real people’s names combined with real addresses.
- Keep the data internally consistent (an order’s total equals its line items).
</constraints>
<output_format>
{{output_format}}, in one code block. After it, a list mapping each edge case to the record IDs that cover it.
</output_format>
<task>
Generate {{count}} records for {{purpose}}.
</task>For an API call: system prompt and user message
With a system prompt, the role, constraints and output format stay fixed across calls (and can be cached), while the context and task go in the user message.
You generate realistic test data that exercises edge cases. You never produce real people’s personal data.
<constraints>
- Every record must be valid against the schema and rules, unless it is listed as a deliberately invalid case.
- Include these edge cases: {{edge_cases}}.
- Vary values realistically: lengths, distributions, character sets (including non-ASCII names), dates across years and time zones.
- Personal data must be clearly fake: emails at example.com, phone numbers from reserved test ranges where they exist, no real people’s names combined with real addresses.
- Keep the data internally consistent (an order’s total equals its line items).
</constraints>
<output_format>
{{output_format}}, in one code block. After it, a list mapping each edge case to the record IDs that cover it.
</output_format><context>
The schema and validation rules:
<schema>
{{schema}}
</schema>
</context>
<task>
Generate {{count}} records for {{purpose}}.
</task>Variables
What to put in each variable
- {{schema}}
- The table definition, TypeScript type, JSON Schema or Pydantic model, plus business rules such as “end_date after start_date”.
- {{count}}
- How many records, such as 25. Small sets with deliberate coverage beat large random ones for tests.
- {{purpose}}
- What the data is for, such as “unit tests of the invoice PDF renderer” or “a demo account”.
- {{edge_cases}}
- The cases you need covered, such as “empty optional fields, a 200-character name, a total of 0, a leap-day date”.
- {{output_format}}
- The format, such as JSON array, CSV with a header, or SQL INSERT statements.
Use
When to use it
Use it to build fixtures for tests, seed data for a staging environment or a demo account that looks real. It is most useful when the data has rules (consistent totals, valid dates, realistic names across languages) that random generators ignore.
For large volumes or property-based testing, use a generator library such as Faker or Hypothesis; they are reproducible and free. This template is for small, deliberate sets where each record has a reason to exist.
Structure
Why it’s structured this way
The schema plus rules is what makes generated data valid. Types alone produce records that parse but break business logic, such as end dates before start dates, so the rules are part of the same section.
Edge cases are a variable because they are the point of test data. Listing them explicitly, and asking for a map from case to record IDs, turns the output into coverage you can check rather than a pile of plausible rows.
The fake-personal-data rule is a privacy safeguard. Models can reproduce real names and addresses they have seen; example.com emails and obviously synthetic details keep fixtures safe to commit and share.
Example
A filled-in example
- {{schema}}
type Booking = { id: string; // "bk_" + 6 digits guestName: string; // 1-120 chars email: string; checkIn: string; // YYYY-MM-DD checkOut: string; // after checkIn guests: number; // 1-8 totalPence: number; // nights * nightly rate, rate 4,500-30,000 };- {{count}}
12
- {{purpose}}
unit tests of the booking confirmation email
- {{edge_cases}}
a one-night stay, a stay across New Year, a 120-character guest name, a non-Latin guest name, 8 guests
- {{output_format}}
A JSON array
What to look for. The consistency rule matters here: each totalPence must equal the number of nights times a rate in range, which is easy to check in a test and easy for a careless generator to get wrong. The coverage map should name at least one record per edge case.
The complete filled-in prompt (326 tokens)
You generate realistic test data that exercises edge cases. You never produce real people’s personal data.
<context>
The schema and validation rules:
<schema>
type Booking = {
id: string; // "bk_" + 6 digits
guestName: string; // 1-120 chars
email: string;
checkIn: string; // YYYY-MM-DD
checkOut: string; // after checkIn
guests: number; // 1-8
totalPence: number; // nights * nightly rate, rate 4,500-30,000
};
</schema>
</context>
<constraints>
- Every record must be valid against the schema and rules, unless it is listed as a deliberately invalid case.
- Include these edge cases: a one-night stay, a stay across New Year, a 120-character guest name, a non-Latin guest name, 8 guests.
- Vary values realistically: lengths, distributions, character sets (including non-ASCII names), dates across years and time zones.
- Personal data must be clearly fake: emails at example.com, phone numbers from reserved test ranges where they exist, no real people’s names combined with real addresses.
- Keep the data internally consistent (an order’s total equals its line items).
</constraints>
<output_format>
A JSON array, in one code block. After it, a list mapping each edge case to the record IDs that cover it.
</output_format>
<task>
Generate 12 records for unit tests of the booking confirmation email.
</task>Models
Tips by model family
- OpenAI GPT
Structured Outputs can enforce the record shape, but OpenAI’s supported schema features are a subset of JSON Schema; check that your patterns and limits are supported before relying on them.
- Claude
Anthropic’s structured outputs return a 400 error for numeric limits such as
minimum, so keep ranges like “1–8 guests” in the prompt text and validate them in your test setup. - All models
Commit the generated fixture, not the prompt output on each test run. Tests need data that doesn’t change between runs.
Related
Related templates and tools
- Write unit testsTests for normal cases, edge cases and errors in your framework, focused on behaviour rather than implementation.
- Clean and normalise dataNormalise messy records to your rules, flag the rows it can’t fix, and never drop or invent data.
- Generate eval test casesDraft realistic, edge-case and adversarial inputs for your prompt, each with the expected behaviour.
Edited the template? Compare your version with this one in the prompt diff, and count it for your model with the token counter. In the glossary: structured outputs. Browse all 29 prompt templates.