Seperti yang diperkenalkan dalam Pengertian pengujian,
pengujian dalam JavaScript pada dasarnya hanyalah kode yang telah kami konfirmasi
berhasil dijalankan, yaitu tanpa menampilkan Error
. Namun, salah satu cara
penyederhanaan yang berlebihan adalah dengan tidak mempertimbangkan tempat kita
menjalankan kode, lingkungan pengujian-nya.
Lingkungan pengujian secara luas dapat dianggap sebagai dua komponen: lingkungan runtime yang Anda gunakan untuk menjalankan pengujian (seperti Node, atau browser) serta API yang tersedia untuk Anda.
Lingkungan runtime
Runtime seperti Node, atau alat serupa seperti Deno atau Bun, ditujukan untuk mendukung kode JS sisi server atau tujuan umum. Lingkungannya tidak menyertakan API yang mungkin Anda harapkan di browser, seperti membuat dan menggunakan elemen DOM dan HTML, atau konsep apa pun terkait komponen visual atau target render (yaitu, bukan elemen hanya, tetapi merender elemen tersebut secara visual bersama CSS ke area pandang).
Dengan demikian, runtime tujuan umum ini akan gagal jika Anda mencoba, misalnya,
merender elemen React agar dapat diuji, karena tidak ada objek document
atau
window
yang tersedia.
Di sisi lain, jika Anda menjalankan pengujian di dalam browser, API bawaan yang dapat Anda harapkan dari runtime ini mungkin tidak tersedia tanpa polyfill atau beberapa pekerjaan tambahan. Gotcha yang umum adalah membaca dan menulis file:
tidak mungkin untuk import { fs } from 'node:'fs';
di dalam browser dan
membaca file dengan cara ini sebagai bagian dari pengujian.
Masalah API "web" versus "backend" ini sedikit di luar cakupan pengujian, karena mungkin canggung memiliki codebase dengan bagian server dan klien, tetapi hal ini terkait dengan gagasan penulisan kode yang dapat diuji, yang akan kita lihat kembali selama kursus ini.
Menguji logika bisnis atau algoritma
Beberapa kode Anda tidak memerlukan impor Node atau browser untuk beroperasi, sehingga untuk diuji. Ini adalah hal yang akan kita bahas nanti dalam kursus ini, tetapi menyusun codebase Anda sedemikian rupa sehingga "logika bisnis" murninya terpisah dari rendering atau kode khusus Node dapat mempermudah pengujian.
Untuk contoh singkat, Anda mungkin memiliki fungsi Node yang membaca dan menulis file dari disk, lalu memodifikasinya dalam prosesnya. Dengan memfaktorkan ulang fungsi guna menerima fungsi yang menjalankan baca dan tulis dari disk, berarti Anda membuatnya dapat diuji di mana saja.
Dalam hal ini, Anda dapat menggunakan lingkungan apa pun untuk menguji kode ini, baik dalam runtime sisi server atau browser. Dalam pengujian, Anda dapat menyediakan helper yang
menyimpan file virtual dalam memori atau menampilkan data placeholder. Helper semacam ini
boleh diperkenalkan dalam pengujian, karena tidak penting untuk memeriksa, misalnya, bahwa fs.writeFileSync
berfungsi. Fokus pada kode Anda dan apa yang membuatnya
unik atau berisiko.
Emulasi API browser
Banyak framework pengujian, seperti Vitest, memberi Anda opsi untuk mengemulasi lingkungan API browser tanpa menjalankan browser. Vitest secara internal menggunakan library yang disebut JSDOM. Ini dapat menjadi pilihan yang baik untuk pengujian komponen sederhana dengan overhead penggunaan browser yang tinggi.
Fitur umum dari library emulasi adalah, meskipun library emulasi dapat mengemulasi browser—misalnya, DOM, elemen, dan cookie, library tersebut tidak memiliki komponen visual. Artinya, keduanya akan menyediakan cara penting untuk menggunakan elemen HTML dan primitif lainnya, tetapi Anda tidak dapat merender output ke gambar atau layar, atau memeriksa posisi elemen dalam piksel pada halaman.
Sekali lagi, pilihan ini mungkin sangat cocok untuk pengujian komponen, dengan komponen mewakili elemen React, atau Komponen Web, atau sebagainya. Jenis komponen ini biasanya membuat dan berinteraksi dengan DOM dengan cara yang relatif kecil, dan browser yang diemulasi dapat menyediakan fungsi yang cukup untuk mengonfirmasi komponen berfungsi seperti yang Anda inginkan. Bagian selanjutnya mencakup contoh pengujian komponen React dengan Vitest dan JSDOM.
Mengemulasi browser adalah praktik yang sudah umum. JSDOM dirilis pada tahun 2014, tetapi akan selalu berbeda dengan penggunaan browser sebenarnya. Perbedaan ini bisa terlihat jelas: misalnya, JSDOM tidak menyertakan mesin tata letak, sehingga tidak ada cara untuk memeriksa ukuran elemen atau menguji gestur yang kompleks seperti menggeser. Perbedaannya juga bisa jadi halus dan tidak diketahui. Itulah sebabnya pengujian berbasis JSDOM sebaiknya tetap ringkas, sehingga Anda dapat 'timebox' risiko bahwa perilaku apa pun menyimpang dari yang sebenarnya.
Mengontrol browser sungguhan
Untuk menguji kode Anda sebagaimana pengguna akan mencobanya, menggunakan browser sungguhan adalah pilihan terbaik. Dalam praktiknya, menguji runtime yang mendukung browser akan memulai dan mengontrol instance browser sebenarnya, meskipun runtime tersebut berjalan 'start' di dalam Node.js.
Dengan mengontrol browser sebagai bagian dari pengujian, browser akan terbuka seperti yang dilakukan pengguna, sehingga pengujian Anda dapat mengontrolnya dengan memuat URL, HTML dan JS kustom, atau apa pun yang diperlukan untuk melakukan pengujian. Selanjutnya, Anda dapat menulis kode untuk bertindak sebagai pengguna, misalnya dengan mengontrol mouse atau mengetik input ke dalam kotak input.
Alat modern seperti WebdriverIO atau Web Test Runner dapat mengontrol semua browser utama, dan bahkan menjalankan beberapa instance secara bersamaan. Browser ini dapat berjalan berdekatan dengan runner pengujian (misalnya, di komputer Anda sendiri, atau sebagai bagian dari tindakan CI), atau dialihdayakan ke layanan komersial eksternal yang akan menjalankannya untuk Anda.
Library pengujian yang lebih mapan (termasuk Vitest dan Jest) sering kali memiliki mode browser. Namun, karena asalnya berasal dari Node.js, mode browsernya sering "dipasang" dan tidak memiliki fitur yang berguna. Misalnya, Vitest tidak dapat tiru impor modul di browser, yang merupakan primitif canggih yang kita gunakan dalam contoh di halaman berikutnya.
Dalam praktik
Dengan semakin kompleksnya pengujian, penggunaan browser sungguhan menjadi semakin penting.
- Untuk pengujian yang tidak menggunakan fitur minimal atau tidak menggunakan DOM, bahkan fitur yang tersedia di Node.js dan runtime serupa, seperti
fetch
atauEventTarget
, lingkungannya tidak menjadi masalah. - Untuk pengujian komponen kecil, JSDOM bisa saja cocok.
- Pengujian yang lebih besar—misalnya, pengujian menyeluruh, yang dapat menyimulasikan pengguna yang login dan melakukan tindakan inti—masuk akal untuk berjalan sepenuhnya di browser sungguhan.
Bagian ini terlalu banyak membahas teori dan menyajikan sudut pandang berbeda tentang tempat untuk menjalankan pengujian. Dalam praktiknya, codebase Anda akan sering menggunakan banyak pendekatan berbeda terhadap berbagai jenis pengujian berdasarkan kebutuhan Anda dan apa yang disediakan alat pengujian.
Menguji pemahaman Anda
Fitur browser apa yang *tidak* didukung oleh lapisan emulasi jsdom?
requestAnimationFrame