Testing, Debugging, dan Kualitas Kode · 1/7
Kenapa kita testing, dan apa yang dibuktikan test yang baik
Test bukan soal berhati-hati. Test itu soal bisa mengubah kode nanti tanpa rasa takut.
Baca 22 menit
Setelah pelajaran ini kamu bisa
- Menyebutkan apa yang sebenarnya kamu dapat dari sebuah test
- Menjelaskan kenapa test itu soal perubahan, bukan soal kebenaran
- Mengenali test yang tidak mungkin gagal
- Menentukan apa yang layak diuji
Penjelasan yang biasa adalah test menangkap bug. Itu benar dan itu bukan manfaat utamanya. Manfaat utamanya adalah test memungkinkanmu mengubah kode yang tidak sepenuhnya kamu ingat tanpa rasa takut.
Tanpa test, setiap perubahan pada kode yang lebih tua dari sebulan adalah pertaruhan. Kamu membacanya, merasa memahaminya, mengubahnya, lalu baru tahu apakah kamu benar saat seorang pengguna mengadu ke managermu. Dengan test, kamu mengubahnya dan mendapat jawaban dalam dua detik.
Sebuah refactor yang kelihatannya jelas aman. Jalankan dan lihat apa kata test-nya.
Hasil
Tekan Jalankan untuk melihat hasilnya.
Ini jalan di browser kamu, di dalam sandbox. Apa pun yang kamu tulis di sini tidak bisa merusak situs.
Apa yang sebenarnya diberikan test
- Kebebasan melakukan refactor. Ini yang utama. Kamu tidak bisa memperbaiki kode yang kamu takut sentuh.
- Spesifikasi yang tidak bisa usang. Komentar bisa berbohong. Test yang lolos tidak bisa.
- Laporan bug yang tetap terperbaiki. Tulis test yang mereproduksinya, dan ia tidak akan pernah kembali diam-diam.
- Pengembangan lebih cepat, begitu suite-nya ada. Dua detik lebih baik daripada memuat ulang halaman dan mengklik lima layar.
- Tekanan desain. Kode yang sulit diuji biasanya strukturnya buruk, dan kesulitannya itulah tandanya.
Test yang tidak mungkin gagal
Sebuah test layak ada hanya kalau ada perubahan yang masuk akal yang bisa membuatnya gagal. Test yang tidak mungkin gagal lebih buruk daripada tidak ada test: ia butuh waktu untuk dijalankan, butuh diperbarui saat kodenya berubah, dan menciptakan rasa percaya diri yang palsu.
// ❌ Tests the language, not your code.
it("adds numbers", () => {
expect(2 + 2).toBe(4);
});
// ❌ Tests the mock. If getUser is mocked to return Ana, of course it does.
it("gets a user", () => {
vi.mocked(getUser).mockReturnValue({ name: "Ana" });
expect(getUser(1).name).toBe("Ana");
});
// ❌ Restates the implementation. Change the code and change the test to match,
// forever, learning nothing.
it("calls the formatter", () => {
render(<Price cents={1999} />);
expect(formatSpy).toHaveBeenCalledWith(1999);
});
// ✅ Tests a rule that could plausibly break.
it("caps guests at the venue maximum", () => {
const state = reducer(initial, { type: "guest_added", name: "D" });
expect(state.guests).toHaveLength(3);
});
// ✅ Tests the edge case a future refactor would get wrong.
it("returns NULL-safe totals for a venue with no bookings", () => {
expect(totalNights([])).toBe(0);
});Tugas praktik
Pilih test mana pun di proyek ini lalu rusak kode yang dicakupnya — ubah sebuah perbandingan, balik sebuah boolean, hapus sebuah guard. Jalankan bun run test dan baca pesan kegagalannya. Lalu tanyakan apakah pesannya cukup memberitahumu untuk menemukan masalahnya tanpa membuka test-nya. Pesan kegagalan yang baik adalah bagian dari test yang baik.
Hasil yang diharapkan
Kegagalan yang menyebutkan file, baris, dan apa yang diharapkan versus yang diterima.
Cek pemahaman
Pilih jawaban dulu