Test verisi: çoğu ekibin en zayıf halkası
Bir yazılım ekibinin olgunluğunu ölçmek için hızlı bir soru: "Staging DB'deki veri ne?" Cevap "production snapshot'ı" ise, ekibin KVKK ve güvenlik tarafında ciddi bir açığı vardır. Cevap "boş bir DB, herkes kendi fixture'ını yazıyor" ise, ekip entegrasyon hatalarını production'da bulacak demektir. Doğru cevap ortadadır: yapay ama gerçekçi, tekrar üretilebilir ve yönetilen bir test verisi stratejisi.
Bu yazı, Türkiye pazarında çalışan ekiplerin özellikle TC kimlik numarası (TCKN) ve Vergi Kimlik Numarası (VKN — günlük dilde "vergi no") içeren veri setlerini nasıl yönetmesi gerektiğini ele alıyor; ama prensipler her tür PII için geçerli. Amaç somut: hangi araçları, hangi kalıpları, hangi sayısal sınırları kullanıyoruz. tc üret / vergi no üret akışlarınızı CI'a bağlamayı planlıyorsanız buradaki kalıplar başlangıç noktası olur.
Production verisini kopyalamak neden kötü
Ekiplerde en yaygın patern: "production DB'yi nightly dump edip dev'e restore ediyoruz". Neden kötü olduğunu yaşayarak öğrenmeden önce listeleyelim:
- KVKK: test ortamının güvenlik seviyesi production ile aynı değildir. Üç kişinin daha erişimi olan bir DB'de gerçek TC kimlik numarası tutmak, denetimde bulgu demektir.
- Kaza senaryoları: dev'de yanlışlıkla "tüm kullanıcılara mail at" scripti çalışırsa, 1 milyon gerçek kullanıcıya mail gider. Yaşanmış vakalar var.
- Boyut: production 500 GB ise dev'de hem yavaş hem pahalı. Developer'ın laptop'unda çalışmaz.
- Temsiliyet eksikliği: production bir zamana sabit. Yeni feature'lar için test verisi üretmesi zor.
Hafif anonymization ("ad soyadı rastgele değiştirdik") bu problemlerin hepsini çözmez. Gerçek güvenlik için ya sentetik veri ya da güçlü anonimleştirme + veri küçültme lazım.
Sentetik veri: nedir, ne değildir
Sentetik veri, istatistiksel olarak gerçek veriye benzeyen ama hiçbir gerçek kişiye ait olmayan veri setidir. TC kimlik tarafında bu şunu demek:
- Algoritma uyumlu ama gerçek kimseye ait olmayan TC kimlik numarası üretmek (Ayrıca API testlerinde vkn doğrulama algoritması kullanarak geçerli VKN üretmek de mümkündür). (tcknvkn.com'un TC Üretici aracının yaptığı iş)
- Gerçekçi ad/soyad havuzu ile rastgele eşleme
- Gerçekçi doğum tarihi dağılımı (18-85 yaş arası Gaussian gibi)
- Gerçekçi adres/posta kodu (Türkiye'deki gerçek il-ilçe haritası, ama sokak adları rastgele)
Sentetik veri gerçek veri yerine geçebilir mi? Pek çok senaryoda evet. Ama şunları test etmek zorlaşır:
- Belirli bir müşteri segmentine özgü edge case'ler ("5 çocuklu 65 yaşındaki emekli mimar" gibi)
- Uzun bir tarih kuyruğu ("15 yıldır aktif kullanıcı")
Bu durumlarda sentetik veriyi production'dan türetilmiş profil-dağılımları ile karıştırmak gerekir. "Differential privacy" ve "k-anonymity" gibi matematiksel garantiler burada devreye girer.
Seed strategy: deterministik ama yenilenebilir
Test verisi üretimini deterministik yapın. Yani aynı seed ile çalıştırıldığında aynı çıktıyı üretmeli. Pek çok ekibin kaçırdığı nokta bu — her CI build'ında rastgele veri üretildiğinde "flaky test" sorunları çıkar.
Python örneği:
import random
from datetime import date, timedelta
def seeded_rng(seed: str) -> random.Random:
return random.Random(seed)
def generate_user(rng: random.Random, tckn_pool: list[str]) -> dict:
return {
"tckn": rng.choice(tckn_pool),
"ad": rng.choice(AD_HAVUZU),
"soyad": rng.choice(SOYAD_HAVUZU),
"dogum": date(1960, 1, 1) + timedelta(days=rng.randint(0, 22_000)),
}
rng = seeded_rng("ci-build-2026-04-22")
users = [generate_user(rng, TCKN_POOL) for _ in range(1_000)]Seed'i CI build ID'si ya da feature branch adı gibi bir şeye bağlayarak farklı senaryolar için farklı dataset'ler elde edebilirsiniz. Production-like senaryo için sabit seed, smoke test için kısa seed.
TC kimlik havuzunu üretirken algoritma bilgisi için TC algoritması yazısına bakabilirsiniz.
Dataset boyutu: Goldilocks problemi
"Kaç kayıt lazım?" sorusuna genel cevap yok, ama kalıplar var:
- Unit test: 5-20 kayıt. Her test kendi setini üretir.
- Integration test: 100-500 kayıt. Edge case'leri kapsayacak kadar çeşitlilik.
- Load test: 100K-10M kayıt. Production'ın %10-100'ü.
- Chaos test: production kadar veya fazlası.
10 milyon kayıtlı bir Postgres DB ile çalışıyorsanız, "test verisi" artık tek bir dosya değil, bir DB mühendislik problemi. Partitioning, bulk COPY, ANALYZE sıraları önem kazanır. Bu ölçekteki üretim için toplu üretim aracımızı kullanabilir veya kendi pipeline'ınızı Kütüphaneler sayfasında listelenen paketlerle kurabilirsiniz.
Anonimleştirme teknikleri: gerçek fark neresi
Production'dan test'e veri taşıyacaksanız anonimleştirme katmanlı olmalı:
1. Suppression (gizleme)
Alanı komple drop etmek. Kredi kartı CVV'si veya password hash bu kategoride. Bu alanlar test'te hiç olmamalı.
2. Masking
Alanın kısmen görünür kalması. +90 555 *** 45 67 gibi. Görsel demo için kullanılır, statistical property korumaz.
3. Generalization
Doğum tarihini aya veya yıla yuvarlama (2023-05-17 → 2023-05-01). Analiz için yeterli, birey için kimlik bilgisi zayıflar. Detay seviyesi "k-anonymity" metriği ile ölçülür: her kayıt en az k-1 başka kayıtla aynı grubu paylaşmalı.
4. Pseudonymization
Kimliği rastgele ama deterministik bir token ile değiştirmek. TCKN → hash(tckn + salt). Aynı kişi tüm tablolarda aynı token'ı alır. Salt gizli tutulursa geri çevrilemez (pratikte).
5. Synthesis
Orijinal veriyi hiç kullanmamak, sadece profilini/dağılımını tutmak. En güvenli ama en karmaşık yaklaşım.
Bir ekip için "karma" strateji genelde doğru: özellikle hassas alanlar (TCKN, IBAN, kart numarası) synthesis ile, diğer alanlar generalization + pseudonymization ile. Gerçek bir uygulama KVKK denetiminde bu katmanları belgelenmiş bulmayı bekler; bu konuda KVKK rehberimiz daha geniş bir yol haritası sunuyor.
CI/CD entegrasyonu
Test verisi üretimini CI pipeline'ının parçası yapın. Örnek bir GitHub Actions job:
name: Integration tests
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: test
ports: [5432:5432]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: '3.11' }
- name: Seed DB
run: python scripts/seed_test_data.py --count 10000 --seed ${{ github.run_id }}
env:
DATABASE_URL: postgres://postgres:test@localhost/test
- run: pytest tests/integrationDikkat: seed script'i her çalıştığında aynı DB state'ini üretmeli. Bu sayede başarısız test'leri aynı state ile tekrar çalıştırıp debug edebilirsiniz. Random seed yerine run_id + fixed salt kullanmak iyi bir orta yoldur.
Fixture mi, factory mi, snapshot mı?
Üç yaygın paradigma var:
- Fixture (sabit dosyalar): JSON/YAML dosyaları ile bir dizi test kaydı. Basit, versiyon kontrolü kolay. Dezavantaj: büyük setler okunmaz, çeşitlilik sağlamak zor.
- Factory (kodla üretim):
factory_boy(Python),factory-girl(Node),FactoryBot(Ruby). Her test çalıştırmasında üretir. Esnektir, ama testler "sihirli" olabilir. - Snapshot: production-like veriden alınan anonimleştirilmiş kopya. Realistik ama ağır.
Çoğu ekip ikisini karıştırır: critical path için factory (hızlı ve esnek), regression için snapshot (gerçekçi). Fixture'ları sadece static lookup tabloları için kullanın.
TC (TCKN) ve VKN fixture havuzu nasıl kurulur
Unit test'te her testin kendi TC kimlik numarasını üretmesi israftır. Bunun yerine bir kez 10.000-100.000 kayıtlık bir havuz üretip dosyaya yazın:
# scripts/build_tckn_pool.py
from pathlib import Path
import json
def generate_valid_tckn(rng):
import random
r = random
while True:
d = [r.randint(1, 9)] + [r.randint(0, 9) for _ in range(8)]
s_odd = d[0] + d[2] + d[4] + d[6] + d[8]
s_even = d[1] + d[3] + d[5] + d[7]
d10 = (s_odd * 7 - s_even) % 10
d11 = (s_odd + s_even + d10) % 10
d += [d10, d11]
return "".join(str(x) for x in d)
import random
rng = random.Random("fixture-seed-v1")
pool = [generate_valid_tckn(rng) for _ in range(50_000)]
Path("tests/fixtures/tckn_pool.json").write_text(json.dumps(pool))Havuzu bir kez oluşturup repo'ya commit edin. Her test çalıştığında üretmeyin — hem yavaş hem sabitlik eksik. Havuz değiştiğinde versiyonlayın: tckn_pool_v2.json.
Aynı havuzu VKN için de yapın. Havuz boyutunu DB unique constraint'lerinize göre boyutlandırın: testte 10.000 kayıt yazıyorsanız en az 20.000'lik havuz tutun.
VKN (Vergi No) ve sektörel test setleri
B2B ürünü geliştiriyorsanız VKN havuzunuz sadece algoritma uyumlu olmakla kalmamalı, aynı zamanda iş senaryolarını kapsamalı:
- e-Fatura mükellefi olmak için tasarlanmış vergi numaraları
- KDV'den muaf şirketler
- Serbest meslek mensupları (aslında TCKN)
- Yurtdışı şirketler (farklı format — VKN yerine 10 haneli yerel ID)
Bu sektörel çeşitliliği factory'nize bir "persona" katmanı olarak ekleyin. VKN algoritmasının detayları için VKN yapısı yazımıza bakın.
Veri yaşam döngüsü: GC stratejisi
Test verisi de production verisi gibi bir yaşam döngüsüne sahip olmalı:
- Create: seed script ile üretim
- Use: test koşumu boyunca
- Retain: başarısız test için kısa süre (debug amaçlı)
- Delete: TTL ile otomatik silme
Özellikle staging/QA ortamlarında DB'yi haftada bir "reset" etmek iyi bir pratiktir. Uzun süredir var olan verinin ne olduğunu kimse hatırlamıyor.
CI ortamında ise her build kendi fresh DB'si ile çalışmalı. Docker Compose + tmpfs ya da ephemeral Postgres (pg_tmp) bu iş için birebir.
Ölçülebilir kalite kriterleri
Test verisi stratejinizin olgunluğunu ölçmek için şu kriterleri kullanın:
- Coverage: test dataset'iniz production'ın kaç %'sini temsil ediyor?
- Reproducibility: aynı seed → aynı dataset?
- Freshness: dataset ne sıklıkla güncelleniyor?
- PII leakage: rastgele 100 kayıt inceleyin, gerçek kişiye ait olabilecek şey var mı?
- Generation time: 1M kayıt üretmek ne kadar sürüyor?
Bu metrikleri quarterly review yapın. Testlerin "yeşil" olmasından çok bu metriklerin sağlıklı olması uzun vadede ekibi kurtarır.
Sonuç
Test verisi, çoğu ekibin düzenli bakım yapmadığı ama aslında production kalitesinin en büyük belirleyicilerinden biri olan bir katmandır. Sentetik üretim + deterministik seed + yönetilen yaşam döngüsü üçlüsü ile hem KVKK uyumu hem test güvenilirliği aynı anda sağlanır.
- TC algoritmasının kendisi: TC algoritması
- VKN algoritması: VKN yapısı ve doğrulama
- KVKK tarafı: KVKK uyumlu kimlik doğrulama
- Büyük ölçek: Toplu TCKN/VKN doğrulama rehberi
Hızla havuz oluşturmak için TC Üretici, Toplu Üretim ve uygun kütüphaneler için Kütüphaneler sayfasını kullanın.