Laravel İle Test Verisi İçin Seed İşlemleri Nasıl Yapılır?

Laravel İle Test Verisi İçin Seed İşlemleri Nasıl Yapılır?
Laravel İle Test Verisi İçin Seed İşlemleri Nasıl Yapılır?

Ön Hazırlık ve Gereksinimler

Laravel ile çalışırken veritabanı işlemlerini sağlıklı bir şekilde gerçekleştirebilmek için sisteminizde PHP 8.2 veya üzeri bir sürümün yüklü olması önerilir. Ayrıca, Composer paket yöneticisinin güncel olduğundan emin olmalısınız. Projenizin kök dizininde bir .env dosyasının bulunduğunu ve veritabanı bağlantı ayarlarınızın (DB_CONNECTION, DB_DATABASE, DB_USERNAME, DB_PASSWORD) doğru yapılandırıldığını varsayıyoruz.

Eğer yerel bir geliştirme ortamı kullanıyorsanız, SQLite, MySQL veya PostgreSQL gibi bir veritabanı sürücüsünün aktif olduğundan emin olun. Veritabanı tablolarınızın halihazırda migration (göç) dosyaları ile oluşturulmuş olması, seed işlemlerinin sorunsuz çalışması için gereklidir.

Adım Adım Seeder Oluşturma

Laravel'de her bir tablo veya veri grubu için bir seeder sınıfı oluşturmak en iyi pratiklerden biridir. Seeder sınıfları, database/seeders dizini altında tutulur. Yeni bir seeder oluşturmak için Artisan komut satırı aracını kullanırız.

php artisan make:seeder UserSeeder

Bu komut, database/seeders/UserSeeder.php dosyasını oluşturacaktır. Bu dosya içerisinde run metodu bulunur ve veritabanı işlemlerinizi bu metodun içerisine yazarsınız. Örneğin, bir kullanıcı eklemek için Query Builder veya Eloquent ORM kullanabilirsiniz.

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;

class UserSeeder extends Seeder
{
    public function run(): void
    {
        DB::table('users')->insert([
            'name' => 'Ahmet Yılmaz',
            'email' => 'ahmet@example.com',
            'password' => Hash::make('gizliSifre123'),
        ]);
    }
}

Yukarıdaki örnekte Hash::make kullanarak şifrenin güvenli bir şekilde saklanmasını sağladık. Veritabanına doğrudan düz metin şifre kaydetmek güvenlik açığına yol açar, bu yüzden her zaman hashleme yöntemini kullanmalısınız.

Model Factory Kullanımı

Tek tek veri eklemek yerine, Laravel'in Model Factory (model fabrikası) yapısını kullanmak çok daha profesyonel ve ölçeklenebilir bir yöntemdir. Factory sınıfları, sahte veriler (fake data) oluşturarak veritabanınızı hızlıca doldurmanıza olanak tanır.

Öncelikle bir factory oluşturalım:

php artisan make:factory UserFactory --model=User

Ardından database/factories/UserFactory.php dosyasını düzenleyerek rastgele veriler tanımlayalım:

public function definition(): array
{
    return [
        'name' => fake()->name(),
        'email' => fake()->unique()->safeEmail(),
        'password' => Hash::make('password'),
    ];
}

Burada fake() yardımcı fonksiyonu, Faker kütüphanesini kullanarak gerçekçi isimler, e-postalar ve diğer verileri otomatik üretir.

Seeder Dosyalarını Çalıştırma

Oluşturduğunuz seeder sınıflarını çalıştırmak için db:seed komutunu kullanabilirsiniz. Eğer sadece belirli bir seeder'ı çalıştırmak isterseniz --class parametresini eklemeniz yeterlidir.

php artisan db:seed --class=UserSeeder

Tüm seeder sınıflarını DatabaseSeeder.php dosyası içerisinde çağırarak merkezi bir yönetim sağlayabilirsiniz. Bu dosya, tüm seed işlemlerinizin ana giriş noktasıdır.

public function run(): void
{
    $this->call([
        UserSeeder::class,
        ProductSeeder::class,
    ]);
}

Bu yapı sayesinde tek bir komutla (php artisan db:seed) tüm projenin başlangıç verilerini yükleyebilirsiniz.

Veritabanını Sıfırlayarak Tohumlama

Geliştirme aşamasında veritabanını temizleyip tekrar doldurmak sıkça ihtiyaç duyulan bir işlemdir. Bunun için migrate:fresh komutu ile birlikte --seed parametresini kullanabilirsiniz.

php artisan migrate:fresh --seed
Kritik Uyarı: migrate:fresh komutu veritabanındaki tüm tabloları siler ve yeniden oluşturur. Bu komutu asla canlı (production) ortamda çalıştırmayın, aksi takdirde tüm verileriniz kalıcı olarak silinecektir.

Seeder Yöntemlerinin Karşılaştırılması

Yöntem Avantajı Dezavantajı
DB::table Hızlı ve basit, küçük veriler için ideal. Karmaşık ilişkilerde yönetimi zordur.
Model Factory Esnek, ölçeklenebilir ve çoklu veri üretimi kolay. Küçük projelerde kurulumu vakit alabilir.

Sıkça Sorulan Sorular

Seeder dosyalarımda neden Faker kullanmalıyım?

Faker kütüphanesi, veritabanınızı doldururken gerçekçi ve çeşitli veriler (adresler, telefon numaraları, sahte metinler) oluşturmanızı sağlar. Bu, uygulamanızın arayüzünde verilerin nasıl görüneceğini test etmek için hayati önem taşır.

Canlı ortamda seeder çalıştırmak güvenli mi?

Canlı ortamda seeder çalıştırmak genellikle önerilmez. Ancak, sistemin çalışması için gerekli olan "sabit" verileri (örneğin: roller, izinler veya varsayılan kategoriler) eklemek için kullanılabilir. Bu durumda, veriyi eklemeden önce mevcut olup olmadığını kontrol eden mantıklar kurmalısınız.

Seeder'lar veritabanı ilişkilerini nasıl yönetir?

Laravel Factory'leri içerisinde ilişkili modelleri (örneğin bir kullanıcıya bağlı postlar) has veya for metodlarını kullanarak kolayca oluşturabilirsiniz.

Hata alırsam ne yapmalıyım?

Genellikle hata mesajları, veritabanı kısıtlamaları (foreign key constraint) ile ilgilidir. Verileri ekleme sırasına dikkat edin; önce ebeveyn tabloları (örneğin: categories), sonra çocuk tabloları (örneğin: products) doldurmalısınız.

Seeder'ları test ortamında nasıl kullanırım?

Laravel testleri içerisinde $this->seed() metodunu çağırarak, testin çalışacağı veritabanını belirli bir senaryo ile doldurabilirsiniz.

Güvenlik Sorumluluk Reddi: Bu rehberdeki kodlar eğitim amaçlıdır. Veritabanı işlemleri sırasında her zaman veri doğrulama (validation) ve yetkilendirme (authorization) kontrollerinizi yapmayı unutmayın. Canlı ortamda veri manipülasyonu yapmadan önce mutlaka yedek alınız.

İleri Seviye Seeder Stratejileri: Büyük Veri Setleri ve Performans Optimizasyonu

Uygulamanız büyüdükçe, binlerce veya milyonlarca satırlık test verisine ihtiyaç duyabilirsiniz. Standart create() metodu, her bir model için ayrı bir veritabanı sorgusu çalıştırdığından, büyük veri setlerinde ciddi performans kayıplarına yol açar. Bu noktada insert() metodunu veya chunk yapısını kullanmak kritik önem taşır.

Aşağıdaki örnekte, binlerce kullanıcıyı tek bir sorgu ile veritabanına nasıl ekleyebileceğinizi görebilirsiniz:

public function run()
{
    $users = [];

    for ($i = 0; $i < 10000; $i++) {
        $users[] = [
            'name' => fake()->name(),
            'email' => fake()->unique()->safeEmail(),
            'password' => bcrypt('password'),
            'created_at' => now(),
            'updated_at' => now(),
        ];
    }

    // 1000'erli gruplar halinde toplu ekleme
    foreach (array_chunk($users, 1000) as $chunk) {
        User::insert($chunk);
    }
}

Dikkat: insert() metodunu kullandığınızda, Laravel'in Model Events (created, saved vb.) tetikleyicileri çalışmaz. Eğer modelinizde boot metodu içerisinde tanımlanmış bir "slug" oluşturma veya "observer" mantığı varsa, bu veriler işlenmeyecektir.

Deployment Süreçlerinde Seeder Yönetimi

Canlıya çıkış (deployment) süreçlerinde, veritabanı şeması güncellenirken bazı "lookup" tablolarının (örneğin; şehirler, ülke kodları, ödeme yöntemleri) otomatik olarak doldurulması gerekebilir. Bu tür veriler için DatabaseSeeder dosyasını akıllıca yönetmelisiniz.

Sadece belirli durumlarda çalışacak seeder'lar tanımlamak için AppServiceProvider veya özel bir komut yapısı kullanmak en temiz yöntemdir:

// DatabaseSeeder.php içerisinde koşullu çalıştırma
public function run()
{
    $this->call([
        CountrySeeder::class,
    ]);

    if (app()->environment('local')) {
        $this->call([
            UserSeeder::class,
            PostSeeder::class,
        ]);
    }
}

Seeder Hata Ayıklama (Debugging) İpuçları

Karmaşık ilişkisel veriler oluştururken, genellikle "Foreign Key Constraint" hataları ile karşılaşırsınız. Bu hataları minimize etmek için şu adımları izleyin:

  • Sıralama: Veritabanı tablolarını, birbirlerine olan bağımlılıklarına göre (önce ana tablolar, sonra alt tablolar) call() metoduna ekleyin.
  • Truncate Kullanımı: Her test öncesi tabloları temizlerken DB::statement('SET FOREIGN_KEY_CHECKS=0;') komutu ile kısıtlamaları geçici olarak devre dışı bırakın.
  • Loglama: Seeder içerisinde $this->command->info('Kullanıcılar oluşturuluyor...') satırlarını kullanarak, işlemin hangi aşamada takıldığını terminal üzerinden takip edin.
public function run()
{
    DB::statement('SET FOREIGN_KEY_CHECKS=0;');
    
    User::truncate();
    
    $this->command->info('Tablolar temizlendi ve tohumlama başlatıldı.');
    
    User::factory(50)->create();
    
    DB::statement('SET FOREIGN_KEY_CHECKS=1;');
}

Sonuç

Laravel ile test verisi oluşturmak, geliştirme sürecini hızlandıran ve uygulamanın tutarlılığını artıran temel bir beceridir. Seeder ve Factory yapılarını doğru kullanarak, karmaşık veri setlerini saniyeler içinde oluşturabilir ve uygulamanızı her zaman güncel tutabilirsiniz. Bir sonraki adım olarak, veritabanı işlemlerinizi daha da ileriye taşımak için "Database Transactions" (Veritabanı İşlemleri) konusunu inceleyerek veri bütünlüğünü nasıl koruyacağınızı öğrenmenizi öneririm.

Bu yazıya tepkinizi paylaşın:
Zeynep Kaya

Adım adım rehber hazırlama ve kullanıcı deneyimi odaklı içerik mimarisi konusunda yetkinim. Okuyucuların sorunlarını hızlı çözen, net ve uygulanabilir metinler üretmeyi seviyorum.

Yorumlar (16)

16
okuyucu bu yazı hakkında yorum yaptı. Siz de deneyiminizi paylaşarak diğer okuyuculara yardımcı olabilirsiniz.
Serhat E.
Serhat E. 30 Temmuz 2026

Seed işlemleriyle ilgili Türkçe kaynak sayısı çok az, bu yazı ilaç gibi geldi valla.

Deniz Kara
Deniz Kara 01 Ağustos 2026

Yazı çok açıklayıcı olmuş, teşekkürler. Laravel 11 ile gelen değişikliklere de değinebilirdin belki.

Merve Demir
Merve Demir 02 Ağustos 2026

Harika bir yazı olmuş, projelerimde hep manuel ekleme yapıyodum, çok vaktimi alıyodu. Şimdi çok daha hızlı halledecem.

Oğuzhan Tekin
Oğuzhan Tekin 03 Ağustos 2026

Seeder'lar için 'DatabaseSeeder' dosyasını bölmek büyük projelerde daha mantıklı değil mi? Tek dosya çok şişiyor.

Zeynep Kaya
Zeynep Kaya 04 Ağustos 2026

Kesinlikle haklısın Oğuzhan, proje büyüdükçe 'call' metoduyla farklı seeder dosyalarına bölmek en temiz yöntem.

Zeynep Çelik
Zeynep Çelik 03 Ağustos 2026

Factory içerisinde fake()->unique() kullanırken bazen çakışma yaşıyorum, bunun bir çözümü var mı?

Hakan Bal
Hakan Bal 04 Ağustos 2026

Ben genelde faker yerine kendi array listemi kullanıyorum o durumlarda, daha garanti oluyo.

Burak Şen
Burak Şen 04 Ağustos 2026

Ya bende sürekli 'Class not found' hatası alıyom, composer dump-autoload yaptım ama düzelmedi. Neyi eksik yapıyorum acaba?

Selin Aras
Selin Aras 05 Ağustos 2026

Namespace kontrol ettin mi? Bazen sadece namespace yüzünden hata veriyor, bir bak istersen.

Kemal Arslan
Kemal Arslan 04 Ağustos 2026

Refresh yaparken foreign key hatası alıyorum, bunu nasıl düzgün çözerim?

Zeynep Kaya
Zeynep Kaya 06 Ağustos 2026

Migration dosyalarında 'onDelete('cascade')' kullanırsan veya truncate işleminden önce foreign key kontrollerini kapatırsan sorun çözülür.

Caner Yıldız
Caner Yıldız 05 Ağustos 2026

Eline sağlık Zeynep, çok temiz bir anlatım olmuş. Factory kullanırken Faker kütüphanesini özelleştirme konusunda da bir yazı bekliyoruz.

Zeynep Kaya
Zeynep Kaya 06 Ağustos 2026

Çok teşekkürler Caner! Faker özelleştirmeleri gerçekten önemli bir konu, not aldım mutlaka bir yazı hazırlarım.

Fatih Yılmaz
Fatih Yılmaz 05 Ağustos 2026

Hocam herseyi dogru yaptim ama seed basinca veritabanina yazmiyo. Seeder sınıfını call yapmayı mı unuttum acaba?

Zeynep Kaya
Zeynep Kaya 06 Ağustos 2026

DatabaseSeeder dosyasında çağırdığından emin olmalısın, kontrol eder misin?

Elifnur G.
Elifnur G. 06 Ağustos 2026

Çok pratik bir anlatım, hemen uyguladım çalıştı. Elinize sağlık.

Yorum Yaz