Vitest adalah test runner: program yang mencari file test-mu, menjalankan tiap test di dalamnya, lalu melaporkan mana yang lulus dan mana yang gagal. Bayangin guru yang memeriksa ujian pakai kunci jawaban. Tiap soal dicocokkan dengan kuncinya, yang benar dihitung, lalu nilainya ditulis di pojok kertas. Di Vitest, describe adalah satu bagian ujian (misalnya Matematika), it adalah satu soal, dan expect(...).toBe(...) adalah mencocokkan jawaban dengan kuncinya.
🧪 Tebakan cepat: Dua test memakai variabel
counteryang sama, mulai dari 0. Test pertama memanggilincrement()sekali dan berharapcounterjadi 1. Test kedua memanggilincrement()dua kali dan berharapcounterjadi 2. Test kedua lulus atau gagal? Jawabannya ada di bagian "beforeEach: tiap test mulai dari nol".
Test runner itu sebenarnya sederhana
Sebelum memakai Vitest, lihat dulu apa yang dikerjakannya. Ini test runner buatan sendiri:
function tambah(a, b) {
return a + b;
}
function kali(a, b) {
return a * b;
}
function runTests() {
let passed = 0;
if (tambah(2, 3) === 5) passed++;
if (kali(3, 4) === 12) passed++;
if (tambah(-1, 1) === 0) passed++;
return passed;
}
console.log(runTests()); // 3
- Tiap baris
ifadalah satu pemeriksaan: jalankan fungsinya, bandingkan hasilnya dengan jawaban yang benar. passed++cuma jalan kalau hasilnya cocok, jadipassedmenghitung pemeriksaan yang lulus, bukan yang dijalankan.- Kalau
kalisalah tulis jadia + b,kali(3, 4)hasilnya 7, danrunTests()mengembalikan 2.
Vitest melakukan hal yang sama, plus memberi nama tiap pemeriksaan, menjalankan semua file test, dan menunjukkan persis mana yang gagal.
Pasang dan jalankan Vitest
npm install -D vitest
Vitest mencari file yang namanya berakhiran .test.js atau .spec.js (juga .ts, .jsx, .tsx). Lalu jalankan:
npx vitest: mode watch. Test dijalankan, lalu Vitest menunggu. Tiap kali kamu menyimpan file, test yang terkait dijalankan ulang otomatis. Ini mode default.npx vitest run: jalan sekali lalu selesai. Dipakai di CI (server yang menjalankan test tiap ada push).
Biasanya keduanya ditulis di package.json sebagai "test": "vitest" dan "test:run": "vitest run".
Menulis test pertama
// math.test.js
import { describe, it, expect } from "vitest";
import { tambah, kali } from "./math.js";
describe("math", () => {
it("menjumlahkan dua angka", () => {
expect(tambah(2, 3)).toBe(5);
});
it("mengalikan dua angka", () => {
expect(kali(3, 4)).toBe(12);
});
});
import { describe, it, expect } from "vitest"mengambil fungsi-fungsi test dari Vitest. Di editor latihan, semuanya sudah tersedia tanpa import.describe("math", ...)mengelompokkan test yang berkaitan.it("...", ...)mendefinisikan satu test.test(...)sama persis.expect(kali(3, 4)).toBe(12)memeriksa hasil pemanggilan dengantoBe, yang membandingkan seperti===.
Kalau kali salah tulis jadi a + b, npx vitest run --reporter=verbose (opsi --reporter=verbose menampilkan tiap test, bukan cuma yang gagal) mencetak:
✓ math.test.js > math > menjumlahkan dua angka 1ms
× math.test.js > math > mengalikan dua angka 3ms
→ expected 7 to be 12 // Object.is equality
Test Files 1 failed (1)
Tests 1 failed | 1 passed (2)
Bacanya: expected 7 to be 12 artinya kodemu menghasilkan 7, padahal test-nya berharap 12. Angka pertama selalu hasil kodemu.
beforeEach: tiap test mulai dari nol
let counter = 0;
function increment() {
counter++;
}
describe("increment", () => {
beforeEach(() => {
counter = 0; // jalan sebelum SETIAP test di blok ini
});
it("menaikkan counter satu kali", () => {
increment();
expect(counter).toBe(1);
});
it("mulai dari 0 lagi, bukan lanjut dari test sebelumnya", () => {
increment();
increment();
expect(counter).toBe(2);
});
});
| Saat | Tanpa reset | Dengan beforeEach |
|---|---|---|
| Test 1 mulai | counter 0 |
counter 0 |
| Test 1 selesai | 1, lulus | 1, lulus |
| Test 2 mulai | 1, sisa test 1 | 0, direset |
| Test 2 selesai | 3, gagal: expected 3 to be 2 |
2, lulus |
Tanpa reset, test kedua gagal, karena counter masih membawa angka dari test pertama. Itu jawaban tebakannya.
Ada empat hook (fungsi yang dijalankan Vitest di sekitar test):
beforeEach: sebelum setiap test. Paling sering dipakai untuk menyiapkan keadaan yang bersih.afterEach: setelah setiap test.beforeAll: sekali saja, sebelum semua test di blok itu.afterAll: sekali saja, setelah semua test selesai. Cocok untuk bersih-bersih, misalnyadb.disconnect().
⚠️ Jebakan yang sering ketemu
- Reset pakai
beforeAll. Dia cuma jalan sekali, jadi test kedua tetap melihat sisa test pertama. Untuk reset per test, pakaibeforeEach. - Salah baca pesan error. Di
expected 7 to be 12, 7 adalah hasil kodemu dan 12 adalah harapan test-nya. - Lupa import. Tanpa
import { describe, it, expect } from "vitest"(dan tanpa opsiglobals: truedi config), file-nya gagal sebelum satu test pun jalan:ReferenceError: describe is not defined. - Memeriksa angka yang ditulis langsung. Yang masuk ke
expectharus hasil kodemu:expect(multiply(3, 4))atauexpect(counter), bukanexpect(12).
TL;DR: Vitest adalah test runner: dia menjalankan tiap test di file .test.js dan melaporkan yang lulus dan gagal. describe mengelompokkan, it (atau test) adalah satu test, expect(hasil).toBe(harapan) membandingkan. npx vitest berjalan dalam mode watch, npx vitest run jalan sekali. Di pesan expected 7 to be 12, angka pertama hasil kodemu. beforeEach jalan sebelum setiap test, jadi pakai dia untuk reset keadaan, afterEach setelah setiap test, beforeAll dan afterAll sekali sebelum dan sesudah semuanya.