Lailatul Badriyah

Software QA | API Testing & Performance Testing

Lailatul Badriyah

Berpengalaman dalam pengujian API, uji performa dengan K6 pada 95 API, dan validasi fungsional aplikasi, dengan latar belakang sebagai Application Developer. Terbiasa menyelidiki defect, memvalidasi perilaku API, dan memverifikasi perbaikan bersama tim lintas fungsi. Saat ini mendalami praktik quality assurance yang terstruktur untuk berkarier di bidang QA/QC.

Lihat portfolioEmailLinkedIn

Pendidikan

2021 – 2025

Politeknik Negeri Malang

Sarjana Terapan, Teknik Informatika · IPK 3,95 / 4,00

  • Juri Project Innovation pada MaFIA Inclusive Bootcamp 2025 yang diselenggarakan Universitas Brawijaya
  • Mahasiswa Berprestasi Jurusan Teknologi Informasi 2024 dan 2025
  • HAKI: Greeny, inovasi sistem pintar untuk pertanian perkotaan dengan pendekatan gamifikasi, IoT, dan AR
  • 5 kali juara lomba software development tingkat nasional

Pengalaman Kerja

Mar 2025 – sekarang

Application Developer

PT Intelix Global Crossing, Malang

Testing

  • Menguji performa 95 API dengan k6 (smoke, load, stress, spike, soak).
  • Memakai Postman, Swagger, dan Scalar untuk memeriksa request dan response API serta menyelidiki masalah integrasi.
  • Melakukan functional validation fitur aplikasi CMS dan Scoring selama pengembangan dan penyelesaian issue.
  • Menyelidiki defect, melaporkannya lewat bug-tracking tool dan komunikasi tim, lalu memverifikasi perbaikannya.
Pekerjaan pengembangan (2)
  • Membangun dan mengintegrasikan aplikasi web dengan React.js dan Next.js, memakai ±200 REST API dan ±15 koneksi WebSocket.
  • Bekerja dengan tim lintas fungsi, melakukan code review, dan mengoordinasi tugas anak magang dalam sprint agile.

Jul 2024 – Des 2024

Application Developer (magang)

PT Intelix Global Crossing, Malang

Testing

  • Menyelidiki masalah terkait API saat mengintegrasikan ±95 REST API.
Pekerjaan pengembangan (2)
  • Membangun fitur web dengan React.js, Vite, dan Tailwind CSS.
  • Memimpin tim 3 orang, serta menulis dokumentasi teknis dan panduan pengguna.

Feb 2024 – Jul 2024

Full Stack Developer (magang)

PT Amerta Indah Otsuka, Pasuruan

Testing

  • Melakukan functional testing dan evaluasi pengguna untuk pengenalan gestur, pengambilan foto, dan pembuatan QR code.
Pekerjaan pengembangan (2)
  • Membangun aplikasi photobooth hand gesture dengan Python, Flask, dan computer vision.
  • Ikut memperbaiki UI/UX berdasarkan masukan pengguna. Aplikasi ini dipakai lebih dari 1.000 pengunjung.

Proyek terpilih

Okt 2024 – Mei 2025

Aplikasi Manajemen Proyek berbasis Kanban

PT Intelix Global Crossing

Testing

  • Functional validation dan scenario-based testing untuk manajemen workflow, penugasan, pelaporan, dan monitoring proyek.
  • Mendukung User Acceptance Testing (UAT) dengan hasil evaluasi 96,25% dari 6 responden.
Pekerjaan pengembangan (1)
  • Membangun aplikasinya dengan framework Kanban dan metode Agile Prototyping.

Keahlian

Testing & quality

  • API testing
  • Performance testing
  • Functional validation
  • Defect investigation
  • Bug fix verification
  • UAT

Tools

  • Postman
  • k6
  • Swagger
  • Scalar
  • Newman

Teknis

  • REST API
  • WebSocket
  • JavaScript
  • SQL
  • Git

Portfolio

Pengujian API Restful-Booker

Proyek mandiri untuk latihan: saya menguji Restful-Booker, sebuah API pemesanan hotel publik yang memang disediakan untuk belajar testing. Saya menulis test case, mengotomasinya dengan Postman, mengukur performanya dengan k6, lalu melaporkan bug yang ketemu. Semua angka di bawah dibaca langsung dari repository.

29
test case26 sudah otomatis
41
assertiondi 22 request Postman
7
bug4 di antaranya major
4
run k6smoke, load, dan 2× stress

Temuan

API ini hampir tidak memvalidasi input. Harga negatif, tanggal checkout sebelum checkin, dan nama kosong tetap diterima, dan field wajib yang hilang malah menghasilkan error 500. Sisi baiknya, semua PUT, PATCH, dan DELETE tanpa token ditolak dengan 403. Klik satu bug untuk melihat langkah reproduksinya.

BUG-001Booking menerima totalprice negatifMajor · P1
Severity / PrioritasMajor / P1
StatusTerbuka
Lingkunganhttps://restful-booker.herokuapp.com (demo publik)
Test case terkaitTC-CRT-05

Langkah reproduksi

  1. Kirim:
    POST /booking
    Content-Type: application/json
    Accept: application/json
    
    {
      "firstname": "A", "lastname": "B",
      "totalprice": -100, "depositpaid": true,
      "bookingdates": { "checkin": "2026-11-01", "checkout": "2026-11-02" }
    }
    

Hasil yang diharapkan

400 Bad Request dengan pesan bahwa totalprice harus nol atau lebih besar.

Hasil aktual

200 OK; booking tersimpan dengan "totalprice": -100.

Dampak

Nominal negatif merusak laporan pendapatan dan bisa disalahgunakan untuk membuat kredit atau pengembalian dana.

Saran perbaikan

Validasi totalprice >= 0 saat membuat dan mengubah (POST, PUT, PATCH).

Lihat sumber di GitHub

BUG-002Booking menerima tanggal checkout lebih awal dari checkinMajor · P1
Severity / PrioritasMajor / P1
StatusTerbuka
Lingkunganhttps://restful-booker.herokuapp.com (demo publik)
Test case terkaitTC-CRT-06

Langkah reproduksi

  1. Kirim POST /booking dengan "bookingdates": { "checkin": "2026-11-10", "checkout": "2026-11-01" } dan data lain yang valid.

Hasil yang diharapkan

400 Bad Request: checkout harus setelah checkin.

Hasil aktual

200 OK; booking tersimpan dengan checkout sembilan hari sebelum checkin.

Dampak

Masa menginap yang tidak valid merusak perhitungan ketersediaan kamar dan harga berdasarkan jumlah malam.

Saran perbaikan

Validasi checkout > checkin saat membuat dan mengubah.

Lihat sumber di GitHub

BUG-003Booking menerima firstname kosongMinor · P2

Langkah reproduksi

POST /booking dengan "firstname": "" -> 200 OK, booking tersimpan dengan nama kosong.

BUG-004Harga bukan angka dan format tanggal salah diam-diam rusak (null, 0NaN-aN-aN)Major · P1
Severity / PrioritasMajor / P1
StatusTerbuka
Lingkunganhttps://restful-booker.herokuapp.com (demo publik)
Test case terkaitTC-CRT-08, TC-CRT-09

Langkah reproduksi

Kasus A - tipe data salah

  1. POST /booking dengan "totalprice": "abc" dan data lain yang valid.

Kasus B - format tanggal salah

  1. POST /booking dengan "checkin": "not-a-date" dan data lain yang valid.

Hasil yang diharapkan

400 Bad Request yang menjelaskan field yang tidak valid.

Hasil aktual

Keduanya mengembalikan 200 OK dan datanya rusak tanpa pemberitahuan:

InputNilai yang tersimpan
"totalprice": "abc""totalprice": null
"checkin": "not-a-date""checkin": "0NaN-aN-aN"

Dampak

Data rusak secara diam-diam: pemanggil mengira booking sudah tersimpan dengan benar. Laporan dan logika tanggal di hilir menerima null atau tanggal yang tidak bisa dibaca.

Saran perbaikan

Validasi tipe data dan format tanggal ISO-8601 (YYYY-MM-DD) sebelum menyimpan, lalu kembalikan pesan error per field.

Lihat sumber di GitHub

BUG-005Field wajib yang hilang menyebabkan 500 Internal Server Error, bukan 400Major · P1
Severity / PrioritasMajor / P1
StatusTerbuka
Lingkunganhttps://restful-booker.herokuapp.com (demo publik)
Test case terkaitTC-CRT-03

Langkah reproduksi

  1. Kirim:
    POST /booking
    Content-Type: application/json
    Accept: application/json
    
    { "firstname": "OnlyName" }
    

Hasil yang diharapkan

400 Bad Request yang menyebutkan field wajib yang hilang (lastname, totalprice, depositpaid, bookingdates).

Hasil aktual

500 Internal Server Error dengan body yang generik.

Dampak

Kode 5xx memberi tahu client bahwa server yang gagal, bukan permintaannya yang salah. Ini mengotori monitoring error dan membuat pengguna API tidak punya petunjuk untuk memperbaiki permintaannya.

Saran perbaikan

Validasi body permintaan dan kembalikan 400 beserta rinciannya, bukan membiarkan exception merambat.

Lihat sumber di GitHub

BUG-006Login gagal mengembalikan 200 OK, bukan 401Minor · P2
Severity / PrioritasMinor / P2
StatusTerbuka
Lingkunganhttps://restful-booker.herokuapp.com (demo publik)
Test case terkaitTC-AUTH-02, TC-AUTH-03

Langkah reproduksi

  1. Kirim:
    POST /auth
    Content-Type: application/json
    
    { "username": "admin", "password": "wrong" }
    

Hasil yang diharapkan

401 Unauthorized.

Hasil aktual

200 OK dengan body {"reason":"Bad credentials"} (tanpa token). Body kosong {} menghasilkan perilaku yang sama.

Dampak

Client dan API gateway yang menganggap 2xx sebagai sukses bisa salah menafsirkan login yang gagal. Pemantauan login gagal dan rate limiting yang berbasis status code tidak akan berfungsi.

Saran perbaikan

Kembalikan 401 Unauthorized untuk kredensial yang tidak valid dan 400 untuk permintaan yang formatnya salah.

Lihat sumber di GitHub

BUG-007Status code hapus tidak konsisten: berhasil mengembalikan 201, hapus ulang mengembalikan 405 (seharusnya 204/200 dan 404)Minor · P3

Langkah reproduksi

DELETE /booking/{id} dengan token valid -> 201 Created; permintaan yang sama diulang -> 405 Method Not Allowed.

Desain tes

Saya mulai dari 24 skenario, lalu memecahnya jadi 29 test case. Tiap ID bisa ditelusuri sampai ke Postman, misalnya TC-CRT-01.

LulusGagalObservasi / belum dijalankan
Lihat 24 skenario

TS-AUTH - Autentikasi (POST /auth)

  • TS-AUTH-01 Pengguna dengan kredensial valid menerima token
  • TS-AUTH-02 Pengguna dengan kredensial salah tidak menerima token
  • TS-AUTH-03 Permintaan tanpa kredensial tidak menerima token

TS-CRT - Membuat booking (POST /booking)

  • TS-CRT-01 Booking dengan semua field valid berhasil dibuat dan id dikembalikan
  • TS-CRT-02 Booking tanpa field opsional berhasil dibuat
  • TS-CRT-03 Permintaan dengan field wajib yang hilang ditolak dengan error dari sisi client
  • TS-CRT-04 Nilai field di luar rentang valid (harga negatif, checkout sebelum checkin) ditolak
  • TS-CRT-05 Tipe data yang salah dan format tanggal yang rusak ditolak
  • TS-CRT-06 Teks kosong / sangat panjang / berisi karakter khusus ditangani dengan aman
  • TS-CRT-07 Permintaan ditolak ketika header Accept tidak ada

TS-GET - Membaca booking (GET /booking, GET /booking/{id})

  • TS-GET-01 Booking yang ada bisa diambil berdasarkan id dan sesuai schema
  • TS-GET-02 Id yang tidak ada atau formatnya salah mengembalikan 404
  • TS-GET-03 Daftar booking mengembalikan id
  • TS-GET-04 Daftar bisa difilter berdasarkan nama dan tanggal

TS-UPD - Mengubah booking (PUT, PATCH /booking/{id})

  • TS-UPD-01 Pengguna yang terautentikasi bisa mengganti seluruh isi booking
  • TS-UPD-02 Pengguna yang terautentikasi bisa mengubah sebagian field saja
  • TS-UPD-03 Permintaan tanpa token atau dengan token tidak valid ditolak

TS-DEL - Menghapus booking (DELETE /booking/{id})

  • TS-DEL-01 Pengguna yang terautentikasi bisa menghapus booking, dan booking itu tidak bisa diambil lagi
  • TS-DEL-02 Penghapusan tanpa autentikasi ditolak
  • TS-DEL-03 Menghapus booking yang sudah tidak ada ditangani dengan wajar

TS-E2E - Alur end-to-end

  • TS-E2E-01 Login -> buat booking -> baca -> ubah -> ubah sebagian -> hapus -> pastikan sudah hilang (folder Postman 1-5 dijalankan berurutan)

TS-NFR - Non-fungsional

  • TS-NFR-01 Endpoint utama merespons dalam waktu kurang dari 2 detik untuk satu pengguna
  • TS-NFR-02 Dengan 10 pengguna bersamaan, latensi p95 dan tingkat error tetap dalam threshold
  • TS-NFR-03 Perilaku saat beban dinaikkan melewati tingkat normal (mencari titik jenuh)
Lihat semua 29 test case
29 dari 29
IDJudulTipePrioritasStatusOtomasi
Login dengan kredensial validPositifP1LulusPostman
Login dengan password salahNegatifP1Gagal (sudah diketahui)Postman
Login dengan body kosongNegatifP2Gagal (sudah diketahui)Postman
Membuat booking dengan data validPositifP1LulusPostman
Membuat booking tanpa header AcceptNegatifP3Lulus (perilaku terdokumentasi)Postman
Membuat booking dengan field wajib hilangNegatifP1Gagal (sudah diketahui)Postman
Membuat booking tanpa additionalneeds (opsional)PositifP2LulusPostman
Membuat booking dengan totalprice negatifBatasP1GagalPostman (folder defect)
Membuat booking dengan checkout sebelum checkinBatasP1GagalPostman (folder defect)
Membuat booking dengan firstname kosongBatasP2GagalPostman (folder defect)
Membuat booking dengan totalprice bukan angkaNegatifP1GagalPostman (folder defect)
Membuat booking dengan format tanggal salahNegatifP1GagalPostman (folder defect)
Membuat booking dengan HTML/script di firstnameKeamananP2ObservasiManual
Membuat booking dengan lastname 10.000 karakterBatasP3Belum dijalankanManual
Mengambil booking berdasarkan idPositifP1LulusPostman
Mengambil booking yang tidak adaNegatifP1LulusPostman
Mengambil booking dengan id bukan angkaNegatifP3LulusPostman
Menampilkan daftar semua bookingPositifP1LulusPostman
Memfilter booking berdasarkan firstnamePositifP2LulusPostman
Memfilter booking berdasarkan tanggal checkinPositifP3LulusManual
Update penuh (PUT) dengan token validPositifP1LulusPostman
PUT tanpa tokenKeamananP1LulusPostman
PUT dengan token tidak validKeamananP1LulusPostman
Update sebagian (PATCH)PositifP1LulusPostman
PATCH tanpa tokenKeamananP1LulusPostman
Hapus tanpa tokenKeamananP1LulusPostman
Hapus dengan token validPositifP1Lulus (perilaku terdokumentasi)Postman
Booking yang sudah dihapus tidak bisa diambilPositifP1LulusPostman
Menghapus booking yang sama dua kaliNegatifP2Gagal (sudah diketahui)Postman

Otomasi dan CI

Test case yang bisa diotomasi saya tulis sebagai collection Postman dan dijalankan dengan Newman. Isinya token chaining, validasi JSON schema, dan satu run data-driven dari CSV. Test untuk bug yang sudah diketahui saya pisahkan ke folder sendiri, supaya regression suite tetap hijau. Semuanya berjalan otomatis di GitHub Actions setiap ada push, bersama k6 smoke test (lihat workflow).

Lihat rincian per folder dan perintahnya
FolderRequestAssertion
0. Health12
1. Auth38
2. Booking - Create49
3. Booking - Read511
4. Booking - Update57
5. Booking - Delete44
6. Data-driven - Create booking from CSV12
7. Known defects (expected to fail)66
npm run test:api          # regression suite, laporan HTML
npm run test:api:data     # run data-driven dari CSV
npm run test:api:defects  # known defect, gagal memang disengaja

Performa

Saya menjalankan skrip k6 ber-threshold ke API sungguhan dari satu laptop, jadi angkanya sudah termasuk latensi jaringan sekitar 230 sampai 250 ms. Smoke dan load lulus, sedangkan stress belum bisa disimpulkan (alasannya di bawah grafik). Baca laporan lengkap.

Batang tebal: dari 0 sampai p95. Garis tipis: sampai nilai maksimum. Titik: median. Garis tegak merah: batas p95 untuk run itu. Batang merah: run melewati threshold, bisa karena latensi atau karena persentase request gagal (cek tabel angka).
Lihat tabel angka
RunRequestMedianp95 (batas)MaksGagal (batas)Hasil
Smoke26248 ms258 ms (2.00 s)275 ms0% (1.0%)Lulus
Load1,301256 ms952 ms (1.50 s)1.91 s0% (1.0%)Lulus
Stress, run 11,773263 ms1.06 s (3.00 s)6.37 s6.1% (5.0%)Gagal
Stress, run 22,061262 ms665 ms (3.00 s)1.18 s0% (5.0%)Lulus

Dua run stress memakai pengaturan yang sama tapi hasilnya berbeda: run 1 gagal 6,1% (semuanya di DELETE), run 2 bersih. Karena itu saya belum menyimpulkan batas kapasitasnya. Beban saya batasi 10 VU karena targetnya server publik yang dipakai bersama.

Kontak

Saya terbuka untuk peran QA, QC, dan software tester. Silakan hubungi saya lewat:

Email
lailatulbadriyah654@gmail.com
LinkedIn
linkedin.com/in/lailatulbadriyah
Linktree
linktr.ee/lailaszh
GitHub
github.com/lailatulbadriyah24/qa-portfolio