Kodeloka
  1. Kodeloka
  2. Kelas k6
  3. Materi

Modul 3 · Modul 3 dari 15

Anatomi Skrip & Siklus Hidup (Lifecycle)

Empat tahap eksekusi skrip k6, apa yang boleh dan tidak boleh dilakukan di masing-masing tahap, serta kesalahan fatal yang paling sering terjadi.

Empat Tahap Hidup Sebuah Tes k6

Ini konsep terpenting di k6. Salah menempatkan kode di tahap yang keliru akan membuat tes Anda lambat, boros memori, atau langsung gagal.

anatomi.jsjavascript
// ── 1. INIT ──────────────────────────────────────────────
// Dijalankan SEKALI per VU, sebelum tes mulai.
// Hanya di sini boleh: import, membaca file, mendefinisikan options.
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = { vus: 10, duration: '30s' };

// ── 2. SETUP ─────────────────────────────────────────────
// Dijalankan SEKALI untuk seluruh tes, sebelum VU manapun jalan.
// Nilai kembaliannya dibagikan (di-copy) ke semua VU.
export function setup() {
  const res = http.post('https://api.contoh.id/login', { user: 'admin' });
  return { token: res.json('token') };
}

// ── 3. DEFAULT (VU code) ─────────────────────────────────
// Dijalankan BERULANG-ULANG oleh setiap VU selama tes berlangsung.
// Inilah "satu iterasi" = satu perjalanan pengguna.
export default function (data) {
  const res = http.get('https://api.contoh.id/produk', {
    headers: { Authorization: 'Bearer ' + data.token },
  });
  check(res, { 'status 200': (r) => r.status === 200 });
  sleep(1);
}

// ── 4. TEARDOWN ──────────────────────────────────────────
// Dijalankan SEKALI setelah semua VU selesai. Untuk bersih-bersih.
export function teardown(data) {
  http.del('https://api.contoh.id/sesi/' + data.token);
}

Ringkasan Aturan Main

TahapBerapa Kali JalanBolehDilarang
init1× per VUimport, open(), SharedArray, definisi optionsMengirim HTTP request
setup1× totalLogin, seeding data, menyiapkan state bersamaMengembalikan objek raksasa (di-copy ke tiap VU)
defaultBerkali-kali per VUSemua aksi pengujianopen() membaca file, deklarasi berat
teardown1× totalHapus data uji, tutup sesiMengandalkan variabel dari default
⛔ Larangan keras: memanggil open() di luar init

Fungsi open() untuk membaca file hanya boleh dipanggil di tahap init (level modul, di luar semua fungsi). Memanggilnya di dalam default akan melempar error "open() can only be used in the init context".

Alasannya masuk akal: membaca file dari disk pada setiap iterasi akan mengubah tes beban menjadi tes kecepatan disk Anda sendiri.

Satu Iterasi = Satu Perjalanan Pengguna

Fungsi default mewakili satu putaran penuh perilaku pengguna. Jangan menaruh satu request saja di sana lalu berharap hasilnya realistis. Pengguna nyata tidak memanggil satu endpoint lalu langsung mengulanginya 1.000 kali dalam sedetik.

perjalanan-realistis.jsjavascript
export default function () {
  // Pengguna membuka beranda
  http.get(BASE + '/');
  sleep(randomIntBetween(2, 5));      // membaca isi halaman

  // Mencari produk
  http.get(BASE + '/search?q=sepatu');
  sleep(randomIntBetween(3, 8));      // memilih-milih

  // Melihat detail
  http.get(BASE + '/produk/123');
  sleep(randomIntBetween(5, 10));     // membaca deskripsi

  // Menambahkan ke keranjang
  http.post(BASE + '/keranjang', JSON.stringify({ id: 123 }));
  sleep(2);
}
💡 Kenapa sleep() wajib ada

Jeda ini disebut think time. Tanpanya, 100 VU Anda akan menghasilkan beban setara puluhan ribu pengguna nyata — hasilnya menakutkan tapi tidak menggambarkan apa pun. Sebaliknya, dengan think time yang realistis Anda bisa menjawab pertanyaan bisnis: "sistem kita sanggup melayani berapa pengguna aktif bersamaan?"

Gunakan jeda acak (randomIntBetween), bukan angka tetap, agar request tidak menggumpal di detik yang sama.

Mengenal Konteks Eksekusi

Modul k6/execution memberi tahu skrip Anda "siapa saya dan sedang di iterasi ke berapa" — sangat penting untuk membagi data uji agar tiap VU memakai akun berbeda.

konteks.jsjavascript
import exec from 'k6/execution';

export default function () {
  exec.vu.idInTest;              // nomor VU unik di seluruh tes (mulai dari 1)
  exec.vu.iterationInInstance;   // iterasi ke berapa untuk VU ini
  exec.scenario.iterationInTest; // nomor iterasi global, unik lintas VU
  exec.scenario.name;            // nama skenario yang sedang berjalan
  exec.instance.vusActive;       // jumlah VU aktif saat ini
}