Nafies Luthfi

Life will always feel wonderful if we always think positively.

Testing Laravel: Menggunakan Model Factory

Bismillahirrahmanirrahim

Di beberapa artikel sebelumnya kita masih bicara seputar satu fitur, yaitu Input Task. Sekarang kita akan membuat testing agar user dapat melihat daftar Task yang ada. Sebenarnya fitur ini secara tidak langsung sudah ada pada tahap pengerjaan fitur sebelumnya, kita sudah dapat melihat daftar task. Tetapi kali ini kita membuat task tanpa harus input task dari form. Kita akan memanfaatkan Model Factory Laravel untuk meng-generate beberapa task pada testing.

Model Factory adalah fitur yang berfungsi untuk membuat instance dari kelas model laravel dengan atribut-atribut yang sesuai dengan kolom-kolom tabel yang sesuai pada database. Setiap penggunaan model factory akan menghasilkan instance model atau collection (list) dari beberapa model yang sama.

Pada artikel Definisi Fitur, kita sudah membuat sebuah test method untuk artikel ini, yaitu user_can_browse_tasks_index_page. Isinya hanya $this->assertTrue(true);, sebuah assert sederhana agar test method ini passed (untuk sementara waktu). Kita akan bekerja pada method test ini.

<?php

// ...

class ManageTasksTest extends TestCase
{
    // ... user_can_create_a_task()

    /** @test */
    public function user_can_browse_tasks_index_page()
    {
        $this->assertTrue(true);
    }

    // ... user_can_edit_an_existing_task()
    
    // ... user_can_delete_an_existing_task()
}

Sebelum mulai kerja, kita jalankan dulu PHPUnit, untuk memastikan aplikasi tidak ada masalah.

# 1
$ vendor/bin/phpunit

OK (7 tests, 13 assertions)

Membuat Test Method

Sekarang kita lanjut mendefinisikan langkah dalam testing method tersebut (dalam bentuk PHP comment line) sesuai yang kita inginkan. Seperti ini :

<?php

    /** @test */
    public function user_can_browse_tasks_index_page()
    {
        // Generate 3 record task pada table `tasks`.
        
        // User membuka halaman Daftar Task.

        // User melihat ketiga task tampil pada halaman.

        // User melihat link untuk edit task pada masing-masing item task.
    }
}

Baik, itu misinya, sekarang kita buat script untuk memenuhi langkah tersebut.

<?php

// ...
use App\Task; // Tambahkan ini

class ManageTasksTest extends TestCase
{
    // ... user_can_create_a_task()
    
    /** @test */
    public function user_can_browse_tasks_index_page()
    {
        // Generate 3 record task pada table `tasks`.
        $tasks = factory(Task::class, 3)->create();

        // User membuka halaman Daftar Task.
        $this->visit('/tasks');

        // User melihat ketiga task tampil pada halaman.
        $this->see($tasks[0]->name);
        $this->see($tasks[1]->name);
        $this->see($tasks[2]->name);

        // User melihat link untuk edit task pada masing-masing item task.
        
        // <a href="/tasks?action=edit&id=1" id="edit_task_1">edit</a>
        $this->seeElement('a', [
            'id'   => 'edit_task_'.$tasks[0]->id,
            'href' => url('tasks?action=edit&id='.$tasks[0]->id)
        ]);

        // <a href="/tasks?action=edit&id=2" id="edit_task_2">edit</a>
        $this->seeElement('a', [
            'id'   => 'edit_task_'.$tasks[1]->id,
            'href' => url('tasks?action=edit&id='.$tasks[1]->id)
        ]);

        // <a href="/tasks?action=edit&id=3" id="edit_task_3">edit</a>
        $this->seeElement('a', [
            'id'   => 'edit_task_'.$tasks[2]->id,
            'href' => url('tasks?action=edit&id='.$tasks[2]->id)
        ]);
    }
}

Jangan lupa use App\Task; di atas kelas ManageTasksTest.

Oke, kita jalankan PHPUnit untuk mendapatkan error pertama.

# 2
$ vendor/bin/phpunit
Hasil: Error
InvalidArgumentException: Unable to locate factory with name [default] [App\Task].
Penyebab

Kita belum memiliki model factory untuk model App\Task.

Solusi

Kita belum buat model factory untuk model App\Task.

Membuat Model Factory “App\Task”

$ php artisan make:factory TaskFactory --model=Task

Laravel akan membuat database/factories/TaskFactory.php. Kita edit file tersebut dan tambahkan atribut name dan description untuk model App\Task.

<?php

use Faker\Generator as Faker;

$factory->define(App\Task::class, function (Faker $faker) {
    return [
        'name' => $faker->word,
        'description' => $faker->sentence,
    ];
});

Jalankan PHPUnit.

# 3
$ vendor/bin/phpunit
Hasil: Error
Failed asserting that the page contains the element [a] with the attributes
{"id":"edit_task_1","href":"http:\/\/localhost\/tasks?action=edit&id=1"}.
Please check the content above.
Penyebab

Kita belum membuat link untuk edit masing-masing task.

Solusi

Buka view tasks.index atau file resources/views/tasks/index.blade.php, kita buat link untuk edit masing-masing task.

<!-- resources/views/tasks/index.blade.php -->

        <h2>Tasks</h2>
        <ul class="list-group">
            @foreach ($tasks as $task)
                <li class="list-group-item">
                    <a
                        href="{% raw" >}}{{ url('tasks') }}{% endraw" >}}?action=edit&id={% raw" >}}{{ $task->id }}{% endraw" >}}"
                        id="edit_task_{% raw" >}}{{ $task->id }}{% endraw" >}}"
                        class="pull-right">
                        edit
                    </a>
                    {% raw" >}}{{ $task->name }}{% endraw" >}} <br>
                    {% raw" >}}{{ $task->description }}{% endraw" >}}
                </li>
            @endforeach
        </ul>

Jalankan PHPUnit.

# 4
$ vendor/bin/phpunit

OK (7 tests, 22 assertions)

Sip, sekarang sudah dapat Hijau. Artinya ketiga task yang kita generate dengan model factory tadi sudah muncul pada halaman web, beserta link edit nya masing-masing.

Sekarang coba kita buka aplikasi melalui browser, kita lihat tampilannya setelah ditambahkan link edit seperti ini.

Link Edit Task

Sampai di sini proses TDD kita untuk fitur melihat daftar Task.

Kita lanjut bahas sedikit tentang beberapa method assert yang kita gunakan di atas.

Method “$this->see()”

Method $this->see() adalah method assert browserkit untuk melihat teks pada halaman html. Method ini kita gunakan untuk melihat teks apapun yang kita ingin lihat pada halaman web, baik di dalam tag heading, paragraf, form, label, div, dan lain-lain.

Contoh
$this->see('123');

akan passed jika di dalam halaman terdapat :

<h1>Rp. 123.000</h1>
<p>Testing 123</p>
<span class="badge">Status 123</span>

Method “$this->seeElement()”

Method $this->seeElement() adalah method assert browserkit untuk melihat element pada halaman html. Method ini kita gunakan untuk melihat apakah terdapat elemen tersebut (beserta atributnya) dalam halaman html.

Contoh Passed
$this->seeElement('h1', ['class' => 'page-header', 'id' => 'judul-halaman']);

akan passed jika di dalam halaman terdapat :

<h1 class="page-header" id="judul-halaman">Rp. 123.000</h1>
<h1 class="page-header" id="judul-halaman">Judul Halaman</h1>
$this->seeElement('button', ['class' => 'btn btn-info']);

akan passed jika di dalam halaman terdapat :

<button class="btn btn-info">Submit</h1>
<button class="btn btn-info" id="judul-halaman">Simpan</h1>
Contoh Failed
$this->seeElement('h1', ['class' => 'page-header', 'id' => 'judul-halaman']);

akan failed jika di dalam halaman hanya terdapat :

<h1 class="page-header">Rp. 123.000</h1>
<h1 id="judul-halaman">Judul Halaman</h1>

Oke, mudah-mudahan teman-teman yang mencoba praktek artikel ini mendapatkan hasil yang sesuai dengan proses di atas. Jika menemui kendala atau ada keliru dalam proses di atas, silakan disampaikan melalui komentar.

Selanjutnya kita akan mengerjakan Form Edit Task dari link edit yang sudah dibuat di atas. Terima kasih atas waktunya.