Seringkali saya mendapatkan project yang sudah jalan tapi tanpa ada testing didalamnya. Bahkan project yang diklaim dikerjakan oleh programmer veteran sekalipun. Sehingga saya harus extra hati-hati untuk mengubah suatu code.

Contoh kasus misalnya saya memperbaiki bug. Bisa jadi code yang saya ubah untuk suatu page, bug-nya beres. Tapi di page lain ternyata menjadi rusak. Saya harus mengecek satu-persatu efeknya kemana saja. Atau code-nya ini digunakan dimana saja. Tentu saja ini tidak efesien. Membuang waktu dan melelahkan :/

So, salah satu solusinya adalah dengan membuat test terlebih dahulu yang sesuai dengan ekspektasi yang kita inginkan, lalu baru membuat code yang sebenarnya. Banyak sekali jargon yang mungkin membuat anda bingung. Misalnya apa itu TDD? :/ Cek Wikipedia πŸ˜€

Masih bingung? :/ Saya coba bantu sederhanakan agar lebih mudah dimengerti (dan semoga mengerti). Seperti biasa, saya selalu mengatakan di forum–untuk mengerti sesuatu, ketahui dulu ARTINYA.

TDD adalah singkatan dari Test-Driven Development. Kita artikan per satu-satu kata. Test dan Development udah taulah yaa… Artiin sendiri aja πŸ˜“

Kata dasar driven adalah drive yang artinya mengendarai. Jadi driven adalah…? Pengembangan yang dikendarai oleh percobaan. Hmm… ntah kenapa kalau diartikan ke Bahasa Indonesia ini jadi aneh πŸ˜–. Tapi semoga anda mengerti maksudnya πŸ˜€

Bagi sebagian orang yang belum terbiasa, dengan membuat test terlebih dahulu memang awalnya terkesan merepotkan dan membuang waktu, karena fiturnya tidak langsung terlihat. Tetapi ini justru akan membuat anda nyaman di kemudian hari (seperti contoh saya diatas). Misalnya 8 bulan dari sekarang (sudah mulai lupa), anda mengubah suatu code, anda akan tetap yakin dan percaya diri kalau code yang anda ubah tidak membuat yang lain menjadi rusak.

Btw, kita tidak akan bahas unit test disini. Karena tujuannya ini untuk mempermudah pemahaman bagi yang belum pernah atau belum terbiasa menggunakan testing, dan yang juga tidak kalah penting adalah untuk mengubah mindset.

Tapi pada dasarnya unit test itu sama. Ketika anda mau membuat suatu fitur atau code anda buat dulu test atau ekspektasinya, lalu baru buat code-nya.

Simulasi

Sebagai contoh kita buat form untuk guest book, salah satu fitur populer di website pribadi pada era akhir 90-an dan awal 2000-an :D. Ada tiga field pada form ini. Yaitu nama, email dan pesan. Ekspektasi saya:

  • Jika nama tidak diisi, maka muncul pesan error “Nama harus diisi”, dan saya tidak mau datanya masuk ke database.
  • Jika email tidak diisi, maka muncul pesan error “Email harus diisi”, dan saya tidak mau datanya masuk ke database.

  • Jika pesan tidak diisi, maka muncul pesan error “Pesan harus diisi”, dan saya tidak mau datanya masuk ke database.

  • Jika email diisi tapi tidak benar formatnya, maka muncul pesan error “Email yang anda masukkan salah”, dan saya tidak mau datanya masuk ke database.

  • Jika tidak ada problem diatas, maka data akan disimpan di database.

Simple kan? Biasanya hal-hal seperti ini sudah ada di otak.

Kita akan buat test dengan menggunakan Laravel 5.1 (masih development version). Caranya install saja dengan cara

composer create-project laravel/laravel [folder] dev-develop

Jangan lupa buat migrations dan setup database sendiri berdasarkan tiga field tadi. Bila dibutuhkan anda juga bisa membuat model sendiri.

Pembuatan Test

Buat file baru di tests/GuestbookTest.php, isi dengan

<?php

use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class GuestbookTest extends TestCase
{
    public function test_name_if_empty()
    {
    }
}

Setiap file harus berakhirkan Test. Dan nama method yang akan di-test harus berawalan test. Jika ingin menggunakan nama method tidak berawalan test, anda bisa menambahkan /** @test */ di docblock.

Oke, kita masukkan ekpektasi kita tadi yang berhubungan dengan nama.

public function test_name_if_empty()
{
    $this->visit('/');
}

Artinya saya MENGUNJUNGI halaman dengan route /. Maksudnya home page.

public function test_name_if_empty()
{
    $this->visit('/')
         ->see('Guest Book');
}

Artinya setelah masuk ke homepage, lalu saya MELIHAT tombol dengan tulisan “Guest Book”.

public function test_name_if_empty()
{
    $this->visit('/')
         ->see('Guest Book')
         ->click('Guest Book');
}

Setelah itu saya KLIK tulisan “Guest Book”.

public function test_name_if_empty()
{
    $this->visit('/')
         ->see('Guest Book')
         ->click('Guest Book')
         ->landOn('/guestbook');
}

Setelah saya klik, saya akan MENDARAT di /guestbook

public function test_name_if_empty()
{
    $this->visit('/')
         ->see('Guest Book')
         ->click('Guest Book')
         ->landOn('/guestbook')
         ->submitForm('Submit', [
             'email' => 'kumis@example.org',
             'message' => 'Hello World!'
         ]);
}

Saya isi email dan message, tapi mengosongkan name. Setelah itu click tombol “Submit”.

public function test_name_if_empty()
{
    $this->visit('/')
         ->see('Guest Book')
         ->click('Guest Book')
         ->landOn('/guestbook')
         ->submitForm('Submit', [
             'email' => 'kumis@example.org',
             'message' => 'Hello World!'
         ])
         ->notSeeInDatabase('guestbooks', [
             'email' => 'kumis@example.org',
             'message' => 'Hello World!'         
         ]);
}

Saya tidak mau setelah submit, data malah masuk ke database.

public function test_name_if_empty()
{
    $this->visit('/')
         ->see('Guest Book')
         ->click('Guest Book')
         ->landOn('/guestbook')
         ->submitForm('Submit', [
             'email' => 'kumis@example.org',
             'message' => 'Hello World!'
         ])
         ->notSeeInDatabase('guestbooks', [
             'email' => 'kumis@example.org',
             'message' => 'Hello World!'         
         ])
         ->see('Nama harus diisi');
}

Lalu saya melihat “Nama harus diisi”.

Pembuatan Code

Setelah test-nya selesai, sekarang saatnya kita buat code-nya.

Saya buat routing untuk guestbook. Edit file app/Http/routes.php, lalu tambahkan

Route::get('/guestbook', 'GuestbookController@getPage');
Route::post('/guestbook', 'GuestbookController@postPage');

Setelah itu kita buat Controller-nya menggunakan artisan

php artisan make:controller GuestbookController --plain

Edit file yang baru di-generate tadi di app/Http/Controllers/GuestbookController.php

Tambahkan saja seperti ini kira-kira

public function getPage()
{
    return view('guestbook');
}

public function postPage(Request $request)
{
    $this->validate();
}

Sekarang kita buat page sederhana di resources/views/guestbook.blade.php

<form method="post">

    <input type="text" name="name">
    <input type="text" name="email">
    <input type="text" name="message">
    <input type="submit">

</form>

Oke, sekarang giliran anda membuat agar fitur guest book ini berfungsi. Jika sudah yakin benar, jalankan phpunit.

Bila sudah ada phpunit di global, bila langsung jalankan. Tapi bila belum ada anda bisa menggunakan ./vendor/bin/phpunit, kalau salah akan muncul warna merah beserta informasi kesalahannya apa dan dimana.

Screen Shot 2015-05-28 at 14.13.01

Jika tidak ada kesalahan, warnanya akan hijau.

Screen Shot 2015-05-28 at 14.13.26

Jika diatas sudah berhasil, coba tambahkan semua fitur pengecekan tadi lalu buat menjadi hijau.

Bila masih bingung, anda bisa mampir ke GitHub ini
https://github.com/mul14/laravel-5.1-test-example

Oh yaa… nikmatnya lagi, anda bisa membuat test di Laravel 5.1 ini TANPA harus membuka browser. Cukup fokus di ekspektasi anda, dan buat code-nya, lalu jalankan test untuk memastikan semua sudah berjalan sesuai rencana πŸ˜€

Bila ada pertanyaan atau kritik silahkan dimasukkin aja di kolom komentar πŸ™‚

Iklan

9 pemikiran pada “Membuat Test di Laravel 5.1

  1. diskusi menarik, menurut anda mendingan dikasih test tapi ngetesnya hal2 yang ga penting atau ga ditest sama sekali tapi design dan peletakan code nya sangat obvious?

    1. Hmm, penting disini sepertinya masih terlalu blurry dan subjective.

      Kalau saya sih biasanya hanya ngetes hal-hal yang penting.

      Hal-hal trivial seperti misalnya tahun di footer, saya nggak mau bikin test-nya 😐

  2. Mungkin bisa ditambahin contoh testing jika terjadi kesalahan?
    contoh yang biasanya atau yang wajib di test itu hal seperti apa?
    btw, article yang bagus πŸ™‚

    1. Yup, jika terjadi kesalahan akan seperti yang ada pada gambar di atas. Ada tulisan warna merah dan berisi informasi kesalahannya apa.

      Bila diperhatikan hal yang kita test adalah KLIK tulisan β€œGuest Book”. Tapi ternyata tidak menemukan “Guest Book”, tapi “Guest Boo”. Silahkan dicek lagi screenshot-nya.

      Hal-hal yang perlu di-test biasanya hal-hal yang penting. Seperti simulasi di kasus di tulisan ini, agar kita yakin fitur Guest Book berjalan sebagaimana mestinya, kita bikin test terlebih dahulu.

      1. saya udah coba utak atik codenya πŸ™‚
        dan sekarang udah lebih ngerti..
        makasih artikelnya πŸ˜€
        btw, “Jika tidak ada kesalahan, warnanya akan hijau.” atau “Jika ada kesalahan, warnanya akan merah.” menggunakan terminal bawaan mac?
        saya menggunakan git bash di windows keliatannya tidak seperti itu 😐

    1. Lha, kan kalau sudah lolos test berarti sudah diimplementasikan 😐

      1) Buat ekspektasi dengan membuat test (masih RED karena code implementasi yang sebenarnya belum dibuat)

      2) Implementasi code yang sebenarnya (jadikan GREEN)

      Selesai 😐

Tinggalkan Balasan

Please log in using one of these methods to post your comment:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s