Navigated to blog β€Ί test-data-generation-replace-pii-csv
Back to Blog
csv-guides

Test Data Generation: Replace Real Customer Data With Safe Synthetic Data

March 18, 2026
12
By SplitForge Team

Quick Answer

Using real customer CSV data in development, testing, or staging environments is a GDPR processing activity β€” and in most cases, it's an unjustifiable one. The lawful basis that covers production use of customer data rarely extends to use in test environments. GDPR Article 5(1)(b) purpose limitation requires that data used for testing be compatible with the original collection purpose β€” and "to test our reporting pipeline" rarely is. The solution is synthetic data: generated records that preserve the statistical properties of real data without containing real individuals' information.


Fast Fix (5 Minutes)

If you're about to copy a production CSV into a test environment right now:

  1. Stop. Ask: is there a documented lawful basis for using this data in testing? Purpose limitation (Art 5(1)(b)) is the most common blocker.
  2. Do you actually need real data, or do you need realistic data? Most testing requires data that looks real β€” correct formats, representative distributions β€” not actual customer records.
  3. Can you mask before copying? Pseudonymize identifiers (replace names with Faker-generated names, emails with [email protected] variants, phone numbers with E.164 format dummies) using SplitForge Data Masking locally before the file leaves production.
  4. For structural testing only: Generate entirely synthetic data that matches your schema β€” no real individuals, no GDPR obligations.
  5. Document the approach β€” which fields were masked, which were synthesized, what method was used. This is your Article 25 privacy-by-design record for the test environment.

TL;DR: Real customer data in test environments is the number one source of data breaches that aren't from production systems. Developers have local access. Staging environments have weaker security controls. Backup exports get forgotten. The fix isn't stricter access controls on real data in test environments β€” it's not using real data in test environments. Synthetic data that preserves your schema structure and statistical distributions gives you everything you need for testing and nothing that creates regulatory or breach risk.


The 2024 Acer data breach exposed 2,869 records of customer data β€” from a staging server. The 2023 Toyota breach exposed 2.15 million customer records β€” from a server with test data that had been accessible for a decade. The pattern repeats across incidents: production data copies in lower-security environments, forgotten or misconfigured, become the breach vector.

GDPR regulators have specifically addressed this. The German DPA (DSK) guidance makes clear that using personal data in test environments requires the same legal basis as production processing β€” and purpose limitation means that basis is rarely available. The practical answer regulators point to: use de-identified or synthetic data for testing and development.

Each technique in this post was assessed against GDPR Articles 5(1)(b) and 25, and standard data engineering practice for test environment design, March 2026.


Table of Contents


Why Real Data in Test Environments Is a GDPR Problem

Purpose limitation (Article 5(1)(b)): Personal data must be collected for specified, explicit, and legitimate purposes β€” and must not be processed in a manner incompatible with those purposes. Your customers provided their data for customer service, product fulfillment, or marketing communications. They did not provide it for load testing your ETL pipeline. Using their data for this incompatible purpose requires a new lawful basis.

Data minimization (Article 5(1)(c)): Only data adequate, relevant, and limited to what is necessary for the purpose. Testing a data pipeline doesn't require real customer names, real email addresses, or real purchase histories. A synthetic dataset with the correct schema and realistic distributions is sufficient β€” and necessary.

Privacy by design (Article 25): Test environments are lower-security by design β€” development access is broader, security controls are lighter, backup processes are less rigorous. Placing personal data in a lower-security environment is a design decision that violates Article 25 unless specific compensating controls are in place.

❌ COMMON PRACTICE β€” GDPR violation:
Production CRM export: 500,000 customer records
β†’ Copied to staging environment for pipeline testing
β†’ Copied again to developer's local machine for debugging
β†’ Backed up with the staging environment
β†’ Retained indefinitely as "the test dataset"

5 copies of 500,000 real customer records in non-production environments.
Zero additional consent or basis. Zero additional security controls.
Purpose limitation: violated.
Data minimization: violated.
Article 25 privacy by design: violated.

COMPLIANT ALTERNATIVE:
β†’ Synthetic dataset generated with same schema and distributions
β†’ No real individuals. No GDPR obligations.
β†’ Developers have full access. No breach risk.
β†’ Can be committed to source control. No security concern.

HIPAA test environment risks:

For healthcare data, HIPAA Safe Harbor de-identification requirements apply before PHI can be used in test or development environments. Even removing names and dates of birth doesn't fully de-identify PHI β€” 18 specific identifiers must be removed. Using PHI in test environments without Safe Harbor de-identification or a signed BAA covering the test environment creates HIPAA exposure.


Three Approaches: Masking, Pseudonymization, and Synthetic Generation

Approach 1: Masking (replacing values with fixed substitutes)

Replace sensitive field values with static masks. Names β†’ XXXX. Emails β†’ [email protected]. Phone numbers β†’ +10000000000.

  • Pros: Fast. No schema changes. Easy to implement.
  • Cons: Destroys statistical properties. All emails are identical β€” won't catch uniqueness constraint failures. All names are XXXX β€” won't catch name validation logic. Provides weak test coverage.
  • GDPR status: Pseudonymized data (if original values recoverable) or anonymized data (if not). GDPR may still apply if re-identification is possible.

Approach 2: Pseudonymization (replacing values with consistent substitutes)

Replace real values with fake but consistent equivalents. [email protected] β†’ [email protected] β€” consistently, so the same real email always maps to the same fake email. This preserves referential integrity across tables.

  • Pros: Preserves referential integrity. Better test coverage than static masking. Consistent mapping enables cross-table testing.
  • Cons: GDPR still applies (pseudonymized = still personal data if mapping exists). Requires maintaining a mapping table, which must be secured.
  • GDPR status: Still personal data under GDPR Article 4(5). Does not eliminate GDPR obligations.

Approach 3: Synthetic generation (creating entirely fake records)

Generate entirely new records that match the schema and statistical distributions of real data, but contain no information about any real individual.

  • Pros: No real individuals = no GDPR obligations for the generated data. Can be committed to source control, shared freely, used in public bug reports. Eliminates test environment breach risk entirely.
  • Cons: Requires more upfront work. Must accurately represent real data distributions to catch realistic bugs. Edge cases must be explicitly included.
  • GDPR status: Genuinely anonymous data falls outside GDPR scope (Recital 26). No processing obligations.

The right approach by use case:

Use CaseBest Approach
Integration testing with real schemaSynthetic generation
Performance testing at production scaleSynthetic generation (millions of records)
Bug reproduction with specific edge casePseudonymized copy of the specific failing record
Schema validation / import format testingSynthetic generation
ML model trainingSynthetic or genuinely de-identified
Sharing with external QA team or vendorSynthetic generation only
Committing to source control as fixturesSynthetic generation only

What Good Synthetic Test Data Looks Like

Good synthetic test data satisfies three requirements:

1. Schema fidelity: Every field has the correct data type, format, and constraints. If production email fields must be unique and match RFC 5322 format, the synthetic version must too.

2. Statistical realism: Distributions match production. If 60% of real customers are in California, the synthetic dataset should reflect a similar distribution. If purchase amounts follow a specific distribution, the synthetic version should approximate it. Tests that pass on synthetic data should predict how the pipeline will behave on production data.

3. Edge case coverage: Real data has edge cases β€” unusually long names, special characters in addresses, null values in optional fields, duplicate entries in poorly validated inputs. Synthetic data must include these explicitly, because random generation won't produce them reliably.

❌ POOR SYNTHETIC DATA (too clean):
first_name,last_name,email,phone,postcode,purchase_amount
John,Smith,[email protected],+15551234567,SW1A 1AA,100.00
Jane,Doe,[email protected],+15559876543,EC1A 1BB,250.00

Problems:
- All names follow First Last format β€” won't catch "O'Brien" or "van der Berg"
- All emails are [email protected] β€” no dots, plusses, or hyphens
- All postcodes valid β€” no testing of postcode validation logic
- All amounts are round numbers β€” no cents, no edge case values

GOOD SYNTHETIC DATA (realistic):
first_name,last_name,email,phone,postcode,purchase_amount
O'Brien,SiobhΓ‘n,[email protected],+442071234567,EC1A 1BB,127.43
van der Berg,Pieter,[email protected],+31612345678,1011 AB,0.99
Smith-Jones,Maria,[email protected],,SW1W 0NY,9999.00
Test,User,[email protected],+15550000000,00000,0.01

This version:
- Includes special characters in names
- Includes email variants (plus addressing, hyphens, country TLDs)
- Includes null phone (optional field β€” tests NULL handling)
- Includes edge case amounts (near-zero, near-maximum)
- Includes test postcode that may fail validation β€” intentionally

Generating Synthetic Data: Field-by-Field Guide

Names: Use a name library (Faker in Python, Bogus in .NET, Chance.js in JavaScript) with locale support. Include international names proportional to your real user base. Explicitly add edge cases: apostrophes (O'Brien), hyphens (Smith-Jones), accented characters (AndrΓ©), prefixes and suffixes (Dr., Jr.).

Email addresses: Format: {word}{optional_separator}{word}{optional_number}@{domain}.{tld} Vary separators (dot, plus, hyphen, nothing). Include non-.com TLDs proportional to your user geography (.co.uk, .de, .fr, etc.). Ensure uniqueness if the field has a unique constraint in production.

Phone numbers: Always generate in E.164 format (+{country_code}{number}). Vary country codes proportional to user geography. Include explicitly invalid formats as edge cases (for testing validation rejection).

Dates: Match your production distribution. If most users signed up in 2022–2024, weight the date range accordingly. Include edge cases: leap day dates, year boundaries, minimum and maximum values for date fields.

Amounts / numeric fields: Match the statistical distribution (uniform, normal, log-normal depending on what production looks like). Always include: zero, negative values (if production ever has them), very small values, very large values near field limits.

Identifiers (customer IDs, order numbers): Maintain format exactly. If production IDs are UUID4, generate UUID4s. If they're sequential integers with a prefix (ORD-000001), replicate that pattern. Referential integrity requires that IDs used as foreign keys in one table appear as primary keys in another β€” maintain this in synthetic generation.


When You Actually Need Real Data Structure

There are legitimate cases where synthetic data is insufficient and a subset of real data is genuinely required:

Machine learning model evaluation: Evaluating model performance requires real production-like data, including the distributional quirks of real user behavior. In these cases, apply Safe Harbor de-identification (for PHI) or pseudonymization with appropriate GDPR basis.

Reproducing a specific production bug: If a bug is triggered by a specific data pattern in a real record, you may need to work with that record. In this case, extract only the minimum necessary record(s), pseudonymize all identifiers, and delete after the bug is reproduced.

Performance benchmarking at exact production scale: If you need exactly 10 million rows at production field-length distribution for a performance test, synthetic generation may not match exactly. Pseudonymize a production subset (replacing all identifiers consistently) and document the legal basis and technical controls.

In all these cases: apply pseudonymization locally before any copy leaves the production environment. SplitForge masks field values in browser Web Worker threads before any transmission β€” the pseudonymized file is what gets copied, not the original.

For the anonymization techniques that can take pseudonymized test data toward genuinely anonymous (GDPR-exempt) status, see our GDPR anonymization guide.


Preserving Statistical Properties in Synthetic Data

The most common criticism of synthetic data for testing: "It doesn't reflect real-world edge cases, so tests that pass on synthetic data fail in production."

This is a legitimate concern β€” but it's a symptom of poorly generated synthetic data, not an inherent limitation of the approach.

Statistical Properties Preservation Table β€” use this when justifying synthetic generation to your compliance or engineering team:

PropertyReal Data ExampleSynthetic TargetWhy It Matters for Testing
Cardinalitycity has 842 distinct valuesGenerate 800–900 distinct citiesLow cardinality hides JOIN failures and index performance issues
NULL rate12% of phone fields are NULLGenerate 12% NULL phonesNULL handling bugs only surface when NULLs appear at realistic rates
Value distribution60% of country = "US"Reflect US-heavy distributionDistribution-dependent logic (tax rules, shipping zones) fails under uniform distributions
String lengthnotes avg 47 chars, SD 23Generate text in that rangeFixed-length synthetic notes miss truncation bugs in VARCHAR fields
Relationship cardinalityCustomers average 3.2 ordersMaintain avg 3–4 orders per customerReferential integrity bugs appear only at realistic parent-child ratios
Edge casesApostrophes in names, null postcodes, Β£0.01 amountsExplicitly include eachRandom generation won't produce these β€” they must be engineered in
Date distribution70% of signups in 2022–2024Weight date range accordinglyDate-range queries fail when all test dates are in one month

Screenshot this table. When a developer argues "why not just use prod data", this is your answer: synthetic data can be made statistically equivalent for test coverage, without the regulatory and breach risk.

Statistical properties to preserve:

  • Cardinality: If the city field has 842 distinct values in production, the synthetic version should have a similar range β€” not 5.
  • NULL rate: If 12% of phone fields are NULL in production, generate 12% NULL in the synthetic set.
  • Value distribution: If 60% of country values are "US", reflect this in the synthetic set.
  • String length distribution: If notes fields average 47 characters with a standard deviation of 23, generate text with this distribution β€” not uniform length.
  • Relationship cardinality: If customers have an average of 3.2 orders each, maintain this in the generated dataset.
  • Known edge cases: Document every edge case you've seen in production and explicitly include it in synthetic generation. This doesn't happen automatically β€” it requires intentional engineering.

The result: a synthetic dataset that causes the same types of failures as production data, without containing any real individuals' information.


Operator Rules: Test Data Generation

Short. Non-negotiable. Reference before any production CSV copy operation.

  • Never copy real customer data to a test environment without a documented legal basis and pseudonymization
  • Synthetic data that passes tests is better than real data that creates breach risk
  • Pseudonymized data is still personal data β€” GDPR still applies
  • Genuinely anonymous synthetic data falls outside GDPR β€” build that way from the start
  • Edge cases must be explicitly included β€” random generation won't produce them
  • Mask locally before copying β€” the test environment should never see the original
  • Document the generation approach β€” which fields, which method, what review was done

Additional Resources

GDPR Primary Sources:

HIPAA:

Technical Resources:

Disclaimer: This post is for informational purposes only and does not constitute legal advice. Test data obligations depend on your specific data types, processing activities, and jurisdiction. Consult qualified legal counsel before making compliance decisions.


FAQ

The risk isn't that you've been doing it β€” it's what happens when it fails. The Acer and Toyota breaches both involved test or staging environments with production data copies. A test environment breach typically triggers the same GDPR breach notification requirements (within 72 hours to the supervisory authority, directly to affected individuals if high risk) as a production breach. "No issues so far" is not a risk management strategy.

A subset of real production data is still real production data. The same GDPR obligations apply to 1,000 records as to 1,000,000. Pseudonymize the subset first β€” replace all identifiers with consistent fake values β€” and you have a dataset that preserves referential integrity and realistic distributions without containing real individuals' information.

Genuinely anonymous synthetic data (meeting GDPR Recital 26 standards β€” no real individuals, not reasonably re-identifiable) can be shared externally without GDPR processing obligations. It can be committed to source control, shared in bug reports, and used in public documentation. This is one of the most practical benefits of synthetic generation over pseudonymization β€” the data can be shared without compliance overhead.

If you're analyzing real production data to derive statistical properties (distributions, cardinalities, NULL rates) and using those statistics to generate synthetic records β€” the analysis phase is a processing activity and GDPR applies to it. The output (the synthetic dataset) is not personal data if no real individual's information is traceable in the output. The distinction: analyzing real data to understand it is regulated; the synthetic output is not.

Referential integrity requires that IDs used as foreign keys in one table appear as primary keys in another. In synthetic generation: generate primary keys for parent entities (customers, orders) first, then generate child entity records referencing those keys. Maintain a consistent synthetic ID mapping table during generation β€” this is internal to the generation process and doesn't contain personal data.


Test Without Risk. Generate Without Exposing.

Mask real customer identifiers locally before any copy operation reaches a test environment
Apply pseudonymization in your browser β€” the masked file is what enters staging, not the original
Combine with synthetic generation for complete coverage β€” realistic data, zero PII
Share synthetic datasets freely with QA teams and vendors without GDPR obligations

Continue Reading

More guides to help you work smarter with your data

csv-import-guides

CSV Delimiter Errors: Fix Comma vs Semicolon for International Teams

Stop all data in Column A errors. Learn comma, semicolon & tab CSV delimiters plus quick fixes for global teams.

Read More
csv-guides

How to Split Large CSV Files Without Excel (Even 1M+ Rows)

Need to split a massive CSV file but Excel keeps crashing? Learn how to split files with millions of rows safely in your browser without uploads.

Read More
excel-guides

Batch Convert Multiple Excel Files to CSV Without Opening Each One

Opening 50 Excel files one at a time to save as CSV takes 45 minutes and produces inconsistent results. Three methods handle the same task in under 60 seconds β€” none require opening a single file.

Read More

We use analytics cookies to improve SplitForge. Your files never leave your browser β€” ever. Privacy policy