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.
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 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
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.
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 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....