Ada dua cara untuk menjawab pertanyaan "apakah produk ini berfungsi?"
Cara pertama: buka browser, klik-klik, lihat apakah hasilnya sesuai harapan. Cara kedua: tulis test yang melakukan itu secara otomatis, jalankan setiap kali ada perubahan, dan biarkan sistem yang memberitahu jika ada yang rusak.
Holixora memilih cara kedua untuk semua produknya — dan 559 end-to-end tests yang ada sekarang bukan karena kami obsesi dengan angka, tapi karena ini adalah satu-satunya cara yang masuk akal untuk memastikan kualitas ketika tim kecil membangun tujuh produk secara bersamaan.
Mengapa E2E, Bukan Sekadar Unit Test
Unit test menguji fungsi individual. E2E test menguji alur pengguna secara menyeluruh — dari membuka halaman, mengisi form, klik tombol, sampai melihat hasilnya di database atau UI.
Untuk produk yang menghadap pengguna nyata, perbedaan ini penting. Sebuah fungsi bisa lolos unit test tapi gagal ketika digabungkan dengan komponen lain dalam alur yang nyata. E2E test menangkap kelas error yang tidak terlihat di level unit: integrasi antar komponen, state management, routing, dan interaksi asinkron yang kompleks.
Di Holixora, setiap produk — Mercora, Hanoman, Arjuna, Cakra, Kapital, Orbit — memiliki E2E test yang mencakup alur utamanya. Bukan semua edge case, tapi semua jalur yang dilewati pengguna ketika melakukan pekerjaan nyata dengan sistem.
Yang Kami Pelajari dari Prosesnya
Mocked API adalah trade-off yang sadar
Sebagian besar E2E test kami menggunakan mocked API — request ke backend dicegat dan dibalas dengan data yang sudah ditentukan, bukan dengan backend yang berjalan sungguhan.
Ini trade-off yang disengaja. Test dengan mocked API jalannya lebih cepat, tidak bergantung pada state database, dan tidak terpengaruh oleh perubahan di backend yang sedang dalam pengembangan. Tapi konsekuensinya: test tidak menangkap bug yang muncul dari interaksi nyata antara frontend dan backend.
Solusinya bukan membuang mocked API, tapi jujur tentang batasannya: test dengan mock memverifikasi bahwa frontend berperilaku benar dengan input yang diharapkan. Test integrasi end-to-end dengan backend nyata adalah lapisan terpisah yang dijalankan sebelum deployment produksi.
Test yang rapuh lebih buruk dari tidak ada test
Test yang sering gagal bukan karena ada bug — tapi karena selector yang terlalu spesifik, timing yang tidak stabil, atau asumsi tentang state yang tidak konsisten — adalah beban, bukan aset.
Setiap kali CI merah karena test flaky, tim menghabiskan waktu menginvestigasi hal yang bukan masalah nyata. Lebih buruk lagi, kepercayaan pada sinyal test menurun: ketika test merah sudah tidak lagi menghasilkan respons segera, test yang benar-benar mendeteksi regresi bisa terlewat.
Kami belajar ini dengan cara yang tidak menyenangkan. Beberapa sprint awal dihabiskan membersihkan test suite dari test rapuh yang lebih banyak menambah noise dari pada sinyal. Sekarang ada aturan sederhana: test yang tidak bisa dijalankan secara konsisten dihapus atau diperbaiki sebelum di-merge, bukan diakali dengan retry atau waitForTimeout yang panjang.
Coverage angka bukan ukuran yang berguna
559 bukan angka yang kami kejar. Tidak ada target "kita harus mencapai 500 tests" atau "kita harus punya 80% coverage."
Pertanyaan yang kami tanyakan berbeda: apakah alur utama yang pengguna gunakan setiap hari ter-cover? Apakah ada jalur kritis — pembayaran, pembuatan laporan, autentikasi — yang belum punya test? Jika jawabannya ya, test baru ditulis. Jika tidak, angkanya tidak relevan.
Coverage yang tinggi dari test yang tidak berarti tidak melindungi apa pun. Coverage yang lebih rendah dari test yang tepat sasaran jauh lebih berharga.
Struktur yang Berhasil untuk Kami
Beberapa pola yang konsisten di semua produk Holixora:
Auth via localStorage mock. Semua test E2E mulai dengan menyuntikkan token autentikasi langsung ke localStorage, bukan dengan mengisi form login setiap kali. Ini menghilangkan dependency pada alur login yang lambat dan membuat setiap test lebih fokus pada yang diuji.
Page Object Model. Setiap halaman punya class atau objek yang merepresentasikan selector dan aksi utamanya. Ketika UI berubah, perubahan dilakukan di satu tempat, bukan di setiap test yang menggunakan halaman itu.
Test yang independen. Setiap test bisa dijalankan sendiri tanpa bergantung pada state dari test sebelumnya. Tidak ada test yang harus dijalankan dalam urutan tertentu untuk berhasil.
Deskripsi yang manusiawi. test('should display error when required field is empty') lebih berguna dari test('form-validation-1'). Ketika test gagal, deskripsi yang baik memberikan konteks langsung tanpa harus membaca kode test.
Testing sebagai Dokumentasi
Ada manfaat dari E2E test yang tidak selalu disebut pertama: test yang ditulis dengan baik adalah dokumentasi yang bisa dieksekusi tentang bagaimana sistem seharusnya berperilaku.
Ketika ada pertanyaan tentang apakah alur tertentu didukung, jawabannya bisa dicari di test suite. Ketika ada perubahan requirements, test yang gagal menunjukkan dengan tepat di mana perilaku yang berubah. Dan ketika ada developer baru yang perlu memahami sistem, membaca test memberikan gambaran nyata tentang apa yang sistem lakukan — lebih akurat dari dokumentasi yang bisa menjadi stale.
Untuk Holixora yang membangun dan memelihara tujuh produk dengan tim yang kecil, ini bukan nice-to-have. Ini infrastruktur yang membuat skalabilitas mungkin.
Semua produk Holixora tersedia di holixora.com. Jika Anda membutuhkan sistem perangkat lunak untuk bisnis Anda — dengan standar engineering yang sama — halaman kontak ada di sana.