bab v implementasi automated testing
TRANSCRIPT
25
BAB V
IMPLEMENTASI AUTOMATED TESTING
5.1 Persiapan Automated Testing
Terdapat beberapa persiapan yang dilakukan sebelum memulai pengujian. Proses
pengujian dan integrasi website marketplace Digitaloka dilakukan tim penguji. Proses
pengujian ini bertujuan untuk meminimalisir kesalahan pada sistem khususnya pada kode yang
bersangkutan dengan fitur inti sistem agar kedepannya tidak terjadi kesalahan yang fatal.
Tahapan-tahapan umum yang dilakukan dalam automated testing adalah (Nafies, 2017)
1. Instalasi software testing pada sistem yaitu PHPUnit yang telah terintegrasi dengan
framework laravel yang digunakan untuk pengembangan website.
2. Menulis kode pengujian pada software testing untuk menguji fitur yang telah ditentukan
dan disesuaikan dengan kebutuhan output yang diharapkan.
3. Menjalankan software testing untuk mengetahui apakah fitur lulus pengujian oleh software
testing atau tidak.
4. Jika fitur yang diuji lulus, status hasil pengujian menjadi passed atau “lulus”.
5. Jika fitur yang diuji tidak lulus, maka software testing akan menampilkan pesan kesalahan.
Pada proses pengujian website marketplace Digitaloka, pengembang membuat
rancangan fitur-fitur yang akan dilakukan proses pengujian, setiap fitur dibuat sebuah fungsi-
fungsi pengujian yang digunakan untuk menguji unit atau bagian fungsi terkecil pada fitur
tersebut sebelum dilakukan penulisan kode sistem, pengujian dilakukan sebelum menulis kode
asli dan terus dijalankan dengan menimbang banyak aspek dan kemungkinan kesalahan
sehingga fitur inti sistem dapat berjalan dan mendapatkan status pengujian yang berhasil (OK)
dengan semua kemungkinan yang telah didefinisikan sebelumnya. Berikut merupakan
persiapan sebelum melakukan automated testing sesuai dengan perancangan yang terdapat
pada Bab 3.2.4 pada poin ‘a’ sampai ‘g’.
5.1.1 Pemetaan Fitur untuk Automated Testing
Pemetaan fitur untuk automated testing dilakukan untuk mengelompokkan unit-unit pada
suatu fitur yang akan diuji menggunakan PHPUnit, pengelompokkan dibagi dari fitur lalu
dipecah menjadi sub-fitur, dan dipecah lagi sampai bagian unit yang akan diuji fitur yang diuji
yaitu fitur pencarian. Fitur pencarian merupakan fitur yang berfungsi untuk memudahkan user
dalam menemukan produk/jasa yang di inginkan berdasarkan kata kunci yang user masukkan.
Fitur pencarian mencakup pencarian produk dan penjual menggunakan kata kunci yang
26
dimasukkan oleh pengguna, hasil pencarian menunjukkan bahwa produk atau user yang dicari
berdasarkan kata kunci dan berstatus aktif .
5.1.2 Penentuan Sub-fitur untuk Automated Testing
Setelah mendefinisikan fitur yang akan diuji, langkah selanjutnya adalah menyusun sub-
fitur untuk diurutkan pada saat pengerjaan pengujian, sub-fitur yaitu kumpulan fungsionalitas
yang terdapat pada fitur. Pendefinisian sub-fitur pengujian pada fitur pencarian website
Digitaloka dapat dilihat pada tabel 4.1.
Tabel 5.1 Tabel prioritas sub-fitur
Fitur Sub-fitur Keterangan
Pencarian
Memproses kueri atau
keyword yang dimasukkan oleh user
Sistem dapat memproses kueri, dan
mengeliminasi karakter yang tidak diperlukan.
Pencarian produk yang
berstatus: aktif
Sistem dapat melakukan pencarian
produk yang aktif dan user yang terdaftar berdasarkan kata kunci yang
telah diproses di tahapan pertama,
pencarian dibantu dengan package
TNTsearch.
Pencarian user atau penjual yang berstatus: aktif
Sistem dapat melakukan pencarian
user yang terdaftar berdasarkan kata
kunci yang telah diproses di tahapan pertama, user yang aktif adalah user
yang telah melakukan verifikasi
melalui email dan tidak melakukan pelanggaran yang dapat
dinonaktifkan oleh admin, pencarian
dibantu dengan package TNTsearch.
5.1.3 Pembuatan Kelas untuk Automated Testing
Kelas pengujian atau testcase adalah sebuah kelas pada bahasa pemrograman yang
digunakan untuk menguji sebuah fitur, kelas testcase dibuat untuk mengelompokkan pengujian
sub-sub fitur dari sebuah fitur. Misalnya adalah ketika ingin membuat sebuah kelas pengujian
untuk fitur Pencarian, maka kelas testcase yang dibuat yaitu SearchTest. Di dalam kelas
SearchTest terdapat metode atau procedure pengujian untuk masing-masing sub-fitur dari fitur
Pengujian tersebut. Berikut merupakan langkah untuk membuat kode pengujian. Setiap kelas
pengujian mewakili satu sub-fitur. Pada terminal, buka direktori proyek, kemudian jalankan
pengujian untuk memastikan pengujian yang sudah ada berjalan dengan baik
$ vendor/bin/phpunit
Hasilnya:
27
PHPUnit 7.5.16 by Sebastian Bergmann and contributors.
.. 2 / 2
(100%)
Time: 163 ms, Memory: 20.00 MB
OK (2 tests, 2 assertions)
Pada proyek Laravel, pengujian awal akan menghasilkan 2 passed test. Pengujian di sini yaitu
menjalankan kode sampel pengujian untuk testing.
Selanjutnya adalah membuat kelas pengujian, membuat kelas pengujian pada suatu proyek
Laravel dapat menggunakan perintah artisan, contoh berikut merupakan membuat kelas
pengujian untuk fitur pencarian
$ php artisan make:test SearchTest
Ketika kode sudah dijalankan, maka Laravel akan membuat sebuah file baru bernama
SearchTest.php pada direktori tests/Feature
<?php
namespace Tests\Unit\Search;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use App\Models\Users\Product;
class SearchTest extends TestCase
{
use RefreshDatabase;
/** @test */
public function testExample()
{
$this->assertTrue(true);
}
}
Setelah file terbuat, jalankan lagi pengujian untuk menguji apakah kelas sudah dapat digunakan
$ vendor/bin/phpunit
Hasilnya:
Time: 593 ms, Memory: 26.00 MB
OK (3 tests, 3 assertions)
Terdapat 3 tests dan 3 assertions yang berarti kelas SearchTest sudah dapat digunakan.
class ExampleTest extends TestCase
{
public function setUp(): void
{
parent::setUp();
Eloquent::unguard();
}
public function testBasicTest()
{
$this->assertTrue(true);
}
}
28
Catatan: PHPUnit menggunakan penambahan akhiran atau suffix (test) pada setiap nama kelas
pengujian (TestCase). Tanpa suffix (test), PHPUnit tidak dapat mengenali kelas tersebut
sebagai kelas pengujian.
5.1.4 Pembuatan test method atau procedure untuk tiap sub-fitur
Setelah pendefinisian kelas pengujian selesai, langkah selanjutnya adalah menulis suatu
method atau fungsi pengujian. Method atau fungsi pengujian adalah kumpulan method atau
procedure pada kelas pengujian yang dijalankan oleh PHPUnit. Penulisan test method sesuai
dengan alur seperti berikut:
1. Menentukan kasus yang akan diuji dalam hal ini merupakan sub-fitur.
2. Menentukan test method untuk menentukan kondisi, aksi dan asumsi hasil keluaran dari
suatu sub-fitur dengan urutan:
a. Kondisi atau permisalan
b. Aksi yang dilakukan
c. Asumsi hasil keluaran yang diinginkan
3. Memastikan test method sudah sesuai dengan tugas atau langkah kerja fitur yang akan diuji.
Berikut merupakan contoh penulisan test method untuk fitur pencarian. Daftar test method yang
akan dibuat yaitu
1. Satu test method untuk sub-fitur memproses kueri atau keyword yang dimasukkan oleh user
2. Satu test method untuk sub-fitur pencarian user yang berstatus aktif
Mengedit file kelas tests/Feature/Search/SearchProductTest.php
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
class SearchProductTest extends TestCase
{
/** @test */
public function query_input_must_be_valid()
{
$this->assertTrue(true);
}
/** @test */
public function buyer_can_search_seller_that_active()
{
$this->assertTrue(true);
}
}
Pada kelas SearchProductTest, satu test method mewakili komponen pada sub-fitur:
29
a. query_input_must_be_valid mewakili komponen Memproses kueri atau
keyword yang dimasukkan oleh user.
b. buyer_can_search_seller_that_active mewakili komponen Pencarian
produk yang berstatus: aktif
Selain test method diatas, dapat juga ditambah test method model. Model behaviour adalah
suatu method khusus yang ditambahkan pada kelas Model pada Laravel. Tujuannya yaitu untuk
refactor method di suatu controller, atau membuat source-code lebih “readable”.
Model behavior termasuk pendefinisian relasi antar model (antar tabel) dan atribut model yang
didefinisikan melalui Eloquent Accessor pada Laravel. Berikut merupakan contoh test method
pada kelas pengujian SearchProductTest yang digunakan untuk memastikan jika pada Model
Product terdapat method search
<?php
namespace Tests\Feature;
use Tests\TestCase;
use App\Models\Products;
use Illuminate\Foundation\Testing\RefreshDatabase;
class SearchProductTest extends TestCase
{
/** @test */
public function product_model_have_search_attribute()
{
$products = factory(Products::class)->create();
$this->assertEquals(1, $products->search());
}
}
Syarat penulisan test method yaitu harus berupa public method dan nama method diawali
dengan test atau diberikan anotasi @test sebelum penulisan test method.
Tabel 4.2 merupakan tabel rancangan pendefinisian test method untuk setiap sub-fitur pada
kelas pengujian website Digitaloka
30
Tabel 5.2 Tabel test method
Fitur Kelas Pengujian Test Method
Pencarian SearchTest()
it_creates_products_factory()
it_creates_users_factory()
it_can_process_query_with_non_empty_query()
it_can_process_query_with_empty_query()
product_has_search_method()
user_has_search_method()
it_can_do_product_search_by_name_with_query()
it_can_do_user_search_by_name_with_query()
it_can_do_search_only_on_active_product()
it_can_do_search_only_on_active_user()
it_return_all_products_when_empty_query()
it_return_all_users_when_empty_query()
it_has_paginated_results()
5.1.5 Setup local development environment
Berikut merupakan environment yang digunakan dalam implementasi pengujian website
marketplace Digitaloka.
a. Sistem Operasi: Mac OS X 10.14.6
b. Web server : Nginx/1.15.12
c. Versi PHP : 7.3.5
d. Terminal : Visual Studio Terminal
e. Database : MySQL (Local) & SQLite3 (Testing)
f. Versi Laravel : Laravel Framework 5.8.35
g. Direktori Project : /Users/mymac/Documents/digitaloka
h. Laravel development environment: Laravel Valet
Selanjutnya adalah masuk ke direktori proyek dan memastikan bahwa PHPUnit berjalan
dengan baik dengan menjalankan perintah berikut
31
$ vendor/bin/phpunit
Jika berhasil maka tampilan pada terminal akan terlihat seperti pada Gambar 4.1
Gambar 5.1 Tampilan pengujian dengan PHPUnit
5.1.6 Konfigurasi PHPUnit
Langkah selanjutnya yang harus dilakukan adalah mengkonfigurasi PHPUnit,
konfigurasi PHPUnit dilakukan untuk konfigurasi PHPUnit dilakukan pada file
phpunit.xml. Gambar 4.2 merupakan isi dari file phpunit.xml.
Gambar 5.2 Tampilan konfigurasi PHPUnit
Konfigurasi yang akan diubah yaitu konfigurasi basisdata untuk pengujian. Agar pada
saat pengujian tidak mempengaruhi basisdata pada saat ujicoba manual, basisdata untuk
pengujian harus dipisahkan basisdata untuk local development, basisdata untuk local
development adalah menggunakan MySQL dan di sini untuk pengujian adalah menggunakan
32
SQLite karena database SQLite dapat menjadikan pengujian lebih cepat karena dapat diatur
menggunakan in-memory database. SQLite diatur dalam file phpunit.xml
Untuk mengaturnya dapat dengan membuka file phpunit.xml dan dapat dilihat pada
baris kode berikut
<phpunit>
<!-- ..... -->
<php>
<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
<!-- dua baris di bawah ini adalah pengaturan database -->
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
</php>
</phpunit>
5.1.7 Instalasi phpunit-watcher
Phpunit-watcher merupakan sebuah package Laravel yang berfungsi untuk menjalankan
perintah pengujian automatis pada saat terjadi perubahan pada file kode program yang sedang
dikembangkan, hal ini dapat menghemat waktu dan menjadikan pengujian menjadi lebih
efisien dikarenakan tidak perlu lagi menjalankan perintah vendor/bin/phpunit setiap kali
menjalalankan 1 pengujian. Berikut merupakan perintah untuk memasang phpunit-watcher
composer global require spatie/phpunit-watcher
Setelah berhasil dipasang, selanjutnya menjalankan phpunit-watcher dengan perintah
phpunit-watcher watch
Ketika sudah berjalan maka akan terlihat phpunit-watcher sudah siap memantau setiap
perubahan pada file.
33
Gambar 5.3 Tampilan pengujian dengan PHPUnit-watcher
5.1.8 Implementasi automated testing
Terdapat 5 langkah dalam penerapan automated testing dengan PHPUnit, 5 langkah
tersebut merupakan penerapan konsep Test-Driven Development pada pembuatan website
marketplace Digitaloka, berikut merupakan langkah pengujian sesuai dengan perancangan
yang terdapat pada Bab 3.2.4 pada poin h, i dan j yang akan diimplementasikan pada fitur yang
telah ditentukan sebelumnya
a. Membuat kode pengujian (add test).
b. Menjalankan pengujian dan mendapatkan hasil yang salah / fail (watch test fail).
c. Menuliskan kode fitur sistem (write code).
d. Menjalankan pengujian (run test) sehingga mendapatkan hasil: passed.
e. Memperbaiki / merapihkan kode fitur sistem (refactor)
Berdasarkan konsep tersebut, tahap pertama yang dilakukan yaitu membuat Kode
Pengujian (Failing Test) dilanjutkan tahap ke 2 dan ke 3, dengan melakukan 4 langkah berikut
secara berulang
1. Menjalankan printah vendor/bin/phpunit
2. Pesan error akan muncul
34
3. Menemukan penyebab pesan error
4. Menentukan Solusi
Keempat langkah dilakukan setiap pada saat menemukan error baru yang ditampilkan oleh
PHPUnit.
Contoh penerapan automated testing dengan PHPUnit
Hal pertama yang dilakukan untuk menerapkan pengembangan aplikasi dengan
automated testing yaitu membuat file kelas TestCase, Kelas TestCase adalah kelas pengujian
untuk sebuah fitur yang dibuat untuk mengelompokkan pengujian sub-sub fiturnya (method).
Misalnya jika akan membuat sebuah kelas pengujian untuk fitur Pencarian, maka kelas
TestCase yang dibuat bernama PencarianTest. Di dalam kelas PencarianTest terdapat method-
method pengujian untuk masing-masing sub-fitur dari fitur pencarian tersebut.
1. Membuka direktori proyek
cd /var/www/html/tdd
2. Menjalankan pengujian dan menampilkan hasil sukses
Menjalankan pengujian:
vendor/bin/phpunit
Hasilnya:
Time: 133 ms, Memory: 16.00 MB
OK (2 tests, 2 assertions)
3. Membuat kelas TestCase (SearchTest.php)
Kode untuk membuat kelas TestCase:
php artisan make:test SearchTest
Laravel akan membuat file “SearchTest.php” pada direktori “Tests/Feature”
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
class SearchTest extends TestCase
{
public function testExample()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
4. Menjalankan kembali pengujian dan menampilkan hasil sukses
Menjalankan pengujian:
vendor/bin/phpunit
35
Hasilnya:
Time: 125 ms, Memory: 16.00 MB
OK (3 tests, 3 assertions)
5. Mengedit file TestCase(SearchTest.php) sesuai skenario apa yang ingin diujikan
(membuat failing test) dalam hal ini yaitu membuat sub-fitur untuk memproses kueri
pencarian
public function testProcessQuery() {
//melakukan request ke sebuah URL dengan parameter yaitu kueri pencarian $response = $this->get('/search?q=query');
//assertStatus = hasil yang diharapkan yaitu berupa status OK / 200 $response->assertStatus(200);
}
6. Menjalankan kembali PHPUnit dan melihat pesan kesalahan
Menjalankan pengujian:
vendor/bin/phpunit
Hasilnya:
There was 1 error:
1) Tests\Feature\SearchTest::testProcessQuery
Symfony\Component\HttpKernel\Exception\NotFoundHttpException: GET
http://localhost/search
7. Menemukan penyebab kesalahan
Pada keterangan yang ditampilkan oleh PHPUnit yaitu “Expected status code 200 but
received 404.” Yang berarti belum ada route yang melayani request ke URL “/search”.
8. Menentukan solusi
Solusi dari masalah tersebut adalah membuat route untuk melayani request ke “/search”
pada file “routes/web.php”. Tambahkan route get ke url “/search” dengan controller dan
method yang melayani request tersebut.
<?php
#route/web.php
Route::get('/', function () {
return view('welcome');
});
//Menambahkan route dan actionnya (controller dan method) Route::get('search', 'SearchController@processQuery');
9. Menjalankan kembali PHPUnit dan melihat pesan kesalahan
a. Menjalankan testing dengan PHPUnit:
vendor/bin/phpunit
Hasilnya:
There was 1 error:
1) Tests\Feature\SearchTest::testProcessQuery
36
ReflectionException: Class App\Http\Controllers\SearchController
does not exist
b. Menemukan penyebab kesalahan
Disebutkan bahwa kesalahan terdapa pada controller yang menangani route tidak ada
atau belum dibuat.
c. Menentukan solusi
Solusinya adalah membuat controller SearchController untuk menangani route yang
diminta. Kode untuk membuat controller:
php artisan make:controller SearchController
Laravel akan membuat sebuah controller bernama “SearchController” yang
digunakan untuk menangani request dari route ‘/search’ yang telah dibuat.
10. Menjalankan kembali PHPUnit dan melihat pesan kesalahan
a. Menjalankan testing dengan PHPUnit:
vendor/bin/phpunit
Hasilnya:
There was 1 error:
1) Tests\Feature\SearchTest::testProcessQuery
BadMethodCallException:Method
App\Http\Controllers\SearchController::processQuery does not exist.
b. Menemukan penyebab kesalahan
Penyebab kesalahan yang ditampilkan PHPUnit yaitu belum dibuatnya method
“processQuery” yang digunakan untuk menangani route.
c. Menentukan solusi
Solusinya adalah menambahkan method “processQuery” ke controller
“SearchController”
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class SearchController extends Controller
{
function processQuery(Request $request) {
}
}
11. Menjalankan kembali pengujian hingga mendapat pesan sukses yang artinya kode asli
sistem telah dibuat dan telah diintegrasikan dengan automated testing
Time: 130 ms, Memory: 16.00 MB
37
OK (3 tests, 3 assertions)
Langkah-langkah pengembangan dilakukan secara berulang hingga pengembangan fitur
telah memenuhi kriteria yang diinginkan, hasil akhirnya yaitu fitur yang dikembangakan
dengan automated testing telah terintegrasi dengan pengujian sehingga jika dalam fase
production terdapat kesalahan, maka dapat dideteksi dengan lebih cepat.
5.2 Automated testing fitur pencarian
Automated testing pertama dilakukan pada fitur pencarian. Yang pertama dilakukan
untuk melakukan pengembangan fitur pencarian dengan automated testing adalah membuat
direktori dan file kelas yang digunakan untuk pengujian unit pada fitur pencarian dan jalankan
phpunit-watcher dengan perintah berikut:
phpunit-watcher watch
Selanjutnya yaitu membuat TestCase, berikut adalah perintah yang digunakan untuk membuat
TestCase untuk “SearchTest”:
php artisan make:test Search/SearchTest --unit
Jika sudah dijalankan dan sukses maka akan muncul pesan sukses dan Laravel akan
membuatkan folder serta file kelas pengujian ke dalam proyek website Digitaloka. Pada
automated testing ini, folder diibaratkan sebuah modul, dan kelas pengujian merupakan sebuah
fitur.
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
class SearchTest extends TestCase
{
public function testExample()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
Tahap pertama dalam pengembangan fitur pencarian dengan automated testing yaitu dengan
menyusun skenario fitur pencarian atau bisa juga disebut dengan failing test. Skenario fitur
pencarian yang akan dilakukan yaitu
1. Membuat data palsu untuk produk dan user berisi data dummy.
2. Mengirim kueri dengan melakukan request GET ke URL “/processquery” untuk
melakukan aksi berdasarkan inputan kueri.
38
- Jika kueri kosong maka diarahkan ke halaman pencarian “/search” dengan
menampilkan semua produk dan user
- Jika kueri tidak kosong dan valid maka diarahkan ke halaman “/search” dan mengirim
kueri yang telah divalidasi
3. Mengecek apakah model User dan model Produk terdapat method untuk pencarian yaitu
method ‘search’ yang merupakan method dari Laravel scout yang digunakan untuk
melakukan fungsi pencarian.
4. Membuat dan menguji fungsi pencarian apakah produk dan user dapat dicari
berdasarkan nama produk atau user dalam record database. Pencarian dilakukan pada
controller yang menangani halaman “/search”.
5. Menguji hasil pencarian hanya produk atau user yang aktif dengan melihat kolom status
pada masing-masing tabel yaitu tabel products dan users.
6. Ketika kata kunci atau kueri kosong, hasil pencarian menampilkan seluruh produk dan
user.
7. Memastikan bahwa hasil pencarian berbentuk pagination. Pagination adalah sebuah fitur
yang digunakan untuk membatasi tampilan data agar tidak terlalu panjang dan lebih rapi.
8. Hasil pencarian disimpan dalam variabel berformat objek dengan variabel tambahan
berisi daftar semua kategori, default sorting, termasuk jumlah penjualan dan rata-rata
rating dari produk tersebut, Semua hasil pencarian dan variabel tambahan dikirimkan ke
view.
Berikut merupakan kode pengembangan dan pengujian dalam pembuatan fitur pencarian
berdasarkan skenario yang telah ditentukan
5.2.1 Membuat data dummy
Langkah pertama yang dilakukan berdasarkan skenario adalah membuat data produk dan
user palsu (dummy) dengan Model factory. Model factory adalah fitur dari laravel 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. (Nafies,
2017), factory dilengkapi dengan faker yaitu sebuah package yang dapat menggenerate data
palsu secara otomatis, data yang digenerate dapat berupa teks, number, pekerjaan, deskripsi.
Langkah membuat data dummy dapat dilihat pada urutan sepeti berikut
1. Membuat Factory Users
Berikut merupakan kode untuk membuat factory untuk user.
39
php artisan make:factory UserFactory
Laravel akan membuat file pada direktori “database/factories/UserFactory.php”.
Kemudian mengeditnya menjadi seperti kode berikut
$factory->define(App\Models\Users\User::class, function (Faker
$faker) {
return [
//membuat record pada kolom id menggunakan UUID
'id' => Uuid::generate()->string,
//membuat record pada kolom name
'name' => $faker->name,
//membuat record email yang bersifat unik
'email' => $faker->unique()->safeEmail,
//membuat record untuk penanda user telah terverifikasi
'email_verified_at' => now(),
//membuat record pada kolom password
'password' =>
'$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm',
//membuat record untuk token lupa password
'remember_token' => str_random(10),
];
});
Pembuatan instance tabel dan record palsu dimasukkan dalam fungsi define pada bagian
return dalam bentuk array dengan menyesuaikan nama kolom yang akan dibuat.
2. Menguji Factory Users
Setelah factory user dibuat, selanjutnya menguji apakah factory produk sudah bisa
digunakan yaiu dengan membuat method test bernama it_creates_users_factory() pada file
pengujian SearchTest() dan membuat 3 record berupa user palsu bernama “User Satu”,
“User Dua” dan “User Tiga” dengan bantuan factory yang telah dibuat, fungsi yang
digunakan untuk menguji bahwa produk yang ingin dibuat masuk ke basisdata yaitu
menggunakan fungsi “assertDatabaseHas()”.
public function it_creates_users_factory()
{
//membuat tabel dan record dummy untuk pengujian pada tabel user factory(User::class)->create([
'name' => "User Satu"
]);
factory(User::class)->create([
'name' => "User Dua"
]);
factory(User::class)->create([
'name' => "User Tiga"
]);
//menguji apakah record yang dibuat dalam basisdata dapat dibaca $this->assertDatabaseHas('users', [
'name' => "User Satu"
]);
$this->assertDatabaseHas('users', [
'name' => "User Dua"
]);
40
$this->assertDatabaseHas('users', [
'name' => "User Tiga"
]);
}
Setelah kode pengujian dibuat, selanjutnya yaitu melihat visual studio code terminal untuk
mengetahui hasil pengujian, dan hasilnya adalah berhasil.
Time: 756 ms, Memory: 30.00 MB
OK (5 tests, 9 assertions)
3. Membuat Factory Products
Selanjutnya yaitu membuat tabel palsu untuk produk, berikut merupakan kode untuk
membuat factory untuk produk.
php artisan make:factory ProductFactory
Laravel akan membuat file pada direktori “database/factories/ProductFactory.php”.
Kemudian mengeditnya menjadi seperti kode berikut
$factory->define(Product::class, function (Faker $faker) {
return [
//membuat record pada kolom id menggunakan UUID 'id' => Uuid::generate()->string,
//membuat record pada kolom name 'name' => $faker->name,
//membuat record user yg berisi relasi foreign key ke user yang telah dibuat 'user_id' => function () {
return factory(User::class)->create()->id;
},
//membuat record category yg berisi relasi foreign key ke model factory category 'category_id' => function () {
return factory(Category::class)->create()->id;
},
//membuat record pada kolom price 'price' => 1,
//membuat record slug yang diambil dari nama 'slug' => function (array $post) {
return str_slug($post['name']);
},
//membuat record pada kolom description 'description' => $faker->text,
];
});
Pembuatan instance tabel dan record palsu dimasukkan dalam fungsi define pada bagian
return dalam bentuk array dengan menyesuaikan nama kolom yang akan dibuat.
4. Menguji Factory Products
Setelah factory produk dibuat, selanjutnya menguji apakah factory produk sudah bisa
digunakan yaiu dengan membuat method test bernama
it_creates_products_factory()pada file pengujian SearchTest() dan membuat 3
record berupa produk palsu bernama “Produk Satu”, “Produk Dua” dan “Produk Tiga”
dengan bantuan factory yang telah dibuat, fungsi yang digunakan untuk menguji bahwa
41
produk yang ingin dibuat masuk ke basisdata yaitu menggunakan fungsi
“assertDatabaseHas()”.
class SearchTest extends TestCase
{
use RefreshDatabase;
/** @test */
public function it_creates_products_factory()
{
//membuat tabel dan record dummy untuk pengujian pada tabel produk factory(Product::class)->create([
'name' => "Produk Satu"
]);
factory(Product::class)->create([
'name' => "Produk Dua"
]);
factory(Product::class)->create([
'name' => "Produk Tiga"
]);
//menguji apakah record yang dibuat dalam basisdata dapat dibaca $this->assertDatabaseHas('products', [
'name' => "Produk Satu"
]);
$this->assertDatabaseHas('products', [
'name' => "Produk Dua"
]);
$this->assertDatabaseHas('products', [
'name' => "Produk Tiga"
]);
}
}
5. Menjalankan PHPUnit dan melihat hasil pengujian
a. Menjalankan testing dengan PHPUnit
Selanjutnya yaitu melihat visual studio code terminal untuk mengetahui hasil
pengujian
There was 1 error:
1) Tests\Unit\Search\SearchTest::it_creates_products_factory
InvalidArgumentException: Unable to locate factory with name
[default] [App\Models\Products\Category].
Hasilnya terjadi kesalahan, berdasarkan pesan yang ditampilkan oleh PHPUnit, hasil
kesalahan menunjukkan bahwa factory untuk model category belum dibuat, model
category diperlukan oleh model products sebagai relasi “produk memiliki kategori”.
b. Menentukan solusi untuk memperbaiki kesalahan
Solusinya yaitu membuat model factory untuk category.
php artisan make:factory CategoryFactory
42
Laravel akan membuat file pada direktori“database/factories/CategoryFactory.php”.
Kemudian mengeditnya menjadi seperti kode berikut
$factory->define(Category::class, function (Faker $faker) {
return [
//membuat record pada kolom id menggunakan UUID 'id' => Uuid::generate()->string,
//membuat record pada kolom name dengan nama “category-{nomor random}” 'name' => 'category-'.rand(1,90),
//membuat record slug yang diambil dari nama 'slug' => function (array $post) {
return str_slug($post['name']);
}
];
});
c. Menjalankan kembali PHPUnit dan dan melihat hasil pengujian
OK (5 tests, 9 assertions)
Hasil dari pengujian membuat data dummy untuk user dan produk sukses, tabel dan
record palsu dari produk dan user berhasil dibuat.
5.2.2 Mengirim dan memproses kueri
Langkah selanjunya dalam melakukan pencarian yaitu melakukan request GET dengan
querystring yang berisi kueri pencarian atau kata kunci yang dimasukkan oleh user ke URL
“/processquery?q={kueri}”, nantinya URL ini digunakan untuk memproses kueri pencarian
apakah kueri tersebut kosong atau tidak sebelum dilakukan pemrosesan pada database,
skenarionya adalah jika kueri kosong maka akan dialihkan ke URL “/query?act=all_products”
dengan isi dari hasil pencarian nantinya adalah semua produk dan user, sebaliknya jika kueri
tidak kosong maka dialihkan ke URL “/query?q={kueri}” dan hasilnya adalah produk dengan
kata kunci yang ditentukan. Berikut merupakan langkah pengembangan automated tesing
untuk sub fitur mengirim dan memproses kueri
1. Membua method pengujian
Langkah pengujiannya yang pertama yaitu membuat membuat method test bernama
it_can_process_empty_query()dan
it_can_process_empty_query()pada file pengujian SearchTest().
public function it_can_process_query_with_non_empty_query()
{
//menguji mengirim request dengan kueri "produk satu" $response = $this->json('GET', '/processquery',
['query' => 'produk satu']);
43
//menguji apakah request dialihkan ke halaman "/search?query=produk satu"
dengan respon kode 302 $response
->assertRedirect('/search?query=produk satu');
->assertStatus(302)
}
public function it_can_process_query_with_empty_query()
{
//menguji mengirim request dengan kueri kosong $response = $this->json('GET', '/processquery',
['query' => '']);
//menguji apakah request dialihkan ke halaman "/search?act=all_products" dengan respon kode 302 $response
->assertRedirect
('http://localhost:8000/search?act=all_products');
->assertStatus(302)
}
2. Menjalankan PHPUnit dan melihat hasil pengujian
a. Hasil pengujian dari PHPUnit
There were 2 errors:
1)
Tests\Unit\Search\SearchTest::it_can_process_query_with_non_empty_
query
Symfony\Component\HttpKernel\Exception\NotFoundHttpException:GET
http://localhost:8000/processquery
Hasil pengujian: error.
b. Mencari penyebab kesalahan
Pada keterangan yang ditampilkan oleh PHPUnit yaitu “NotFoundHttpException.”
Yang berarti belum ada route yang melayani request ke URL “/searchquery”.
c. Menentukan solusi untuk memperbaiki kesalahan
Solusi dari masalah tersebut adalah membuat route untuk melayani request ke
“/searchquery” pada file “routes/web.php”. Tambahkan route get ke url
“/processquery” dengan controller dan method yang melayani request tersebut yaitu
‘SearchController’ dan method ‘processquery’.
<?php
#routes/web.php
//Menambahkan route dan actionnya (controller dan method) Route::get('/processquery', 'SearchController@processquery')-
>name('processquery');
3. Menjalankan PHPUnit dan melihat hasil pengujian
44
a. Hasil pengujian dari PHPUnit
There were 2 errors:
1)
Tests\Unit\Search\SearchTest::it_can_process_query_with_non_empty_
query
ReflectionException: Class App\Http\Controllers\SearchController
does not exist
Hasil pengujian: error.
b. Mencari penyebab kesalahan
Pada keterangan yang ditampilkan oleh PHPUnit yaitu “Class
App\Http\Controllers\SearchController does not exist” yang berarti belum ada
controller yang melayani route processquery.
c. Menentukan solusi untuk memperbaiki kesalahan
Solusinya adalah membuat controller “SearchController” untuk melayani route
“processquery”.
php artisan make:controller SearchController
Laravel akan membuat sebuah controller bernama “SearchController” yang
digunakan untuk menangani request dari route ‘/processquery’ yang telah dibuat.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class SearchController extends Controller
{
//
}
4. Menjalankan PHPUnit dan melihat hasil pengujian
a. Hasil pengujian dari PHPUnit
There were 2 errors:
1)
Tests\Unit\Search\SearchTest::it_can_process_query_with_non_empty_
query
BadMethodCallException: Method
App\Http\Controllers\SearchController::processquery does not
exist.
Hasil pengujian: error.
b. Mencari penyebab kesalahan
Pada keterangan yang ditampilkan oleh PHPUnit yaitu “Method
App\Http\Controllers\SearchController::processquery does not exist.” yang berarti
45
belum ada method “proccessquery” pada controller yang digunakan untuk menangani
route.
c. Menentukan solusi untuk memperbaiki kesalahan
Solusinya adalah menambahkan method “processquery” ke controller
“SearchController”.
class SearchController extends Controller
{
public function processquery(Request $request) { }
}
5. Menjalankan PHPUnit dan melihat hasil pengujian
a. Hasil pengujian dari PHPUnit
There were 2 failures:
1)
Tests\Unit\Search\SearchTest::it_can_process_query_with_non_empty_
query
Response status code [200] is not a redirect status code.
Failed asserting that false is true.
Hasil pengujian: error.
b. Mencari penyebab kesalahan
Pada keterangan yang ditampilkan oleh PHPUnit yaitu “Response status code [200]
is not a redirect status code.” yang berarti respon yang diharapkan tidak sesuai atau
halaman tidak beralih ke halaman yang ditentukan.
c. Menentukan solusi untuk memperbaiki kesalahan
Solusinya adalah membuat fungsi percabangan yang menentukan pengalihan halaman
pada controller ‘SearchController’.
public function processquery(Request $request) {
//cek apakah kueri kosong / tidak if(empty($request[‘query’]))
{
//jika kosong alihkan kehalaman "/search?act=all_products" return redirect(url('/search?act=all_products'));
} else {
//jika tidak, alihkan kehalaman "/search?q={kueri}" return redirect(url('/search?query=').$reques[‘query’]);
}
}
6. Menjalankan PHPUnit dan melihat hasil pengujian
Berikut merupakan hasil pengujian dari PHPUnit
Time: 800 ms, Memory: 30.00 MB
OK (7 tests, 15 assertions)
46
Hasil pengujian menunjukkan sukses dan fungsi dapat berjalan sesuai harapan yaitu
halaman sukses dialihkan ke URL “/search” dimana kueri akan diproses pada halaman ini.
5.2.3 Mengecek method untuk pencarian
Pada tahap ini yaitu memulai pengembangan fitur pencarian dengan dilengkapi
automated testing. Langkah pertama yang dilakukan adalah membuat method pengujian
berdasarkan skenario yang akan dilakukan yaitu mengecek apakah method pencarian atau
“search()” tersedia. Method search dipasang pada model “Product” dan model “User”, method
“search()” merupakan method yang diberikan oleh Laravel scout, Laravel scout adalah fitur
fdari laravel yang bertujuan untuk memudahkan dalam melakukan pencarian menggunakan
full-text. Laravel scout membutuhkan driver yang pada kasus ini menggunakan package
TNTSearch untuk keperluan pencarian, method “search” ini nantinya digunakan untuk mencari
produk dan user berdasarkan kata kunci. Penulisan kode dilakukan pada file “SearchTest()”.
Berikut merupakan langkah yang dilakukan untuk menguji method search
1. Membuat method failing test untuk mengecek apakah method search tersedia pada model
User dan Product
/** @test */
public function product_has_search_method() {
}
/** @test */
public function user_has_search_method() {
}
2. Menulis kode pengujian untuk menjalankan skenario bahwa model User dan Product
memiliki method “search” yang merupakan instance dari Laravel scout dengan driver:
TNTSearch.
/** @test */
public function product_has_search_method() {
//membuat instance dari model produk $product = new Product();
//mengecek apakah model prduct memiliki method search yg merupakan instance dari Laravel scout $this->assertInstanceOf('Laravel\Scout\Builder',
$product->search());
}
/** @test */
public function user_has_search_method() {
//membuat instance dari model user $user = new User();
//mengecek apakah model user memiliki method search yg merupakan instance dari Laravel scout $this->assertInstanceOf('Laravel\Scout\Builder', $user->search());
}
3. Menjalankan PHPUnit dan melihat hasil pengujian
47
a. Hasil pengujian dari PHPUnit
There were 2 errors:
1) Tests\Unit\Search\SearchTest::product_has_search_method
BadMethodCallException: Call to undefined method
App\Models\Users\Product::search()
2) Tests\Unit\Search\SearchTest::user_has_search_method
BadMethodCallException: Call to undefined method
App\Models\Users\User::search()
Hasil pengujian: error.
b. Mencari penyebab kesalahan
Pada keterangan yang ditampilkan oleh PHPUnit yaitu “Call to undefined method
App\Models\Users\Product::search().” yang berarti belum ada method “search()”
pada kedua model yang digunakan untuk menangani fungsi pencarian.
c. Menentukan solusi untuk memperbaiki kesalahan
Solusinya adalah memasang Laravel scout. Dengan memasang TNTSearch sebagai
driver untuk pencarian, Laravel scout akan otomatis terpasang atau diaktifkan. Berikut
merupakan kode untuk instalasi TNTSearch melalui Composer:
composer require teamtnt/laravel-scout-tntsearch-driver
Setelah memasang, TNTSearch, selanjutnya adalah mengkonfigurasi TNTSearch agar
dapat digunakan. Konfigrasi TNTSearch dengan menamahkan kode berikut ke .env
SCOUT_DRIVER=tntsearch
Lalu menjalankan perintah:
php artisan vendor:publish
--provider="Laravel\Scout\ScoutServiceProvider"
Dan menambahkan konfigurasi pada file ‘config/scout.php”
'tntsearch' => [
'storage' => storage_path(),
'fuzziness' => env('TNTSEARCH_FUZZINESS', false),
'fuzzy' => [
'prefix_length' => 2,
'max_expansions' => 50,
'distance' => 2
],
'asYouType' => false,
'searchBoolean' => env('TNTSEARCH_BOOLEAN', false),
],
Serta menambahkan kode berikut pada model ’user’ dan ‘produk’
48
use Laravel\Scout\Searchable;
protected $searchable = ['name','description'];
use Searchable;
public $asYouType = true;
public function toSearchableArray()
{
$arr = [
'id' => $this->id,
'name' => $this->name,
'description' => $this->description,
];
return $arr;
}
Dan yang terakhir yaitu mengsingkronisasikan data dengan servis yang digunakan
unuk pencarian
php artisan scout:import App\\Models\\Users\User &&
php artisan scout:import App\\Models\\Users\Product
d. Menjalankan PHPUnit dan melihat hasil pengujian
Berikut merupakan hasil pengujian dari PHPUnit
OK (9 tests, 17 assertions)
Hasil pengujian menunjukkan sukses dan fungsi dapat berjalan sesuai harapan yaitu dapat
mengakses method “search” dari model “user” dan “produk” yang digunakan untuk
pengujian.
5.2.4 Membuat dan menguji fungsi pencarian
Tahap selanjutnya yaitu membuat fungsi untuk pencarian disertai dengan automated
testing. Fitur pencarian akan berada pada URL “/search”. Berikut merupakan langkah dalam
membuat fungsi untuk pencarian.
1. Membuat method failing test untuk membuat fungsi dan menguji bahwa user dapat
mencari produk dan user lain berdasarkan kata kunci, penulisan kode dilakukan pada file
‘SearchTest()’. Pencarian yang diimplementasikan adalah pencarian berdasarkan nama.
/** @test */
public function it_can_do_product_search_by_name_with_query() {
}
/** @test */
public function it_can_do_user_search_by_name_with_query() {
}
2. Menulis kode pengujian untuk menjalankan skenario pencarian menggunakan method
‘search’ yang telah dibuat sebelumnya.
49
Kode pengujian pencarian produk:
/** @test */
public function it_can_do_product_search_by_name_with_query() {
//membuat data produk palsu
factory(Product::class)->create([
'name' => "Contoh Produk Aktif",
'status' => 1
]);
factory(Product::class)->create([
'name' => "Contoh Produk Nonaktif",
'status' => 0
]);
//menguji mengirim request dengan kueri 'contoh produk'
$response = $this->json('GET', '/search',
['query' => 'Contoh Produk']);
//mengambil hasil request untuk dibandingkan
$responsedata = $response->original->getData();
//membuat instance produk
$product = new Product();
//menguji pencarian dengan method 'search'
$search_product = $product->search('Contoh Produk')
->get();
//menguji hasil pencarian apakah sama dengan yang diharapkan pada pengujian
$this->assertEquals($responsedata['searched_products'],
$search_product);
}
Kode pengujian pencarian user:
/** @test */
public function it_can_do_user_search_by_name_with_query() {
//membuat data user palsu
factory(User::class)->create([
'name' => "Contoh User Aktif",
'status' => 1
]);
50
factory(User::class)->create([
'name' => "Contoh User Nonaktif",
'status' => 0
]);
//menguji mengirim request dengan kueri 'contoh produk'
$response = $this->json('GET', '/search',
['query' => 'Contoh User']);
//mengambil hasil request untuk dibandingkan
$responsedata = $response->original->getData();
//membuat instance user
$user = new User();
//menguji pencarian dengan method 'search'
$search_user = $user->search('Contoh User')
->get();
//menguji hasil pencarian apakah sama dengan yang diharapkan pada pengujian
$this->assertEquals($responsedata['searched_users'],
$search_user);
}
Kode pengujian menggunakan fungsi “assertEquals()”, karena akan membandingkan 2
variabel yaitu variabel hasil pengujian dan variabel hasil kode asli.
3. Menjalankan PHPUnit dan melihat hasil pengujian
a. Hasil pengujian dari PHPUnit
1) Tests\Unit\Search\SearchTest::
it_can_do_product_search_by_name_with_query
Symfony\Component\HttpKernel\Exception\NotFoundHttpException:
GET http://localhost:8000/search
2) Tests\Unit\Search\SearchTest::
it_can_do_user_search_by_name_with_query
Symfony\Component\HttpKernel\Exception\NotFoundHttpException:
GET http://localhost:8000/search
Hasil pengujian: error.
b. Mencari penyebab kesalahan
51
Pada keterangan yang ditampilkan oleh PHPUnit yaitu
“NotFoundHttpException:GET http://localhost:8000/search.” Yang berarti belum ada
route yang melayani request ke URL “/search”.
c. Menentukan solusi untuk memperbaiki kesalahan
Solusi dari masalah tersebut adalah membuat route untuk melayani request ke
“/search” pada file “routes/web.php”. Tambahkan route get ke url “/search” dengan
controller dan method yang melayani request tersebut yaitu controller
‘SearchController’ dan method ‘search’.
<?php
#routes/web.php
//Menambahkan route dan actionnya (controller dan method) Route::get('/processquery', 'SearchController@search')-
>name('processquery');
4. Menjalankan PHPUnit dan melihat hasil pengujian
a. Hasil pengujian dari PHPUnit
1) Tests\Unit\Search\SearchTest::
it_can_do_product_search_by_name_with_query
BadMethodCallException: Method
App\Http\Controllers\SearchController::search does not exist.
2) Tests\Unit\Search\SearchTest::
it_can_do_user_search_by_name_with_query
BadMethodCallException: Method
App\Http\Controllers\SearchController::search does not exist.
Hasil pengujian: error.
b. Mencari penyebab kesalahan
Pada keterangan yang ditampilkan oleh PHPUnit yaitu “BadMethodCallException:
Method App\Http\Controllers\SearchController::search does not exist.” yang berarti
belum ada method “search” pada controller yang digunakan untuk menangani route.
c. Menentukan solusi untuk memperbaiki kesalahan
Solusinya adalah menambahkan method “search” ke controller “SearchController”.
class SearchController extends Controller
{
...
public function search(Request $request) {
}
}
5. Menjalankan PHPUnit
a. Hasil pengujian dari PHPUnit
There were 2 failures:
52
1)
Tests\Unit\Search\SearchTest::it_can_do_product_search_by_name_wit
h_query
Error: Call to a member function getData() on null
2)
Tests\Unit\Search\SearchTest::it_can_do_user_search_by_name_with_q
uery
Error: Call to a member function getData() on null
Hasil pengujian: error.
b. Mencari penyebab kesalahan
Pada keterangan yang ditampilkan oleh PHPUnit yaitu “Error: Call to a member
function getData() on null.” yang berarti belum respon dari controller masih kosong
karena controller belum diisi kode apapun.
c. Menentukan solusi untuk memperbaiki kesalahan
Solusinya adalah membuat view dummy yang diisi dengan variabel ‘produk’ dan
‘user’ yang berisi hasil pencariandan kueri pencarian.
public function search(Request $request) {
//mencari produk menggunakan method search $searched_products = Product::search($request['query'])-
>get();
//mencari user menggunakan method search $searched_users = User::search($request['query'])->get();
//view dummy untuk menguji respon dari controller return view('testing')->with([
'users' => $users,
'products' => $products,
'query' => $request['query']
]);}
6. Menjalankan PHPUnit
Berikut merupakan hasil pengujian dari PHPUnit
Time: 1.07 seconds, Memory: 30.00 MB
OK (11 tests, 19 assertions)
Hasilnya adalah sukses. Hasil pencarian yang diharapkan sesuai dengan hasil pencarian
sebenarnya yang didapat dari request ke URL ‘/search’.
5.2.5 Menguji hasil pencarian
Setelah fungsi pencarian berhasil dibuat, selanjutnya adalah menguji hasi pencarian, hasil
yang diharapkan yaitu menampilkan hasil pencarian berupa ‘user’ dan ‘produk’ yang berstatus
aktif. Berikut merupakan langkah untuk menguji hasil pencarian.
53
1. Membuat method failing test untuk membuat fungsi dan menguji bahwa hasil pencarian
harus berupa produk dan user yang aktif, penulisan kode dilakukan pada file
‘SearchTest()’.
/** @test */
public function it_can_do_search_only_on_active_product() {
}
/** @test */
public function it_can_do_search_only_on_active_user() {
}
2. Menulis kode pengujian untuk menjalankan skenario pencarian menggunakan method
‘search’ yang telah dibuat sebelumnya.
Kode pengujian pencarian produk:
/** @test */
public function it_can_do_search_only_on_active_product(){
//membuat data produk palsu factory(Product::class)->create([
'name' => "Contoh Produk Aktif",
'status' => 1
]);
factory(Product::class)->create([
'name' => "Contoh Produk Nonaktif",
'status' => 0
]);
//menguji mengirim request dengan kueri 'contoh produk' $response = $this->json('GET', '/search',
['query' => 'Contoh Produk']);
//mengambil hasil request untuk dibandingkan $responsedata = $response->original->getData();
//membuat instance produk
$product = new Product();
//menguji pencarian dengan method 'search' dan diambil id dari hasil pencarian $search_product = $product->search('Contoh Produk')
->where(‘status’, 1)
->get()->pluck('id');
//menguji hasil pencarian apakah sama dengan yang diharapkan pada pengujian $this->assertEquals($responsedata['active_products'],
$search_product);
}
Kode pengujian pencarian user:
/** @test */
public function it_can_do_user_search_by_name_with_query() {
//membuat data user palsu factory(User::class)->create([
'name' => "Contoh User Aktif",
'status' => 1
]);
factory(User::class)->create([
'name' => "Contoh User Nonaktif",
'status' => 0
54
]);
//menguji mengirim request dengan kueri 'contoh produk' $response = $this->json('GET', '/search',
['query' => 'Contoh User']); //mengambil hasil request untuk dibandingkan $responsedata = $response->original->getData();
//membuat instance user $user = new User();
//menguji pencarian dengan method 'search' dan diambil id dari hasil pencarian $search_user = $user->search('Contoh User')
->where(‘status’, 1)
->get()->pluck(id);
//menguji hasil pencarian apakah sama dengan yang diharapkan pada pengujian $this->assertEquals($responsedata['active_users'],
$search_user);
}
Kode pengujian menggunakan fungsi ‘assertEquals()’, karena akan membandingkan 2
variabel yaitu variabel hasil pengujian dan variabel hasil kode asli.
3. Menjalankan PHPUnit
a. Hasil pengujian dari PHPUnit
1) Tests\Unit\Search\SearchTest::
it_can_do_search_only_on_active_product
ErrorException: Undefined index: active_products.
2)
Tests\Unit\Search\SearchTest::it_can_do_search_only_on_active_user
ErrorException: Undefined index: active_users.
Hasil pengujian: error.
b. Mencari penyebab kesalahan
Pada keterangan yang ditampilkan oleh PHPUnit yaitu “ErrorException: Undefined
index: active_products.” yang berarti belum ada variabel ‘active_products’ dan
‘active_users’ yang akan dimasukkan ke dalam view nantinya.
c. Menentukan solusi untuk memperbaiki kesalahan
Solusinya adalah membuat dan mengisi view dengan variabel ‘active_products’ dan
‘active_users’ yang berisi hasil pencarian.
//mencari produk yang aktif menggunakan method search $active_products = Product::search($request['query'])-
>where('status', 1)->get()->pluck('id');
//mencari user yang aktif menggunakan method search
$active_users = User::search($request['query'])->where('status',
1)->get()->pluck('id');
//view dummy untuk menguji respon dari controller
return view('testing')->with([
'users' => $users,
55
'products' => $products,
'active_products' => $active_products,
'active_users' => $active_users,
'query' => $request['query']
]);
4. Menjalankan PHPUnit dan melihat hasil pengujian
Berikut merupakan hasil pengujian dari PHPUnit
Time: 1.49 seconds, Memory: 32.00 MB
OK (13 tests, 21 assertions)
Hasil pengujian menunjukan jika pengujian sukses dan hasil pencarian merupakan hasil
pencarian yang diharapkan yaitu setiap ‘user’ dan ‘product’ memiliki status aktif.
5.2.6 Menguji hasil pencarian jika masukan kueri kosong
Langkah selanjutnya yaitu menguji jika masukan kueri kosong maka akan menampilkan
semua produk dan semua user. Berikut merupakan langkah yang dilakukan untuk melakukan
pengujian hasil pencarian jika masukan kueri kosong.
1. Membuat method failing test untuk membuat fungsi dan menguji bahwa jika kueri yang
dimasukkan kosong, hasil pencarian akan menampilkan semua produk dan semua user,
penulisan kode dilakukan pada file ‘SearchTest()’.
/** @test */
public function it_return_all_products_when_empty_query()
{
}
/** @test */
public function it_return_all_users_when_empty_query()
{
}
2. Menulis kode pengujian untuk menjalankan skenario pencarian menggunakan method
‘search’ yang telah dibuat sebelumnya.
Kode pengujian pencarian produk:
/** @test */
public function it_return_all_products_when_empty_query()
{
//membuat data produk palsu factory(Product::class)->create([
'name' => "Contoh Produk Aktif",
'status' => 1
]);
factory(Product::class)->create([
'name' => "Contoh Produk Nonaktif",
'status' => 0
]);
//menguji mengirim request dengan kueri kosong $response = $this->json('GET', '/search', ['query' => '']);
//mengambil hasil request untuk dibandingkan
56
$responsedata = $response->original->getData();
//membuat instance produk $product = new Product();
//menguji pencarian dengan method get $search_product = $product->get();
//menguji hasil pencarian $this->assertEquals($responsedata[''searched_products'],
$search_product);
}
Kode pengujian pencarian user:
/** @test */
public function it_return_all_users_when_empty_query()
{
//membuat data user palsu factory(User::class)->create([
'name' => "Contoh User Aktif",
'status' => 1
]);
factory(User::class)->create([
'name' => "Contoh User Nonaktif",
'status' => 0
]);
//menguji mengirim request dengan kueri kosong $response = $this->json('GET', '/search', ['query' => '']);
//mengambil hasil request untuk dibandingkan $responsedata = $response->original->getData();
//membuat instance user $user = new User();
//menguji pencarian dengan method get $search_user = $user->get();
//menguji hasil pencarian $this->assertEquals($responsedata[''searched_users'],
$search_user);
}
Kode pengujian menggunakan fungsi ‘assertSessionHas’, karena nantinya hasil pencarian
disimpan dalam sebuah session bernama searchresults.{hasil pencarian}.
3. Menjalankan PHPUnit
a. Hasil pengujian dari PHPUnit
1)
Tests\Unit\Search\SearchTest::it_return_all_products_when_empty_qu
ery
Failed asserting that two objects are equal.
57
2)
Tests\Unit\Search\SearchTest::it_return_all_users_when_empty_query
Failed asserting that two objects are equal.
Hasil pengujian: error.
b. Mencari penyebab kesalahan
Pada keterangan yang ditampilkan oleh PHPUnit yaitu “Failed asserting that two
objects are equal.” yang berarti hasil pencarian tidak sama dengan hasil yang
diharapkan.
c. Menentukan solusi untuk memperbaiki kesalahan
Solusinya adalah memodifikasi kode pencarian dan membuat percabangan.
if(empty($request['query'])) {
//ketika kueri kosong tampilkan semua produk dan user $searched_products = Product::get();
$searched_users = User::get();
//ketika kueri kosong tampilkan semua produk dan user yang aktif $active_products = Product::where('status', 1)->get()-
>pluck('id');
$active_users = User::where('status', 1)->get()->pluck('id');
} else {
$searched_products = Product::search($request['query'])->get();
$searched_users = User::search($request['query'])->get();
$active_products =
Product::search($request['query'])->where('status', 1)
->get()->pluck('id');
$active_users =
User::search($request['query'])->where('status', 1)
->get()->pluck('id');
}
//view dummy untuk menguji respon dari controller return view('testing')->with([
'users' => $users,
'products' => $products,
'active_users' => $active_users,
'active_products' => $active_products,
'query' => $request['query']
]);
4. Menjalankan PHPUnit dan melihat hasil pengujian
Berikut merupakan hasil pengujian dari PHPUnit
Time: 1.83 seconds, Memory: 32.00 MB
OK (15 tests, 23 assertions)
Hasil pengujian menunjukan jika pengujian sukses dan hasil pencarian merupakan hasil
pencarian yang diharapkan yaitu setiap kueri kosong maka akan menampilkan semua
produk.
58
5.2.7 Menguji hasil pencarian telah menggunakan pagination
Langkah berikutnya yaitu menguji hasil pencarian telah menggunakan pagination,
Pagination adalah sebuah fitur yang digunakan untuk membatasi tampilan data agar tidak
terlalu panjang dan lebih rapi. Berikut merupakan langkah untuk menambah pagination ke hasil
pencarian.
1. Membuat method failing test untuk membuat fungsi dan menguji bahwa hasil pencarian
telah menggunakan pagination, penulisan kode dilakukan pada file ‘SearchTest()’.
public function it_has_paginated_results(){}
2. Menulis kode pengujian untuk menjalankan skenario pencarian
/** @test */
public function it_return_all_products_when_empty_query()
{
//membuat data produk palsu factory(Product::class)->create([
'name' => "Contoh Produk Aktif",
'status' => 1
]);
factory(Product::class)->create([
'name' => "Contoh Produk Nonaktif",
'status' => 0
]);
//menguji mengirim request dengan kueri kosong $response = $this->json('GET', '/search', ['query' => '']);
//mengambil hasil request untuk dibandingkan $responsedata = $response->original->getData();
//membandingkan hasil pencarian apakah memiliki instance pagination atau tidak $this-
>assertInstanceOf('Illuminate\Pagination\LengthAwarePaginator',
$responsedata['searched_products']);
}
Kode pengujian menggunakan fungsi ‘assertInstanceOf()’, karena nantinya hasil
pencarian akan dibandingkan berdasarkan instance kelas yang dimiliki.
3. Menjalankan PHPUnit
a. Berikut merupakan hasil pengujian dari PHPUnit
1) Tests\Unit\Search\SearchTest::it_has_paginated_results
Failed asserting that Illuminate\Database\Eloquent\Collection
Object (...) is an instance of class
"Illuminate\Pagination\LengthAwarePaginator".
Hasil pengujian: error.
b. Mencari penyebab kesalahan
59
Pada keterangan yang ditampilkan oleh PHPUnit yaitu “Failed asserting that
Illuminate\Database\Eloquent\Collection Object (...) is an instance
of class "Illuminate\Pagination\LengthAwarePaginator"."”. Yang berarti
hasil pencarian bukan instance dari Pagination.
c. Menentukan solusi untuk memperbaiki kesalahan
Solusinya adalah memodifikasi kode pencarian dengan mengubahnya ke pagination.
$users = User::whereIn('id', $active_users)->paginate(18);
$products = Product::whereIn('id', $active_products)-
>paginate(18);
//view dummy untuk menguji respon dari controller
return view('testing')->with([
'users' => $users,
'products' => $products,
'active_users' => $active_users,
'active_products' => $active_products,
'searched_users' => $searched_users,
'searched_products' => $searched_products,
'query' => $request['query']
]);
4. Menjalankan PHPUnit dan melihat hasil pengujian
Berikut merupakan hasil pengujian dari PHPUnit
Time: 1.95 seconds, Memory: 32.00 MB
OK (16 tests, 24 assertions)
Hasil pengujian berhasil dan menunjukan jika hasil pencarian merupakan bentuk dari kelas
pagination.
5.2.8 Mengirim hasil pencarian ke view
Langkah terakhir automated testing pada fitur pencarian yaitu mengirim hasil pencarian
ke view untuk ditampilkan pada user dengan mengganti nama view pada bagian view dummy
menjadi halaman view asli Kode untuk mengubah dapat dilihat pada controller
‘SearchController.php’.
//mengubah nama view dummy menjadi ‘page.search.index’ return view('page.search.index')->with([
'users' => $users,
'products' => $products,
'active_users' => $active_users,
'active_products' => $active_products,
'searched_users' => $searched_users,
'searched_products' => $searched_products,
'query' => $request['query'],
//variabel tambahan yang tidak iku diujikan
'req' => $request,
'all_products' => $all_products,
'active_sort_user' => $active_sort_user,
'productCategoryCounter' => $productCategoryCounter,
'productPriceMin' => $productPriceMin,
'productPriceMax' => $productPriceMax,
60
'active_sort' => $active_sort,
'categories' => $categories,
]);
Catatan: Diasumsikan halaman view ‘page.search.index’ telah dikembangkan sehingga seluruh
sumberdaya yang dibutuhkan oleh halaman view didapatkan dari controller ‘SearchController’.
5.3 Pembahasan Automated Testing
Saat skenario pada automated testing fitur pencarian dijalankan satu-persatu per kasus
uji, hasil implementasi pengujian untuk fitur pencarian tercatat menggunakan total 13 kasus uji
(TestCase), 19 statement pengujian dan total waktu yang dibutuhkan adalah sekitar 8046 ms
atau 8 detik, hasil tersebut dapat dilihat pada Tabel 4.3.
Tabel 5.3 Implementasi automated testing pada skenario fitur pencarian
TestCase Test Statement Execution Time
it_creates_products_factory() 3 assertions 767 ms
it_creates_users_factory() 3 assertions 671 ms
it_can_process_query_with_non_empty_query() 2 assertions 540 ms
it_can_process_query_with_empty_query() 2 assertions 545 ms
product_has_search_method() 1 assertion 528 ms
user_has_search_method() 1 assertion 558 ms
it_can_do_product_search_by_name_with_query() 1 assertion 795 ms
it_can_do_user_search_by_name_with_query() 1 assertion 742 ms
it_can_do_search_only_on_active_product() 1 assertion 814 ms
it_can_do_search_only_on_active_user() 1 assertion 727 ms
it_return_all_products_when_empty_query() 1 assertion 695 ms
it_return_all_users_when_empty_query() 1 assertion 664 ms
it_has_paginated_results() 1 assertion 723 ms
Total TestCase: 13 19 assertions 8046 ms
Pada implementasi automated testing pada fitur pencarian yang telah dilakukan di Bab 4.4,
tercatat hasil akhir automated testing pada fitur pencarian setelah seluruh kasus uji dijalankan
adalah:
Time: 1.95 seconds, Memory: 32.00 MB
OK (16 tests, 24 assertions)
Pada bagian waktu, tercatat untuk melakukan implementasi automated testing pada fitur
pencarian yang terdiri dari 16 kasus uji dan 24 statement pengujian hanya membutuhkan 1.95
detik. Lebih cepat jika dibandingkan pengujian secara manual yang telah dilakukan yaitu:
61
- Pengembang membuka browser untuk mensimulasikan mengisi form dengan mengisi data
dengan beberapa kemungkinan “keyword” yang kemungkinan akan mencari dengan lebih
dari 5 form input dan mengirim form pencarian. (estimasi rata-rata waktu setelah
dilakukan pengujian manua: 5 detik)
- Setelah mengerjakan satu fitur, pengembang akan menguji fitur tersebut dalam beberapa
tahap, misalnya: membuka halaman, mengetik keyword pencarian, melakukan submit
form, mengamati hasil pencarian apakah benar atau salah dengan asumsi bahwa sistem
telah melakukan proses pencarian pada database dengan kata kunci yang diinginkan
(estimasi rata-rata waktu setelah dilakukan pengujian manual: 8 detik)
Jika tahapan tersebut dilakukan maka memerlukan waktu sekitar 13 detik.
Ketika aplikasi sudah dilengkapi automated testing, pengembang tidak perlu lagi
mensimulasikan aktifitas tersebut karena semuanya sudah dilakukan dalam proses
pengembangan dengan automated testing. Pengembang menulis skenario rancangan fitur yang
akan dikembangakan dan sekaligus bersamaan dengan menuliskan rancangan skenario
pengujian diawal sebelum implementasi pengembangan aplikasi.
Dibandingkan dengan pengujian tradisional, rancangan dan implementasi pengujian
dilakukan setelah perancangan implementasi pengembangan fitur telah selesai, sehingga ketika
akan menguji suatu fitur, pengembang harus mencoba suatu fitur tersebut berurutan sesuai
skenario secara berulang-ulang secara manual, hal ini berbanding terbalik dengan automated
testing, yaitu ketika skenario pengujian ditulis diawal, maka pengujian dengan automated
testing dapat berjalan lebih cepat karena dibantu dengan bantuan komputer dengan berdasarkan
skenario pengujian yang telah ditentukan.