Iman Sugirman

Laravel Pest Untuk Test Api

20 Juni 2023

Pest adalah framework untuk pengujian dengan fokus pada kesederhanaan terutama untuk framework Laravel. Agar Api yang kita bangun lebih percaya diri untuk di deploy karena sudah di test dengan pengujian menggunakan Pest Framework.

Instalasi Pest di Laravel

Install Pest dengan Dependencies

composer require pestphp/pest --dev --with-all-dependencies

Initialisasi Pest menggunakan --init

./vendor/bin/pest --init

Tambahkan Package pest untuk Laravel

composer require pestphp/pest-plugin-laravel --dev

Jika anda membutuhkan Faker bisa juga diinstall dengan pest dengan cara menambahkan, namun ini adalah hanya alternative saja tidak begitu dibutuhkan nanti karna laravel menggunakan factory

composer require pestphp/pest-plugin-faker --dev

Membuat Model dan Migration Terlebih Dahulu

Membuat model dan migration di laravel

php artisan make:model Product -m

dan akan terbuat 2 file yaitu Model dan Migration sekarang kita edit file Migration :

Schema::create('products', function (Blueprint $table) { $table->id(); $table->string('name'); $table->decimal('weight', 45)->nullable(); $table->string('slug')->unique(); $table->string('sku')->unique(); $table->string('image')->nullable(); $table->decimal('price', 45)->nullable(); $table->decimal('discount', 45)->nullable(); $table->timestamps(); });

Lalu sekarang kita edit model dari Product tersebut

// App\Models\Product.php class Product extends Model { use HasFactory; protected $table = 'products'; protected $fillable = [ 'name', 'weight', 'slug', 'sku', 'image', 'price', 'discount' ]; } // Kode Selanjutnya

Membuat Factory berdasarkan Model

Sebelum membuat test baiknya kita menggunakan factory untuk berinteraksi dengan database, dan masukan perintah :

php artisan make:factory ProductFactory --model=Product

dan Edit file ProductFactory berikut :

public function definition(): array { return [ 'name' => fake()->name(), 'weight' => rand(1000, 10000), 'slug' => Str::slug(fake()->name()), 'sku' => Str::slug(fake()->unique()->name(2)), 'price' => fake()->randomNumber(5, true), 'discount' => rand(1, 20), ]; }

Dan sekarang bisa kita gunakan untuk membuat demo product dummy. Sekarang kita edit phpunit.xml

<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd" bootstrap="vendor/autoload.php" colors="true" > <php> <env name="APP_ENV" value="testing"/> <env name="BCRYPT_ROUNDS" value="4"/> <env name="CACHE_DRIVER" value="array"/> <!-- Tambahkan 2 baris ini --> <env name="DB_CONNECTION" value="sqlite"/> <env name="DB_DATABASE" value=":memory:"/> <!-- Tambahkan 2 baris ini --> <env name="MAIL_MAILER" value="array"/> <env name="QUEUE_CONNECTION" value="sync"/> <env name="SESSION_DRIVER" value="array"/> <env name="TELESCOPE_ENABLED" value="false"/> </php> </phpunit>

Tambahkan file database.sqlite di folder database dan saatnya kita buat Controller untuk interaksi API.

Membuat ProductController

Untuk membuat interaksi API kita harus membuat Controller terlebih dahulu untuk berintegrasi dengan test yang akan kita buat :

php artisan make:controller ProductController

Lalu edit ProductController

public function index(Request $request): JsonResponse { try { // Controller Untuk Query Index } catch (Exception $ex) { // Jika Error } } public function store(Request $request): JsonResponse { try { // Controller Untuk Membuat Data } catch (Exception $ex) { // Jika Error } } public function show($id): JsonResponse { try { // Controller Untuk Menampilkan Data } catch (Exception $ex) { // Jika Error } } public function update(Request $request, $id): JsonResponse { try { // Controller Untuk mengupdate Data Data } catch (Exception $ex) { // Jika Error } } public function delete(Request $request, $id): JsonResponse { try { // Controller Untuk mengupdate Data Data } catch (Exception $ex) { // Jika Error } }

Lalu atur Routenya untuk Api diatas :

Route::get('products', [ProductController::class, 'index']); Route::get('products/{id}', [ProductController::class, 'show']); Route::post('products', [ProductController::class, 'store']); Route::put('products/{id}', [ProductController::class, 'update']); Route::delete('products/{id}', [ProductController::class, 'destroy']);

Lalu sekarang kita buat Testnya untuk Membuat Test :

Saatnya Buat Pest Untuk Test

Saatnya kita buat Pest file dengan memasukan Perintah :

php artisan make:test ProductTest --pest --unit

Lalu edit ProductTest.php seperti ini :

Ini adalah untuk mengetest Bahwa Route /api/products bisa digunakan untuk membuat produk

Expektasi kita response mengembalikan status 200 dan Expektasi di database products ada data seperti variable product

use App\Models\Product; use Illuminate\Foundation\Testing\RefreshDatabase; uses(Tests\TestCase::class, RefreshDatabase::class); it('Can Create Product Data', function () { $product = Product::factory()->raw(); $response = $this->postJson('/api/products', $product); $response->assertStatus(200); $this->assertDatabaseHas('products', $product); });

Dibawah membuat test ketika kita menginput lebih dari 1 atau lebih tepatnya 10 data

use App\Models\Product; use Illuminate\Foundation\Testing\RefreshDatabase; uses(Tests\TestCase::class, RefreshDatabase::class); // Untuk Berinteraksi dengan Database it('Can Create More Product with Count', function () { $product = Product::factory()->count(10)->create(); $results = $this->getJson('/api/products'); expect($results['data'])->toHaveCount(10); });

Ketika Di Query maka akan mengeluarkan data seperti expektasi data yang kita buat dan status 200:

use App\Models\Product; use Illuminate\Foundation\Testing\RefreshDatabase; uses(Tests\TestCase::class, RefreshDatabase::class); // Untuk Berinteraksi dengan Database it('Can Fetch Product Data', function () { $product = Product::factory()->create(); $response = $this->getJson("/api/products/{$post->id}"); $data = [ 'data' => ['id' => $post->id, 'name' => $post->name, 'slug' => $post->slug], ]; $response->assertStatus(200)->assertJson($data); });

Expektasi Kita ketika salah id untuk menemukan produk berdasarkan ID :

use App\Models\Product; use Illuminate\Foundation\Testing\RefreshDatabase; uses(Tests\TestCase::class, RefreshDatabase::class); // Untuk Berinteraksi dengan Database it('Cannot Fetch Product Because Wrong ID', function () { $product = Product::factory()->create(); $wrongId = $product->id.'j3443'; $response = $this->getJson("/api/products/{$wrongId}"); $response->assertStatus(500); });

Expektasi Kita ketika hanya memasukan nama produk saja tidak ada data lain :

use App\Models\Product; use Illuminate\Foundation\Testing\RefreshDatabase; uses(Tests\TestCase::class, RefreshDatabase::class); // Untuk Berinteraksi dengan Database it('Validation Without Product', function () { $response = $this->postJson('/api/products', ['name' => 'Updated Woke']); $response->assertStatus(422); });

Produk Bisa di update dengan data data demo :

use App\Models\Product; use Illuminate\Foundation\Testing\RefreshDatabase; uses(Tests\TestCase::class, RefreshDatabase::class); // Untuk Berinteraksi dengan Database it('Can Update Product', function () { $product = Product::factory()->create(); $updatedpost = ['name' => 'Wakanda', 'slug' => '2834932asd', 'sku' => '2834932asd']; $response = $this->putJson("/api/products/{$product->id}", $updatedpost); expect($response)->assertStatus(200); $this->assertDatabaseHas('products', $updatedpost); });

Expextasi kita bisa menghapus produk

use App\Models\Product; use Illuminate\Foundation\Testing\RefreshDatabase; uses(Tests\TestCase::class, RefreshDatabase::class); // Untuk Berinteraksi dengan Database it('Can Delete Product', function () { $product = Product::factory()->create(); $deleted = $this->deleteJson('/api/products/'.$product->id); expect($deleted)->assertStatus(200); });

Lalu masukan perintah :

./vendor/bin/pest

atau bisa juga dengan memasukan perintah :

php artisan test

maka akan keluar seperti ini :

PASS Tests\Unit\ProductUnitTest ✓ it Can Create Product Data ✓ it Can Create More Product with Count ✓ it Can Fetch Product Data ✓ it Cannot Fetch Product Because Wrong ID ✓ it Validation Without Product ✓ it Can Update Product ✓ it Can Delete Product

Dan test berhasil selanjutnya akan saya share tutorial Github Pipeline untuk test Laravel Api kita.

Terimakasih Happy Coding....