Lompat ke isi
Les Laravel DocsTutorial Les Privat · Laravel CRUD
Unduh Starter Pack
Sesi 4: Delete & Uji MerusakEstimasi: 70 menit5 titik periksa

Bab 9 — Uji Merusak Aplikasi: Siapa yang Sebenarnya Menjaga Data?

9.1Konsep

Sampai Bab 8, semua fitur sudah jalan. Tetapi aplikasi yang "jalan kalau dipakai dengan benar" belum tentu aplikasi yang baik. Bab ini mengajakmu berpikir seperti orang yang mencoba merusaknya.

Di permintaan Bu Rina ada aturan: nomor HP orang tua wajib ada. Kita sudah menjaganya di dua tempat:

Tempat Cara Dijalankan oleh
Formulir HTML atribut required peramban (milik pengguna)
Controller $request->validate([...]) server (milikmu)

Pertanyaannya: kalau salah satu dari dua itu bisa dilewati, yang mana, dan apa akibatnya?

9.2🪤 Pertanyaan jebakan (kerjakan berurutan!)

Langkah A: tebak dulu, sebelum mencoba

Tulis tebakanmu di bukumu, jujur, sebelum menjalankan percobaan:

Langkah B: lakukan percobaan

  1. Jalankan php artisan serve, buka http://127.0.0.1:8000/siswa/create.
  2. Catat jumlah siswa sekarang: php artisan tinker lalu App\Models\Siswa::count(). Tulis angkanya, lalu exit.
  3. Di halaman formulir, klik kanan pada kolom Nomor HP → Inspect (Periksa). Di panel yang terbuka, cari tag <input ... required> dan hapus kata required (klik dua kali pada kata itu lalu hapus). Lakukan untuk ketiga kolom.
  4. Kosongkan semua kolom, lalu klik Simpan.
  5. Perhatikan apa yang terlihat di layar setelah itu.
  6. Hitung lagi lewat tinker: App\Models\Siswa::count(). Bandingkan dengan angka sebelumnya.

Langkah C: jawab

Tulis di bukumu:

  1. Berapa count() sebelum dan sesudah? Apakah data kosong tersimpan?
  2. Apa yang kamu lihat di layar setelah klik Simpan? Apakah ada pesan yang memberi tahu apa yang salah?
  3. Siapa yang menolak data kosong itu: peramban atau server? Baris kode mana yang menjadi buktinya?
  4. Kenapa required di HTML saja tidak cukup?

Kunci jawaban (untuk pengajar)

Data kosong tidak tersimpan: count() tidak berubah, karena $request->validate() di store() menolaknya di server. Tetapi layar hanya menampilkan formulir kembali tanpa pesan apa pun, karena create.blade.php belum punya blok yang menampilkan $errors. Pengguna tidak tahu kenapa datanya "tidak tersimpan". Pelajarannya: required di HTML hanya kenyamanan pengguna dan bisa dibuang oleh siapa saja. Pagar sesungguhnya ada di server. Dan pagar yang tidak memberi tahu pengguna kenapa ia menolak adalah pengalaman yang buruk.

9.3Perbaiki: tampilkan pesan galat

Test di Bab 6 sudah membuktikan data kosong ditolak server. Sekarang kita periksa bagian yang belum: apakah pesan galatnya tampil? Jalankan:

PowerShell
php artisan test --filter=TampilanGalatTest

Hasilnya: 2 test merah, 2 test hijau. Baca pesan merahnya: test mengharapkan teks The nama field is required. di halaman, tetapi tidak menemukannya. Itulah bukti bahwa pesan tidak tampil. Dua test hijau lainnya adalah jawaban dari jebakan: data kosong tidak tersimpan, dan nomor HP yang diawali nol tetap utuh.

Buka create.blade.php dan edit.blade.php. Di kedua berkas ada komentar penanda {{-- BAB 9: letakkan blok pesan galat di sini --}}. Ganti komentar itu dengan blok berikut:

📄 Berkas resources/views/siswa/create.blade.php dan resources/views/siswa/edit.blade.php

resources/views/siswa/create.blade.phpBlade
@if ($errors->any())    <div class="alert alert-danger">        <ul class="mb-0">            @foreach ($errors->all() as $error)                <li>{{ $error }}</li>            @endforeach        </ul>    </div>@endif

Membaca blok ini:

Potongan Artinya
$errors->any() Ada galat validasi? Kalau tidak, kotak merah tidak ditampilkan.
$errors->all() Daftar semua pesan galat.
@foreach ... <li>{{ $error }}</li> Menampilkan tiap pesan sebagai satu butir daftar.

$errors tersedia di setiap tampilan Blade tanpa kamu kirimkan dari controller. Laravel yang menyiapkannya setelah validate() gagal.

Jalankan test lagi:

PowerShell
php artisan test --filter=TampilanGalatTest

Sekarang 4 test hijau. Ulangi juga percobaan 9.2 langkah B. Kali ini, setelah klik Simpan, kamu melihat kotak merah berisi tiga pesan galat, dan count() tetap tidak berubah.

9.4Pembuktian kedua: kenapa no_hp bertipe teks?

Di Bab 2, no_hp dibuat bertipe string. Sekarang buktikan kenapa. Percobaan ini mengubah tabel sementara, jadi kerjakan hati-hati.

  1. Di migration create_siswas_table, ubah $table->string('no_hp'); menjadi $table->unsignedBigInteger('no_hp'); lalu simpan.
  2. php artisan migrate:fresh lalu php artisan serve.
  3. Lewat formulir, tambah siswa dengan nomor HP 081234567890.
  4. Lihat nomor yang tampil di daftar. Apa yang terjadi pada angka 0 di depan?
  5. Jalankan php artisan test --filter=ModelSiswaTest. Test mana yang merah, dan kenapa?
  6. Kembalikan migration menjadi string, lalu:
PowerShell
php artisan migrate:freshphp artisan db:seed --class=SiswaSeeder

9.5Jalankan seluruh test

PowerShell
php artisan test

Harapannya: 35 test hijau, tanpa satu pun merah:

Berkas test Jumlah
ModelSiswaTest 4
SeederSiswaTest 3
RuteSiswaTest 4
DaftarSiswaTest 4
TambahSiswaTest 6
UbahSiswaTest 5
HapusSiswaTest 5
TampilanGalatTest 4
Total 35

Tunjukkan layar hasil php artisan test kepada pengajarmu. Itu bukti pekerjaanmu lengkap.

9.6Yang sudah kamu bangun

Siapa berbicara dengan siapa dalam aplikasi CRUD.Siapa berbicara dengan siapa dalam aplikasi CRUD.
Siapa berbicara dengan siapa dalam aplikasi CRUD.
Fitur Method Rute Pelajaran utama
Daftar index GET /siswa Controller mengirim data ke View
Tambah create, store GET /siswa/create, POST /siswa Validasi, @csrf, redirect
Ubah edit, update GET /siswa/{id}/edit, PUT /siswa/{id} Route model binding, @method('PUT')
Hapus destroy DELETE /siswa/{id} Aksi berbahaya tidak boleh lewat tautan

Dan satu prinsip yang paling penting dari seluruh tutorial ini:


Titik periksa Bab 9

Centang setiap butir yang sudah kamu selesaikan.

  • Aku menulis tebakan sebelum percobaan jebakan, lalu menuliskan hasil sebenarnya.
  • Aku bisa menjelaskan: data kosong tidak tersimpan karena server menolaknya, tetapi tidak ada pesan karena tampilan belum memuat $errors.
  • Blok pesan galat sudah ada di create.blade.php dan edit.blade.php, dan kotak merah muncul saat formulir kosong dikirim.
  • Aku sudah membuktikan sendiri nol di depan nomor HP hilang pada kolom angka, lalu mengembalikan migration.
  • php artisan test → 35 test hijau.

Pertanyaan pemahaman

  1. Siapa yang menolak data kosong pada percobaan 9.2: peramban atau server? Bagaimana kamu membuktikannya?
  2. Kenapa required di HTML tidak cukup sebagai satu-satunya penjaga? Apa fungsinya kalau begitu?
  3. Apa yang terjadi pada pengguna kalau validasi gagal tetapi tampilan tidak memuat $errors?
  4. Kenapa nomor telepon disimpan sebagai teks, bukan angka?
  5. Dari semua yang kamu bangun, bagian mana yang menurutmu paling mudah dibobol kalau aplikasi ini dipakai banyak orang? Kenapa?

Tantangan akhir (pilih satu)

Tantangan Petunjuk
Pencarian nama Tambah kolom pencarian di daftar. Di index() pakai Siswa::where('nama', 'like', '%'.$request->q.'%').
Paginasi Ganti get() dengan paginate(5) dan tambah {{ $siswas->links() }} di tampilan.
Kolom kelas Tambah kolom lewat migration, $fillable, formulir, dan validasi. Tulis test-mu sendiri.
Tulis satu test baru Buat tests/Feature/NamaTestMu.php yang memeriksa satu hal yang belum diuji (mis. nama lebih dari 100 karakter).
Login pengelola Pasang Laravel Breeze dan lindungi semua rute siswa dengan auth. (Tantangan besar!)

Kesalahan umum

Gejala Penyebab & solusi
Kotak merah tidak muncul walau validasi gagal Blok @if ($errors->any()) belum ditempel, atau ditempel di luar @section('content').
TampilanGalatTest merah tetapi kotak merah muncul di browser Pesan galat di test memakai bahasa Inggris (The nama field is required.). Pastikan APP_LOCALE=en di .env.
Test galat merah pada halaman edit saja Blok hanya ditempel di create.blade.php. Tempel juga di edit.blade.php.
migrate:fresh menghapus semua data Itu memang tugasnya. Isi lagi dengan php artisan db:seed --class=SiswaSeeder.
ModelSiswaTest atau TampilanGalatTest merah setelah percobaan 9.4 Migration belum dikembalikan ke string. Kembalikan lalu migrate:fresh.
php artisan test merah di banyak berkas Perbaiki yang pertama (paling atas) dulu. Satu kesalahan dasar sering menjatuhkan banyak test.

🎉 Selesai! Kamu membangun aplikasi Laravel dari proyek kosong, menelusuri beberapa jenis galat dari pesannya, dan membuktikan sendiri bahwa validasi di peramban saja tidak cukup. Bu Rina punya aplikasinya sekarang.

Tutorial Data Siswa Les — Laravel CRUD untuk les privat.

Kode boleh disalin, tapi coba ketik sendiri dulu: tangan yang mengetik lebih cepat paham.