Menulis skrip k6 pertama secara utuh: struktur dasar dengan import, options, dan export default function, menjalankan request HTTP GET dan POST, memvalidasi respons dengan check, memecah skenario dengan group, lalu membaca output k6 run di terminal.

Di episode 2 kalian telah memegang peta arsitektur k6: engine Go dengan goja, model virtual users dan iterasi, lifecycle init-setup-default-teardown, serta komponen checks, thresholds, dan metrics. Sekarang waktunya mengisi peta itu dengan tulisan tangan sendiri. Episode 3 adalah episode praktek pertama: kita menulis skrip k6 yang benar-benar berjalan, dari nol.
Target episode ini sederhana tapi fundamental: memahami struktur wajib sebuah skrip k6 (import, options, export default function, check), menjalankan request HTTP GET dan POST, memvalidasi respons, menampilkan output ke terminal, dan memakai group() agar skenario yang kompleks tetap mudah dibaca. Di akhir episode, kalian akan menjalankan k6 run script.js sendiri dan membaca outputnya dengan percaya diri.
Setiap skrip k6 memiliki empat bagian standar yang selalu muncul. Bayangkan ini sebagai kerangka tubuh: tanpa salah satu bagian, skrip tidak berfungsi sebagaimana mestinya.
k6/http, check, group, sleep).import http from "k6/http";
import { check } from "k6";
export const options = {
vus: 5,
duration: "10s",
};
export default function () {
const res = http.get("https://test.k6.io");
check(res, { "status is 200": (r) => r.status === 200 });
}Perhatikan dua hal. Pertama, export const options mendefinisikan perilaku load — dalam contoh ini 5 VU selama 10 detik. Kedua, export default function () adalah jantung skrip: fungsi ini dipanggil berulang kali oleh tiap VU, dan di dalamnyalah request serta validasi terjadi. Kode di luar kedua bagian ini hanya berjalan pada fase init (episode 2).
Mari tulis file pertama kalian, smoke-get.js, di direktori latihan:
import http from "k6/http";
import { check } from "k6";
export const options = {
vus: 1,
duration: "5s",
};
export default function () {
const res = http.get("https://test.k6.io");
check(res, {
"status is 200": (r) => r.status === 200,
"body contains welcome": (r) => r.body.includes("Welcome"),
});
}k6 run smoke-get.jsSetelah selesai, terminal akan menampilkan summary — tabel hasil akhir berisi metrik seperti http_req_duration dan http_reqs, plus blok checks yang menunjukkan berapa check lulus dan gagal. Output di bawah ini adalah bentuk yang akan kalian lihat (angka disederhanakan):
Dua bagian yang paling penting untuk episode ini: baris checks: 100.00% yang menunjukkan dua check lulus, dan baris http_reqs: 9 1.8/s yang menunjukkan 9 request berhasil dikirim dalam 5 detik — kira-kira 1,8 request per detik dengan satu VU.
Tip
Gunakan situs latihan resmi k6 seperti https://test.k6.io untuk eksperimen awal. Ia memang disiapkan untuk ini dan tidak akan protes saat dihantam puluhan request. Jangan pernah mulai latihan dengan menghantam API produksi perusahaan — episode 13 akan membahas etika dan keamanan testing secara khusus.
Selanjutnya, request POST yang mengirim data. Inilah bentuk paling dasar interaksi API modern: kirim JSON, terima respons, validasi. Perhatikan tiga hal penting: header Content-Type, body JSON yang diserialisasi dengan JSON.stringify, dan parameter ketiga http.post yang menerima objek params.
import http from "k6/http";
import { check } from "k6";
export default function () {
const payload = JSON.stringify({
name: "Arman",
email: "arman@example.com",
});
const params = {
headers: { "Content-Type": "application/json" },
};
const res = http.post("https://httpbin.test.k6.io/post", payload, params);
check(res, {
"status is 200": (r) => r.status === 200,
"email echo matches": (r) => r.json().json.email === "arman@example.com",
});
}Di sini r.json() mem-parse body respons menjadi objek JavaScript, lalu kita menembus field json yang membungkus payload untuk membaca email. r.json() adalah jembatan antara teks respons dan data terstruktur yang bisa di-assert.
Untuk melihat detail saat skrip berjalan, k6 menyediakan console.log. Sangat berguna saat debugging skrip di awal:
import http from "k6/http";
export default function () {
const res = http.get("https://test.k6.io");
console.log(`Status: ${res.status}`);
console.log(`Durasi: ${res.timings.duration} ms`);
console.log(`Panjang body: ${res.body.length}`);
}Output console.log muncul di terminal saat iterasi berjalan, dengan awalan timestamp. Gunakan hemat: di beban tinggi, ribuan iterasi berarti ribuan baris log yang membanjiri terminal. Untuk debugging ringan, ini alat yang tepat; untuk observasi produksi, serahkan pada metrik (episode 15).
Saat skenario bertumbuh — login, ambil data, lakukan aksi, logout — alur tunggal menjadi sulit dibaca dan hasilnya sulit dianalisis. Di sinilah group() berperan: ia memecah skenario menjadi bagian-bagian yang diberi nama, dan k6 melaporkan durasi setiap bagian secara terpisah di output. Fungsinya seperti bab dalam sebuah buku: struktur naratif yang membuat cerita lebih mudah diikuti.
import http from "k6/http";
import { check, group, sleep } from "k6";
export const options = {
vus: 2,
duration: "10s",
};
export default function () {
group("halaman beranda", () => {
const res = http.get("https://test.k6.io");
check(res, { "beranda 200": (r) => r.status === 200 });
});
group("halaman login", () => {
const res = http.get("https://test.k6.io/login");
check(res, { "login 200": (r) => r.status === 200 });
});
sleep(1);
}Perhatikan sleep(1) di akhir fungsi — k6 memuat 2 VU selama 10 detik, dan setiap iterasi menyisipkan jeda 1 detik agar simulasi lebih realistis. Tanpa jeda, k6 menembak request secepat mungkin; dengan jeda, perilakunya mendekati pengguna sungguhan yang membutuhkan waktu berpikir antar halaman. Ini praktik standar yang membedakan test yang "menghantam" dari test yang "mensimulasikan".
Di output, k6 menampilkan durasi per group dalam blok bernama sesuai nama group kalian — █ halaman beranda dan █ halaman login — lengkap dengan rincian check per bagian. Jika salah satu bagian lebih lambat dari yang lain, angka di blok group menunjukkan persis bagian mana yang menjadi bottleneck — nilai besar dari group() yang sering diremehkan.
export pada options. Jika options tidak di-export, k6 menjalankan test tanpa VU konfigurasi — hasilnya sering membingungkan. Pastikan export const options.export default, k6 menolak menjalankan skrip dengan pesan yang jelas. Nama fungsi harus default.import _ from "lodash" gagal total — k6 bukan Node.js (episode 2). Impor hanya modul k6 dan file lokal.sleep().http_req_duration, http_reqs, dan blok checks setiap kali selesai.Di episode 3 ini kalian telah menulis dan menjalankan skrip k6 pertama:
import, export const options, export default function, dan check.JSON.stringify, mengatur header Content-Type, dan membaca respons dengan r.json().console.log untuk debugging cepat dan hemat penggunaannya.k6 run script.js dan kemampuan membaca summary, blok checks, serta durasi per group.Kalian sekarang menulis skrip yang benar-benar berjalan. Di episode 4 kita menaikkan level dengan fokus penuh pada HTTP API load testing dasar: header autentikasi (bearer token), cookies, parameterisasi request dengan data dinamis, payload JSON, assertion gabungan fungsional dan performa dengan check(), serta pemahaman http.get, http.post, r.json(), dan content-type. Dari skrip yang berjalan, kita menuju skrip yang profesional. Sampai jumpa di episode 4!