Overview
Faker is a family of libraries (Python / JS / Ruby / Java / .NET / PHP) that generate realistic synthetic field values - names, emails, addresses, dates, etc. - for test fixtures. The three most common ports in this skill's scope:
| Language | Library | Reference |
|---|---|---|
| Python | faker | faker-py (opens in new window) |
| JS / TS | @faker-js/faker | faker-js (opens in new window) |
| Ruby | faker-ruby/faker | faker-rb (opens in new window) |
For .NET (Bogus) and Python-specifically with stronger locale coverage (mimesis), see synthetic-data-toolkit.
When to use
Install
Python
pip install Faker(Per faker-py (opens in new window).)
JavaScript / TypeScript
npm install --save-dev @faker-js/faker(Per faker-js (opens in new window).)
Ruby
# Gemfile
gem 'faker', group: :test(Per faker-rb (opens in new window).)
Authoring
Python
from faker import Faker
fake = Faker()
fake.name() # 'Margaret Boehm'
fake.email() # 'walker.travis@example.com'
fake.address() # '123 Main St, Apt 4B\nSpringfield, IL 62701'
fake.phone_number() # '+1-555-867-5309'
fake.date_of_birth(minimum_age=18, maximum_age=65)
fake.text(max_nb_chars=200)(Per faker-py (opens in new window).)
Common provider modules: person (name, prefix), address, internet (email, url, ipv4), phone_number, date_time, lorem (paragraphs, sentences, words), company, credit_card, job (faker-py (opens in new window)).
JavaScript
import { faker } from '@faker-js/faker';
faker.person.fullName(); // 'Margaret Boehm'
faker.internet.email(); // 'walker.travis@example.com'
faker.location.streetAddress(); // '123 Main St'
faker.phone.number(); // '+1-555-867-5309'
faker.date.past({ years: 30 });
faker.lorem.paragraphs(2);(Per faker-js (opens in new window).)
Module organization mirrors the Python ports but uses the module- namespace form: faker.person.*, faker.internet.*, faker.location.*, faker.date.*, faker.finance.*, faker.commerce.* (faker-js (opens in new window)).
Ruby
require 'faker'
Faker::Name.name # 'Margaret Boehm'
Faker::Internet.email # 'walker.travis@example.com'
Faker::Address.full_address
Faker::PhoneNumber.cell_phone
Faker::Date.birthday(min_age: 18, max_age: 65)
Faker::Lorem.paragraphs(number: 2)(Per faker-rb (opens in new window).)
Seeding for deterministic output
The most common test-stability mistake is letting Faker generate non-deterministic values across runs. Always seed in tests so a failure can be reproduced.
Python
from faker import Faker
# Class-level - sets the default RNG for all subsequent Faker() calls
Faker.seed(4321)
fake = Faker()
# Instance-level - useful when multiple Faker instances need different seeds
fake.seed_instance(4321)(Per faker-py (opens in new window).)
JavaScript
import { faker } from '@faker-js/faker';
faker.seed(123);
// All faker.* calls until the next seed() are deterministic.(Per faker-js (opens in new window).)
Ruby
require 'faker'
Faker::Config.random = Random.new(42)For test frameworks: place the seed in beforeEach / setup so each test starts with the same baseline; for paired runs, persist the seed used per failing test (similar to the flake-pattern-reference Pattern 8 randomness guidance).
Locale support
Python
fake = Faker('it_IT') # Italian
fake = Faker(['en_US', 'fr_FR', 'ja_JP']) # Multi-locale (random per call)
fake.name() # generates per the configured locale(s)(Per faker-py (opens in new window).)
JavaScript
import { fakerDE } from '@faker-js/faker';
import { fakerJA } from '@faker-js/faker';
fakerDE.person.fullName(); // German name
fakerJA.address.city(); // Japanese city(Per faker-js (opens in new window); 70+ locales available.)
Ruby
Faker::Config.locale = :ja
Faker::Name.name # Japanese name(Per faker-rb (opens in new window).)
Composing factories with referential integrity
Faker generates field values; for referential integrity (a factory that creates a User with a related Order), use a factory library that wraps Faker:
| Language | Factory library | Skill |
|---|---|---|
| Python | factory_boy | (consider mimesis - synthetic-data-toolkit - for locale-rich generation) |
| JS / TS | fishery / factory.ts | hand-rolled with Faker as engine |
| Ruby | FactoryBot | synthetic-data-toolkit references/factory-bot.md |
| .NET | Bogus | synthetic-data-toolkit references/bogus.md |
Faker alone won't enforce that order.user_id == user.id; the factory library handles that.
Anti-patterns
| Anti-pattern | Why it fails | Fix |
|---|---|---|
| Calling Faker without a seed in tests | A failure on CI doesn't reproduce locally; flake-investigation guesswork. | Seed once per test or per suite (Faker.seed(...)). |
Using fake.email() with a real domain (example.com is shared) | Spam concerns; some validators reject example.com. | Faker's defaults use safe RFC-2606 domains; never override to a real domain in tests. |
| Hardcoding generated values into snapshots | Snapshot bound to a Faker version's PRNG sequence; library bump breaks the snapshot. | Snapshot the shape of the data; assert types and patterns rather than literal values. |
| Generating names with the wrong locale | A test asserting "name has at least one space" fails on :ja (Japanese) where names use ・. | Match the locale to the assertion; or relax the assertion to be locale-aware. |
| Using Faker for security testing payloads | Faker generates "realistic" data, not malicious. SQL injection / XSS won't happen by chance. | Use malicious-payload-bank for adversarial input. |
Limitations
References
- Nightly run failed on a cart nobody can get back
- Nothing in the suite ever inserts a second account
- Inventory tests can't be run one at a time
- Half of contact.js has no tests because our fixtures can't reach it
- Nothing our factory generates gets past the contact API
- Every order in our fixtures belongs to a customer who doesn't exist
- Profile suite can't be pointed at the German or Japanese market
- Receipt test can only ever see one customer
- Seed 1337 gives everyone different data
- Staging seeding sent 214 welcome emails to real people