Every developer has been there. You need to test a feature, so you manually insert a few rows into the database. You type [email protected], 123 Fake St, and John Doe as the name. It works for five minutes. Then you realize your pagination breaks at 11 records, your search function chokes on special characters, and your analytics dashboard looks empty because you only have three users.
Testing with real data is worse. Copying production data into a staging environment is a compliance nightmare, and one wrong query can expose customer PII. The answer is fake data: realistic-looking but entirely synthetic records that let you test your application thoroughly without risking anyone's privacy.
Why You Need Fake Data
Here is what happens when you test with [email protected] and John Doe everywhere:
- Your uniqueness constraints never get tested because every email is the same.
- Your UI layout breaks the first time someone has a 25-character name or an address with a line break.
- Your date handling looks fine until you get a birthday of February 29 in a non-leap year.
- Your pagination and search are untested because you have 3 records, not 3,000.
Fake data fixes all of this. You generate hundreds or thousands of realistic records, each with variety in length, format, character set, and edge cases. Then you actually find bugs before your users do.
What Makes Good Fake Data?
Not all fake data is created equal. Good mock data has four properties:
- Realistic: Names look like real names. Emails follow valid formats. Phone numbers have correct digit counts. You should not be able to tell the data is fake just by glancing at it.
- Varied: Not every user is named John. You need names with apostrophes (O'Brien), hyphens (Mary-Kate), non-Latin characters (Jose), and edge cases (names with spaces).
- Consistent: If a user is in Seattle, their phone number should have a Seattle area code. If their birthday says 1995, their age calculation should return 30, not 130.
- Safe: No real email addresses. No real phone numbers. No data that could identify a real person.
[email protected]is fine.[email protected]is not.
Generating Fake Data in JavaScript
The most popular library for fake data in JavaScript is @faker-js/faker. It generates names, emails, addresses, phone numbers, company names, lorem ipsum text, and dozens of other data types.
// npm install @faker-js/faker
import { faker } from '@faker-js/faker';
// Generate a single fake user
const user = {
id: faker.string.uuid(),
name: faker.person.fullName(),
email: faker.internet.email(),
phone: faker.phone.number(),
address: faker.location.streetAddress(),
city: faker.location.city(),
zipCode: faker.location.zipCode(),
birthDate: faker.date.birthdate({ min: 18, max: 90 }),
bio: faker.lorem.paragraph(),
avatar: faker.image.avatar(),
createdAt: faker.date.past()
};
console.log(user);
// {
// id: 'a1b2c3d4-...',
// name: 'Sarah Chen',
// email: '[email protected]',
// phone: '+1 (555) 123-4567',
// address: '742 Evergreen Terrace',
// city: 'Portland',
// zipCode: '97201',
// birthDate: 1991-03-15T...,
// bio: 'Lorem ipsum dolor sit amet...',
// avatar: 'https://avatars.example.com/...',
// createdAt: 2024-06-20T...
// }
Generating 10,000 users is just as easy:
const users = Array.from({ length: 10000 }, () => ({
id: faker.string.uuid(),
name: faker.person.fullName(),
email: faker.internet.email(),
role: faker.helpers.arrayElement(['admin', 'editor', 'viewer']),
active: faker.datatype.boolean(0.8), // 80% true
lastLogin: faker.date.recent({ days: 30 })
}));
Generating Relational Data
Real applications have relationships. Users have orders, orders have items, items have categories. Your fake data needs to respect these relationships:
// Generate users and their orders with proper foreign keys
const users = Array.from({ length: 100 }, () => ({
id: faker.string.uuid(),
name: faker.person.fullName(),
email: faker.internet.email()
}));
const orders = [];
for (const user of users) {
const orderCount = faker.number.int({ min: 0, max: 15 });
for (let i = 0; i < orderCount; i++) {
orders.push({
id: faker.string.uuid(),
userId: user.id, // foreign key to user
total: parseFloat(faker.commerce.price()),
status: faker.helpers.arrayElement(['pending', 'shipped', 'delivered', 'cancelled']),
date: faker.date.between({ from: '2026-01-01', to: '2026-08-18' })
});
}
}
console.log(`Generated ${users.length} users and ${orders.length} orders`);
Notice how userId on each order references a real user ID. This keeps your joins and cascading deletes working correctly during testing.
Generating Fake Data in Python
Python has the Faker library, which is just as capable:
# pip install faker
from faker import Faker
import json
fake = Faker()
# Generate a user
user = {
'id': fake.uuid4(),
'name': fake.name(),
'email': fake.email(),
'phone': fake.phone_number(),
'address': fake.address().replace('\n', ', '),
'company': fake.company(),
'job': fake.job(),
'created_at': fake.date_time_this_year().isoformat()
}
print(json.dumps(user, indent=2))
# {
# "id": "f47ac10b-58cc-...",
# "name": "Jennifer Wallace",
# "email": "[email protected]",
# "phone": "(555) 234-5678",
# "address": "123 Main St, Springfield, IL 62701",
# "company": "Turner LLC",
# "job": "Software Engineer",
# "created_at": "2026-03-14T10:22:31"
# }
# Generate 1000 users
users = [{
'id': fake.uuid4(),
'name': fake.name(),
'email': fake.email(),
'active': fake.boolean(chance_of_getting_true=80)
} for _ in range(1000)]
One feature I use constantly is Faker.seed(). Setting a seed makes your fake data deterministic. The same seed always produces the same data. This is essential for regression tests where you need reproducible results:
Faker.seed(42)
# Every run now produces identical data
# Great for snapshot tests and CI pipelines
Generating Fake Data in SQL
If you need to populate a database directly, you can generate SQL insert statements with fake data. Here is a pattern that works across PostgreSQL, MySQL, and SQLite:
-- Generate 1000 users with varied data
INSERT INTO users (id, name, email, phone, created_at)
SELECT
gen_random_uuid(),
(array[
'Alice Chen', 'Bob Martinez', 'Carol O''Brien',
'David Kim', 'Eva Novak', 'Frank Delgado',
'Grace Park', 'Henry Walsh', 'Iris Tanaka',
'James Patel'
])[1 + (random() * 9)::int],
'user' || (1000 + g)::text || '@example.com',
'+1 (555) ' || lpad((100 + (random() * 899)::int)::text, 3, '0') || '-' || lpad((1000 + (random() * 8999)::int)::text, 4, '0'),
NOW() - (random() * INTERVAL '365 days')
FROM generate_series(1, 1000) AS g;
This is PostgreSQL-specific syntax, but the pattern translates. The key is generating variety in every column so your application gets exercised against realistic data.
Unique Identifiers for Test Data
IDs are the backbone of relational data. When generating test data, you need unique identifiers that do not collide. UUIDs are the standard choice:
// JavaScript: generate a UUID v4
// Using crypto.randomUUID() (built into modern browsers and Node.js)
const id = crypto.randomUUID();
// => "f47ac10b-58cc-4372-a567-0e02b2c3d479"
// Python
import uuid
id = str(uuid.uuid4())
For a quick UUID without writing code, use our free online UUID generator. It generates multiple UUIDs at once, which is handy when you need to pre-populate a set of IDs before inserting related records.
If you need shorter IDs for things like URL slugs or shareable links, NanoID is a great alternative. It is URL-safe, compact (21 characters by default), and collision-resistant.
Generating Test Passwords
Test accounts need passwords too. But do not use real passwords, and definitely do not reuse your own. Generate random ones:
// JavaScript: generate a random password for test accounts
function generateTestPassword(length = 16) {
const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789!@#$%^&*';
let password = '';
const array = new Uint32Array(length);
crypto.getRandomValues(array);
for (let i = 0; i < length; i++) {
password += chars[array[i] % chars.length];
}
return password;
}
console.log(generateTestPassword());
// => "xK7!mP2#nQ9$vR4*"
For generating passwords without writing code, our free password generator lets you control length, character sets, and complexity. The passwords it generates are strong enough for test accounts that simulate real security constraints.
One note: if you are testing authentication flows, hash the passwords before storing them. Never store plaintext passwords, even fake ones. It builds bad habits.
Generating Lorem Ipsum and Text Content
Applications that display user-generated content need text for testing. Blog posts, comments, product descriptions, chat messages. Lorem ipsum is the standard placeholder text, but you can also generate realistic-looking sentences:
// Using Faker
faker.lorem.sentence(); // "The quick brown fox jumps over the lazy dog."
faker.lorem.paragraph(); // Multiple sentences
faker.lorem.paragraphs(3); // Three paragraphs
// For product descriptions
faker.commerce.productName(); // "Handmade Cotton Keyboard"
faker.commerce.productDescription(); // "Ergonomic design with soft-touch keys..."
// For review text
faker.lorem.sentence(10); // A 10-word sentence
For quick placeholder text without a library, use our Lorem Ipsum generator. It produces paragraphs, sentences, or individual words in the quantity you need.
Using an Online Fake Data Generator
Sometimes you do not want to write a script. You just need 50 rows of fake user data to paste into a spreadsheet or a database. That is where an online fake data generator comes in.
Our free online fake data generator lets you pick the fields you need (name, email, phone, address, company, and more), choose the number of rows, and export as JSON or CSV. Everything runs in your browser, so no data gets sent to a server.
This is especially useful for:
- Quick prototyping when you need sample data in a spreadsheet
- Testing CSV imports with varied, realistic records
- Demo environments that need to look populated
- QA testing where you need different data sets without setting up a script
Best Practices for Test Data
- Use seeded random generation for tests. Set a fixed seed so test runs are reproducible. If a test fails, you can reproduce the exact same data.
- Generate more data than you think you need. If your pagination shows 10 items per page, test with at least 25 records. If your search supports fuzzy matching, include names with special characters.
- Include edge cases deliberately. Add a user with a 1-character name. Add one with a 200-character bio. Add one with an email that is exactly 254 characters (the RFC max). See what breaks.
- Never use real customer data in test environments. Even anonymized production data can leak information. Synthetic data has no privacy risk.
- Refresh test data periodically. If your test database accumulates stale fake data, clear it and regenerate. Old test data can mask new bugs.
- Keep data consistent across related tables. If a user references a country code, make sure that country exists in your countries table. Broken foreign keys cause false test failures.
Wrapping Up
Fake data is not just about filling an empty database. It is about testing your application against the kind of messy, varied, edge-case-heavy data it will encounter in production. The few minutes you spend generating proper test data will save you hours of debugging later.
The approach is simple: use a library like Faker in whatever language you are working with, generate more data than you think you need, seed your generators for reproducibility, and always include edge cases. If you need quick data without writing code, the free online fake data generator handles it. Pair it with the UUID generator for unique IDs, the password generator for test credentials, and the Lorem Ipsum generator for text content.
Stop testing with [email protected]. Your future self will thank you.