Testing Laravel: Definisi Fitur dan First Failing Test
Bismillahirrahmanirrahim
Sebelumnya kita membahas setup project baru laravel dengan testing, sekarang kita lanjutkan membuat definisi dari fitur yang akan kita buat. Pada tutorial TDD ini, ceritanya kita akan membuat Fitur CRUD Task atau Create, Read, Update, and Delete Task.
Pada penerapan TDD, proses yang kita lakukan saat membuat sebuah fitur kurang lebih seperti ini (mulai perencanaan hingga implementasi) :
- Mendefinisikan fitur.
- Memprioritas sub-fitur.
- Membuat kelas TestCase fitur.
- Membuat method test untuk masing-masing sub-fitur.
- Mulai membuat failing test untuk method test.
- Mulai kerjakan (menulis kode) fitur pada aplikasi sampai failing test menjadi passed test.
- Ulangi langkah 4 s/d 6 hingga fitur selesai dibuat.
1. Definisi Fitur
Mendefinisikan sama dengan menentukan/menyusun spesifikasi dari fitur yang kita ingin buat. Kali ini kita akan membuat fitur CRUD Task dengan spesifikasi sebagai berikut :
- Record pada database disimpan dalam tabel
tasks
dengan atributname
,description
, danis_done
- Atribut
is_done
: 0 belum dikerjakan, 1 sudah dikerjakan. - User dapat melihat daftar Task
- User dapat menginput Task baru
- User dapat meng-edit Task
- User dapat menghapus Task
2. Menyusun Prioritas Sub-fitur
Berikutnya kita susun prioritas pengerjaan fitur/sub-fitur mana yang kita kerjakan duluan dari spesifikasi di atas, dilengkapi dengan rencana konsep pengoperasian oleh user.
- Input Task
Untuk melakukan Input Task baru, user membuka halaman Daftar Task, kemudian mengisi formname
dandescription
, klik tombol “Create Task”. Setelah berhasil, record Task tersimpan ke database, user redirect ke halaman Daftar Task, dan melihat Task yang telah diinput tampil pada halaman webnya. - Lihat Daftar Task
Jika ada record Task di dalam database, kemudian user membuka halaman Daftar Task. Muncul nama dan deskripsi Task yang ada. - Edit/Update Task
Jika ada record Task di dalam database, kemudian user membuka halaman Daftar Task, User meng-klik tombol “Edit Task”, mengubahname
dandescription
kemudian tekan tombol “Update Task”. Setelah berhasil, record tersimpan di database, user redirect ke halaman Daftar Task, dan melihat Task yang telah diupdate pada halaman webnya. - Hapus Task
Jika ada record Task di dalam database, kemudian user membuka halaman Daftar Task, User melihat tombol “Delete Task”. User meng-klik tombol “Delete Task”. Setelah berhasil, user redirect ke halaman Daftar Task, record Task tidak tampil dan hilang dari database.
Penyusunan prioritas ini penting, agar kita tahu sub-fitur mana yang mesti dikerjakan terlebih dahulu dibandingkan dengan sub-fitur yang lain. Ini melatih kita (sebagai developer) untuk efisien waktu dan manajemen project. Lama-kelamaan kita bisa dengan mudah meng-estimasi lama pengerjaan dari sebuah fitur dengan spesifikasi tertentu.
3. Membuat Kelas TestCase
Kelas TestCase adalah kelas testing untuk sebuah fitur, yang dibuat untuk mengelompokkan pengujian sub-sub fiturnya. Misal kita ingin membuat sebuah kelas testing untuk fitur Kalkulator, maka kelas TestCase yang kita buat bernama KalkulatorTest. Di dalam kelas KalkulatorTest terdapat method-method test untuk masing-masing sub-fitur dari kalkulator tersebut.
Baik, kita lanjut. Pada terminal, kita cd
ke direktori Project Laravel, kemudian jalankan testing untuk memastikan testing yang sudah ada berjalan dengan baik :
$ vendor/bin/phpunit
{:style=“width:100%”}
Hasilnya, 2 tests
dan 2 assertions
, sama seperti kondisi akhir artikel sebelumnya.
Untuk membuat TestCase baru, kita berikan perintah :
$ php artisan make:test ManageTasksTest
Laravel membuat TestCase pada direktori tests/Feature
bernama ManageTasksTest.php
.
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
class ManageTasksTest extends TestCase
{
/**
* A basic test example.
*
* @return void
*/
public function testExample()
{
$this->assertTrue(true);
}
}
Sekarang kita coba jalankan lagi testingnya :
$ vendor/bin/phpunit
{:style=“width:100%”}
Oke, sudah ada 3 tests
dan 3 assertions
artinya kelas ManageTasksTest sudah jalan. Sampai disini kita lanjutkan membuat method-method testingnya.
Akhiran (suffix) Test wajib untuk setiap nama kelas TestCase. Karena tanpa suffix Test, PHPUnit tidak mengenali kelas tersebut sebagai kelas testing yang harus dijalankan. Referensi.
4. Membuat Method Test
Method Test atau Test Method adalah method-method pada kelas TestCase yang akan dijalankan oleh PHPUnit. Untuk mempermudah pemahaman kita, satu Test Method itu sama dengan pengujian untuk satu sub-fitur. Jadi kita akan membuat :
- Satu Test Method untuk Input Task
- Satu Test Method untuk Lihat Daftar Task
- Satu Test Method untuk Edit Task
- Satu Test Method untuk Hapus Task
Baik kita edit file kelas tests/Feature/ManageTasksTest.php
dan kita update seperti ini :
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
class ManageTasksTest extends TestCase
{
/** @test */
public function user_can_create_a_task()
{
$this->assertTrue(true);
}
/** @test */
public function user_can_browser_tasks_index_page()
{
$this->assertTrue(true);
}
/** @test */
public function user_can_edit_an_existing_task()
{
$this->assertTrue(true);
}
/** @test */
public function user_can_delete_an_existing_task()
{
$this->assertTrue(true);
}
}
Ingat, satu test method mewakili satu sub-fitur :
user_can_create_a_task
untuk Input Taskuser_can_browser_tasks_index_page
untuk Lihat Daftar Taskuser_can_edit_an_existing_task
untuk Edit Taskuser_can_delete_an_existing_task
untuk Hapus Task
Sekarang kita jalankan lagi PHPUnit-nya, seharusnya kita mendapat hasil seperti berikut :
{:style=“width:100%”}
“Hijau” ya? Baik, sampai di sini kita punya 4 sub-fitur dengan Test Method masing-masing untuk fitur CRUD Task.
Syarat sebuah test method : harus berupa
public
method dan nama method harus diawali dengantest
atau diberikan anotasi@test
pada docblock method. Referensi.
5. Membuat “Failing Test”
Sekarang kita fokus ke method user_can_create_a_task() untuk membuat failing test, yaitu script testing yang kita buat ini untuk menguji fitur yang belum ada di sistem, jadi pasti gagal (fail).
Oke, untuk mempermudah membuat script testing, kita buat beberapa perumpamaan langkah/proses yang dilakukan oleh user ketika menggunakan sub-fitur tersebut dengan PHP comment line. Seperti ini :
<?php
// Kelas ManageTasksTest.php
/** @test */
public function user_can_create_a_task()
{
// User buka halaman Daftar Task
// Isi form `name` dan `description` kemudian submit
// Lihat Record tersimpan ke database
// Redirect ke halaman Daftar Task
// Tampil hasil task yang telah diinput
}
Metode ini saya pelajari dari video youtube Laravel Daily.
Setelah membuat comment seperti di atas, kita coba buat testing script-nya untuk masing-masing langkah ini.
<?php
// Kelas ManageTasksTest.php
/** @test */
public function user_can_create_a_task()
{
// User memngunjungi halaman Daftar Task
$this->visit('/tasks');
// Isi form `name` dan `description` kemudian submit
$this->submitForm('Create Task', [
'name' => 'My First Task',
'description' => 'This is my first task on my new job.',
]);
// Lihat Record tersimpan ke database
$this->seeInDatabase('tasks', [
'name' => 'My First Task',
'description' => 'This is my first task on my new job.',
'is_done' => 0,
]);
// Redirect ke halaman Daftar Task
$this->seePageIs('/tasks');
// Tampil hasil task yang telah diinput
$this->see('My First Task');
$this->see('This is my first task on my new job.');
}
Kita bisa lihat, setiap langkah/proses yang seharusnya dilakukan oleh user (manusia) kita gantikan dengan testing script yang sesuai :
$this->visit('/tasks');
untuk mengunjungi halaman dengan URL tertentu.$this->submitForm('Create Task', ...
untuk mengisi form dan klik tombol “Create Task”.$this->seePageIs('/tasks');
melihat URL yang kita dapatkan setelah action sebelumnya.$this->seeInDatabase('tasks', ...
melihat isi tabeltasks
pada database.$this->see('.....');
melihat isi tulisan yang tampil di halaman web.
Oke, jika kita jalankan kembali PHPUnitnya :
$ vendor/bin/phpunit
Hasilnya? {:style=“width:100%”}
{:style=“width:100%”}
Yap kita dapat “Merah”
, “failing test” pertama berhasil dibuat :)
Pada error ini, yang kita perhatikan adalah tulisan-tulisan pada posisi saya garis bawahi pada gambar di atas :
- Tulisan di bawah Kelas dan method test
- Status Code yang didapatkan
- Baris keberapa pada Kelas Test kita mendapatkan error ini
- Disebabkan oleh apa error ini terjadi.
Dengan memperhatikan 4 hal di atas, kita bisa tahu, apa yang menyebabkan error ini terjadi, sehingga kita dapat memperbaiki kode di aplikasi yang kita buat. Untuk error yang pertama ini, kita mendapatkan NotFoundHttpException
, artinya route untuk URL /tasks
itu tidak ditemukan.
Untuk membuktikannya, sekarang coba kita buka halaman webnya :
$ php artisan serve
Laravel development server started: <http://127.0.0.1:8000>
Kita coba buka URL di browser : http://127.0.0.1:8000/tasks
.
Setiap error yang tampil pada terminal saat kita menjalankan test, umumnya sama dengan tampilan error yang muncul di layar web. Pesan di atas sama dengan NotFoundHttpException
dan status code = 404, hanya saja dihandle oleh Laravel dengan menampilkan halaman error 404.
Baik, sampai di sini cukup dulu. Insyaallah pada artikel berikutnya, kita akan menulis kode aplikasi untuk sub-fitur input Task, sampai testing method user_can_create_a_task() mendapatkan hasil “Hijau”
.
Jika ada yang kurang jelas dengan penjelasan dan tutorial pada artikel ini, atau ada hal yang keliru, mohon disampaikan pada komentar.
Terima kasih untuk waktu teman-teman berkenan membaca.
Source untuk kelas
ManageTasksTest
dapat dilihat commit github ini.