Nafies Luthfi

Life will always feel wonderful if we always think positively.

Testing Laravel: Register Feature Test

Bismillahirrahmanirrahim.

Jika pada artikel sebelumnya kita membuat feature test untuk fitur login bawaan Laravel, kali ini kita membuat feature test untuk fitur registrasi usernya. Sedikit mengulang, fitur register ini dihasilkan melalui perintah:

$ php artisan make:auth

Pada praktek ini, kita menggunakan repository github Laravel-TDD, yaitu pada commit eb202bf. Jika ingin mengikuti sama persis, silakan teman-teman clone repo itu ke localhost.

Karena konten artikel ini agak panjang, sedikit saya sampaikan sub-sub judulnya:

  1. Jalankan Testing Sebelum Mulai
  2. Membuat Feature Test Register
  3. Testing Validasi Form Register
  4. Kesimpulan

Baik kita mulai.

Jalankan Testing Sebelum Mulai

Seperti biasa, kita mulai kerja dengan menjalankan testing dulu.

# 1
$ vendor/bin/phpunit

OK (11 tests, 60 assertions) Sudah hijau, kita lanjutkan.

Membuat Feature Test Register

$ php artisan make:test Auth/RegisterTest

Kita akan mendapatkan testcase class baru di : tests/Feature/Auth/RegisterTest.php. Sekarang edit filenya dan buat test method baru user_can_register.

<?php

namespace Tests\Feature\Auth;

use App\User; // Tambahkan use model App\User
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;

class RegisterTest extends TestCase
{
    // Trait refresh database agar migration dijalankan
    use RefreshDatabase;

    /** @test */
    public function user_can_register()
    {        
        // Kunjungi halaman '/register'
        $this->visit('/register');

        // Submit form register dengan name, email dan password 2 kali
        $this->submitForm('Register', [
            'name'                  => 'John Thor',
            'email'                 => 'username@example.net',
            'password'              => 'secret',
            'password_confirmation' => 'secret',
        ]);

        // Lihat halaman ter-redirect ke url '/home' (register sukses).
        $this->seePageIs('/home');

        // Kita melihat halaman tulisan "Dashboard" pada halaman itu.
        $this->seeText('Dashboard');

        // Lihat di database, tabel users, data user yang register sudah masuk
        $this->seeInDatabase('users', [
            'name'  => 'John Thor',
            'email' => 'username@example.net',
        ]);

        // Cek hash password yang tersimpan cocok dengan password yang diinput
        $this->assertTrue(app('hash')->check('secret', User::first()->password));
    }
}

Sekarang kita jalankan PHPUnitnya:

# 2
$ vendor/bin/phpunit
Hasil: Passed

Register Test Passed{:style=“width:100%”}

Okey, mantap. Sekali lagi, karena fiturnya sudah ada, ketika script testing dibuat sesuai fitur yang ada, maka hasilnya harus langsung hijau.

Testing Validasi Form Register

Karena kita sudah dapat hasil hijau untuk inputan yang valid, sekarang kita buat testing untuk validasi form register ini.

Lihat Validation Rules

Karena fiturnya sudah ada, maka kita perlu melihat apa saja validation rules yang digunakan pada formulir register ini. Bisa dilihat di controller: app\Http\Controllers\Auth\RegisterController.php, kemudian lihat method validator(). Script pada method itu isinya seperti ini:

<?php
    // Class RegisterController.php

    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:6|confirmed',
        ]);
    }

Di lihat dari validation rules-nya:

  1. name: wajib diisi, berbentuk string, dan maksimal 255 karakter.
  2. email: wajib diisi, berbentuk string, berupa format email, maksimal 255 karakter, dan email harus unik pada tabel users.
  3. password: wajib diisi, berbentuk string, minimal 6 karakter, dan harus sama dengan field password_confirmation.

Sedikit refresher saja, validation rules adalah aturan-aturan yang diberlakukan terhadap data-data yang diinput ke sistem melalui submit form. Jika aturan-aturannya dilanggar (data yang diinput tidak valid), maka Laravel akan membatalkan proses data dan meminta agar formulir diisi kembali dengan benar.

Test Method untuk Validation Rules

Dari validation rules di atas, kita akan membuat beberapa test method :

  1. user_name_is_required
  2. user_name_maximum_is_255_characters
  3. user_email_is_required
  4. user_email_must_be_a_valid_email
  5. user_email_maximum_is_255_characters
  6. user_email_must_be_unique_on_users_table
  7. user_password_is_required
  8. user_password_minimum_is_6_characters
  9. user_password_must_be_same_with_password_confirmation_field

Wah, kok banyak? Ga apa-apa sekalian latihan, biar terbiasa nulis test :D

Testing Script untuk Validation Rules

Nah untuk script testingnya, kita boleh mencontoh script testing yang pernah kita buat pada artikel ini: Testing Validasi Form.

Baik sekarang kita buat test method dan script sesuai dengan method-method di atas ya …

<?php
    // Class RegisterTest.php
    
    // ... user_can_register()

    /** @test */
    public function user_name_is_required()
    {
        // Submit form untuk register dengan field 'name' kosong.
        $this->post('/register', [
            'name'                  => '',
            'email'                 => 'username@example.net',
            'password'              => 'secret',
            'password_confirmation' => 'secret',
        ]);

        // Cek pada session apakah ada error untuk field 'name'.
        $this->assertSessionHasErrors(['name']);
    }

    /** @test */
    public function user_name_maximum_is_255_characters()
    {
        // Submit form untuk register dengan field 'name' 260 karakter.
        $this->post('/register', [
            'name'                  => str_repeat('John Thor ', 26),
            'email'                 => 'username@example.net',
            'password'              => 'secret',
            'password_confirmation' => 'secret',
        ]);

        // Cek pada session apakah ada error untuk field 'name'.
        $this->assertSessionHasErrors(['name']);
    }

    /** @test */
    public function user_email_is_required()
    {
        // Submit form untuk register dengan field 'email' kosong.
        $this->post('/register', [
            'name'                  => 'John Thor',
            'email'                 => '',
            'password'              => 'secret',
            'password_confirmation' => 'secret',
        ]);

        // Cek pada session apakah ada error untuk field 'email'.
        $this->assertSessionHasErrors(['email']);
    }

    /** @test */
    public function user_email_must_be_a_valid_email()
    {
        // Submit form untuk register dengan field 'email' tidak valid.
        $this->post('/register', [
            'name'                  => 'John Thor',
            'email'                 => 'username.example.net',
            'password'              => 'secret',
            'password_confirmation' => 'secret',
        ]);

        // Cek pada session apakah ada error untuk field 'email'.
        $this->assertSessionHasErrors(['email']);
    }

    /** @test */
    public function user_email_maximum_is_255_characters()
    {
        // Submit form untuk register dengan field 'email' 260 karakter.
        $this->post('/register', [
            'name'                  => 'John Thor',
            'email'                 => str_repeat('username@example.net', 13),
            'password'              => 'secret',
            'password_confirmation' => 'secret',
        ]);

        // Cek pada session apakah ada error untuk field 'email'.
        $this->assertSessionHasErrors(['email']);
    }

    /** @test */
    public function user_email_must_be_unique_on_users_table()
    {
        // Buat satu user baru
        $user = factory(User::class)->create(['email' => 'emailsama@example.net']);

        // Submit form untuk register dengan field
        // 'email' yang sudah ada di tabel users.
        $this->post('/register', [
            'name'                  => 'John Thor',
            'email'                 => 'emailsama@example.net',
            'password'              => 'secret',
            'password_confirmation' => 'secret',
        ]);

        // Cek pada session apakah ada error untuk field 'email'.
        $this->assertSessionHasErrors(['email']);
    }

    /** @test */
    public function user_password_is_required()
    {
        // Submit form untuk register dengan field 'password' kosong.
        $this->post('/register', [
            'name'                  => 'John Thor',
            'email'                 => 'username@example.net',
            'password'              => '',
            'password_confirmation' => 'secret',
        ]);

        // Cek pada session apakah ada error untuk field 'password'.
        $this->assertSessionHasErrors(['password']);
    }

    /** @test */
    public function user_password_minimum_is_6_characters()
    {
        // Submit form untuk register dengan field 'password' 5 karakter.
        $this->post('/register', [
            'name'                  => 'John Thor',
            'email'                 => 'username@example.net',
            'password'              => 'ecret',
            'password_confirmation' => 'ecret',
        ]);

        // Cek pada session apakah ada error untuk field 'password'.
        $this->assertSessionHasErrors(['password']);
    }

    /** @test */
    public function user_password_must_be_same_with_password_confirmation_field()
    {
        // Submit form untuk register dengan field 'password'
        // beda dengan 'password_confirmation'.
        $this->post('/register', [
            'name'                  => 'John Thor',
            'email'                 => 'username@example.net',
            'password'              => 'secret',
            'password_confirmation' => 'escret',
        ]);

        // Cek pada session apakah ada error untuk field 'password'.
        $this->assertSessionHasErrors(['password']);
    }

Cukup panjang, tapi ga apa-apa, cuman copy-paste ini. Sekarang kita jalankan PHPUnitnya:

# 3
$ vendor/bin/phpunit
Hasil: Passed

Register Validation Test Passed{:style=“width:100%”}

Langsung hijau juga ya? Ya harus, kalau dapat merah, berarti copy-paste-nya ada salah.

Kesimpulan

Seperti manfaat dari feature test login kemarin, feature test register user ini akan sangat membantu jika ada perubahan kebijakan terhadap formulir yang harus diisi oleh user baru. Misalnya:

  1. Formulir isian register ditambahkan nomor telepon, alamat, kota dan Kodepos.
  2. Pada formulir register, user harus setuju dengan syarat dan ketentuan sistem dengan cara centang checkbox.
  3. Dan berbagai kemungkinan perubahan fitur register di kemudian hari.

Semua kode yang telah kita kerjakan pada artikel ini, bisa teman-teman lihat di pada file RegisterTest.php ini.

Semoga belajar automated testing di Laravel semakin menyenangkan. Demikian dan terima kasih atas waktu teman-teman, semoga bermanfaat.