Canada Test Data Generator

Whole synthetic records for QA, staging and CI: name, company, address, email and phone, reproducible from a seed.

Whole records, not just addresses

Name, company, address, email and phone, generated together and consistent with each other — a Quebec record gets a French-form address and a name that reads naturally alongside it.

Everything runs on the same seeded generator as the address tool, so a record set is reproducible from its seed.

What this generator will not produce, ever

These are not settings. They are constraints on what the tool is, and they are the reason it is safe to paste output into a ticket or commit it to a repository.

The reproducible fixture workflow

The point of a seed is that a fixture stops being a snapshot and becomes a recipe. Instead of committing five hundred records, commit the seed and the options that produced them.

A record set is identified by three things: the seed, the options, and the data version. Same three, same records, permanently. Every export and every API response carries all three.

// Instead of a 500-record JSON fixture in your repository:
const FIXTURE = { seed: 20260904, province: "ON", count: 500, dataVersion: 1 };

beforeAll(async () => {
  const res = await fetch(`/api/v1/addresses?province=${FIXTURE.province}` +
    `&count=100&seed=${FIXTURE.seed}`);
  const { data, meta } = await res.json();

  // If this ever fails, the generator data changed — that is the explanation
  // for records differing, and the reason to pin it.
  expect(meta.dataVersion).toBe(FIXTURE.dataVersion);
  records = data;
});

Why pin the data version

A seed selects a path through the generator’s data. Change the data — add a city, correct a postal district, extend the street vocabulary — and the same seed lands somewhere else.

That is not a bug, it is unavoidable, and the only honest response is to make it visible. Assert on the data version in your fixture setup and a change announces itself as a clear failure rather than as a diff you have to explain.

What a record contains

FieldExampleNotes
namePriya SandhuGiven and family names drawn independently; never a real person
companyNorthwind Logistics Inc.Optional; French suffixes for Quebec records
addressLine1100-1234 Yonge St WUnit-hyphen-civic, or a rural or PO box form
addressTypeciviccivic, rural, poBox or generalDelivery
localityTorontoReal municipality, mapped to its real region
province / provinceTypeON / provinceBranch on provinceType rather than a list of three codes
postalCodeM5V 3L9String, always. Valid first letter for the region
emailp.sandhu@example.comReserved domains only
phone555-0142Reserved range only

Questions

Can I get a SIN or a credit card number for testing?

No, and the tool will not be extended to provide them. For payment testing, use the test card numbers your payment provider publishes — they are designed for it and are safe in a way a generated number is not.

Are the phone numbers safe to call?

They are in the 555-01XX range, which is reserved for fictional use and not allocated to subscribers, so they do not reach anyone. That is why the range is the only one used.

Can I commit generated records to my repository?

Yes — the data is synthetic and represents no one. Better still, commit the seed and the options instead of the records, and regenerate. A recipe stays small and stays honest about where the data came from.

Why did my committed fixture change?

Almost certainly because the data version changed. Compare the dataVersion in your stored response with the current one. If they match and the records differ, that is a bug worth reporting.

Do the names belong to real people?

No. Given names and family names are drawn independently from separate pools, so a full name is a combination rather than a person. Any resemblance to a specific individual is coincidence.

Related

Everything this site generates is synthetic, produced for development, QA, testing, demos and staging. The records do not represent real people, and the addresses are not verified deliverable addresses.