Laravel Migrations Seeders Factories Testing Dasar
Selesai membaca dokumentasi ini?
Kembali ke rujukan utama Laravel untuk melanjutkan topik lainnya.
Kembali ke rujukan utama Laravel untuk melanjutkan topik lainnya.
Di Laravel, migrations dipakai untuk mengelola struktur database secara terversioning. Seeders dipakai untuk mengisi data awal atau data referensi. Factories dipakai untuk menghasilkan data palsu yang realistis dan konsisten untuk development atau testing. Testing dasar dipakai untuk memverifikasi bahwa schema, data bootstrap, dan perilaku aplikasi tetap berjalan setelah perubahan.
Kalau empat alat ini dipakai bareng, hasilnya adalah database yang lebih mudah direproduksi, lebih aman diubah, dan lebih kecil kemungkinan rusak diam-diam saat proyek tumbuh.
Pakai migrations ketika kamu mengubah struktur database:
Migrations adalah catatan perubahan schema, bukan tempat menyimpan data aplikasi. Fokusnya adalah bentuk database, bukan isi tabel.
Pakai seeders ketika kamu perlu data awal yang selalu tersedia:
Seeders cocok untuk data yang memang ingin ada sejak awal dan bisa diulang dengan hasil yang dapat diprediksi.
Pakai factories ketika kamu perlu data sintetis dalam jumlah banyak:
Factories sangat berguna saat kamu tidak mau menulis data satu per satu. Mereka menghasilkan data cepat, konsisten, dan cukup realistis untuk kebutuhan aplikasi.
Pakai testing ketika kamu ingin memastikan perubahan tidak merusak perilaku yang sudah ada:
Untuk Laravel, testing paling sering dipakai di level feature dan unit. Untuk topik ini, fokus utamanya adalah memastikan bootstrap database dan alur data dasar tetap sehat.
Alur yang sehat biasanya begini:
Urutan ini penting karena setiap alat punya tugas yang berbeda. Kalau urutannya dicampur, hasilnya biasanya sulit direproduksi: schema berubah, data referensi hilang, atau test menjadi bergantung pada keadaan database sebelumnya.
Migration adalah cara Laravel mencatat perubahan schema database sebagai file PHP yang bisa dijalankan berulang di environment mana pun.
Prinsip utamanya:
Contoh migration:
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->string('title'
Hal yang penting dari migration bukan cuma syntax-nya, tetapi niatnya:
Schema::create() untuk membuat tabel baruSchema::table() untuk mengubah tabel yang sudah adaGunakan migration saat perubahan database harus ikut versi code. Contoh:
published_atemailMigration yang baik menjelaskan schema, bukan menebak keadaan runtime.
Seeder dipakai untuk mengisi database dengan data awal atau data referensi.
Contoh umum:
Contoh seeder:
class DatabaseSeeder extends Seeder
{
public function run(): void
{
User::factory()->create([
'name' => 'Admin',
'email' => 'admin@example.com',
]);
Seeder sering menjadi pintu masuk orkestrasi seeding. Di dalamnya, kamu bisa memanggil seeder lain agar struktur data lebih modular.
Seeder cocok saat data itu:
Kalau seeder tidak idempotent, developer bisa sulit menjalankan ulang setup tanpa membersihkan database dulu.
Factory menghasilkan instance model dengan data palsu yang valid. Di Laravel, factory biasanya memakai Faker untuk membuat data yang terlihat realistis.
Contoh:
User::factory()->count(10)->create();Atau dengan relasi:
Post::factory()
->for(User::factory())
->count(5)
->create();Factory cocok saat kamu perlu:
Factory membantu menjaga test dan development tetap ringan. Tanpa factory, developer sering tergoda membuat data manual di database lokal, lalu test menjadi rapuh karena bergantung pada data yang tidak terkontrol.
published, draft, atau inactiveData palsu yang “terlalu liar” bisa menyulitkan debugging. Yang dibutuhkan bukan sekadar random, tetapi random yang masih masuk akal.
Testing di sini bukan cuma mengecek satu fungsi. Tujuannya adalah memastikan alur database dan data yang dipakai aplikasi masih benar setelah perubahan.
Yang biasanya dites:
Pakai feature test untuk memverifikasi alur dari request sampai data tersimpan.
Contoh:
Pakai unit test untuk logika kecil yang bisa diuji tanpa banyak dependensi, misalnya helper, service kecil, atau transformasi data.
Pada Laravel, test biasanya dijalankan pada database terisolasi, lalu schema disiapkan ulang sebelum test berjalan. Dengan begitu, hasil test tidak bergantung pada data lokal yang kebetulan ada.
public function test_user_can_create_post(): void
{
$user = User::factory()->create();
$response = $this->actingAs($user)->post('/posts', [
'title'
Test seperti ini memverifikasi bukan hanya response, tetapi juga efek data di database.
Urutan yang sering dipakai saat bootstrap project baru:
Kalau alur ini dijaga, environment baru bisa naik dengan cepat dan test suite lebih mudah dijalankan ulang.
Data referensi seperti role, status, atau kategori sering dianggap sama dengan data transaksi. Padahal beda.
Kalau dua jenis data ini dicampur, reset environment jadi sulit.
Seeder yang terus membuat duplikat akan menyulitkan developer saat menjalankan ulang setup. Kalau perlu, gunakan pendekatan yang aman seperti updateOrCreate() atau cek keberadaan data dulu.
Factory yang membuat data tanpa relasi yang benar akan memunculkan record “yatim” atau foreign key error. Pastikan relasi model ikut dibentuk, bukan hanya atribut tunggal.
Kalau test bergantung pada data yang dibuat tangan di database lokal, test itu tidak portable. Begitu environment berubah, test bisa gagal tanpa alasan yang jelas.
Migration seharusnya fokus pada schema. Kalau isinya sudah mulai mirip ETL, bulk data import, atau backfill yang berat, biasanya lebih tepat dipisah ke command, job, atau script khusus.
Random itu berguna, tetapi jangan sampai hasilnya sulit dipakai. Contoh masalah:
Kalau test tidak memakai database terisolasi, hasilnya bisa dipengaruhi test sebelumnya. Ini salah satu sumber bug paling menyebalkan karena test terlihat “kadang gagal”.
Constraint yang tidak diuji sejak awal sering baru muncul saat data nyata masuk. Karena itu, factory dan test sebaiknya ikut menguji constraint penting, bukan hanya happy path.
Eloquent Relationship, Eager Loading, dan Query PatternMiddleware, Request, Response, dan Validation Flow di LaravelQueues, Jobs, Events, Listeners, dan Notifications di LaravelKalau kamu sudah paham empat alat ini, biasanya langkah berikutnya adalah merapikan cara aplikasi memproses data: request masuk, divalidasi, disimpan, diuji, lalu diulang tanpa bikin database lokal jadi liar.