Tentukan hal yang perlu Anda uji dan hal yang dapat Anda hapus.
Artikel sebelumnya membahas dasar-dasar kasus pengujian dan apa yang harus dimuat di dalamnya. Artikel ini membahas lebih dalam pembuatan kasus pengujian dari perspektif teknis, yang menjelaskan apa yang harus disertakan dalam setiap pengujian dan apa yang harus dihindari. Pada dasarnya, Anda akan mempelajari jawaban atas pertanyaan lama "Apa yang harus diuji" atau "Apa yang tidak boleh diuji".
Panduan dan pola umum
Perlu diperhatikan bahwa pola dan poin tertentu sangat penting, terlepas dari apakah Anda melakukan pengujian unit, integrasi, atau menyeluruh. Prinsip-prinsip ini dapat dan harus diterapkan pada kedua jenis pengujian, sehingga merupakan tempat yang baik untuk memulai.
Sederhanakan komunikasi
Dalam hal menulis pengujian, salah satu hal terpenting yang harus diingat adalah membuatnya tetap sederhana. Penting untuk mempertimbangkan kapasitas otak. Kode produksi utama menghabiskan ruang yang signifikan, sehingga hanya menyisakan sedikit ruang untuk kompleksitas tambahan. Hal ini terutama berlaku untuk pengujian.
Jika ruang kepala yang tersedia lebih sedikit, Anda mungkin akan lebih santai dalam upaya pengujian. Itulah sebabnya sangat penting untuk memprioritaskan kesederhanaan dalam pengujian. Faktanya, praktik terbaik pengujian JavaScript Yoni Goldberg menekankan pentingnya Aturan Emas—pengujian Anda harus terasa seperti asisten, bukan seperti formula matematika yang rumit. Dengan kata lain, Anda harus dapat memahami intent pengujian Anda pada pandangan pertama.
Anda harus mengutamakan kesederhanaan dalam semua jenis pengujian, terlepas dari kompleksitasnya. Faktanya, semakin kompleks pengujian, semakin penting untuk menyederhanakannya. Salah satu cara untuk mencapainya adalah melalui desain pengujian datar, dengan pengujian yang dibuat sesederhana mungkin, dan hanya menguji hal yang diperlukan. Artinya, setiap pengujian hanya boleh berisi satu kasus pengujian, dan kasus pengujian harus berfokus pada pengujian satu fungsi atau fitur tertentu.
Pikirkan dari perspektif ini: Anda harus dapat dengan mudah mengidentifikasi apa yang salah saat membaca pengujian yang gagal. Itulah sebabnya penting untuk menjaga pengujian tetap sederhana dan mudah dipahami. Dengan begitu, Anda dapat mengidentifikasi dan memperbaiki masalah dengan cepat saat muncul.
Menguji hal yang layak
Desain pengujian datar juga mendorong fokus dan membantu memastikan pengujian Anda bermakna. Ingat, Anda tidak ingin membuat pengujian hanya demi cakupan—pengujian harus selalu memiliki tujuan.
Jangan menguji detail implementasi
Salah satu masalah umum dalam pengujian adalah pengujian sering kali dirancang untuk menguji detail implementasi, seperti menggunakan pemilih dalam komponen atau pengujian menyeluruh. Detail penerapan mengacu pada hal-hal yang biasanya tidak akan digunakan, dilihat, atau bahkan diketahui oleh pengguna kode Anda. Hal ini dapat menyebabkan dua masalah utama dalam pengujian: negatif palsu dan positif palsu.
Negatif palsu terjadi saat pengujian gagal, meskipun kode yang diuji sudah benar. Hal ini dapat terjadi saat detail implementasi berubah karena pemfaktoran ulang kode aplikasi. Di sisi lain, positif palsu terjadi saat pengujian lulus, meskipun kode yang diuji salah.
Salah satu solusi untuk masalah ini adalah mempertimbangkan berbagai jenis pengguna yang Anda miliki. Pengguna akhir dan developer dapat memiliki pendekatan yang berbeda, dan mereka mungkin berinteraksi dengan kode secara berbeda. Saat merencanakan pengujian, penting untuk mempertimbangkan hal-hal yang akan dilihat atau digunakan pengguna, dan membuat pengujian bergantung pada hal-hal tersebut, bukan detail penerapan.
Misalnya, memilih pemilih yang kurang rentan terhadap perubahan dapat membuat pengujian lebih andal: atribut data, bukan pemilih CSS. Untuk detail selengkapnya, lihat Kent C. artikel Dodds tentang topik ini, atau nantikan artikel tentang topik ini yang akan hadir nanti.
Peniruan: Jangan sampai kehilangan kontrol
Tiruan adalah konsep luas yang digunakan dalam pengujian unit dan terkadang dalam pengujian integrasi. Hal ini melibatkan pembuatan data atau komponen palsu untuk menyimulasikan dependensi yang memiliki kontrol penuh atas aplikasi. Hal ini memungkinkan pengujian terpisah.
Menggunakan tiruan dalam pengujian dapat meningkatkan prediktabilitas, pemisahan masalah, dan performa. Selain itu, jika perlu melakukan pengujian yang memerlukan keterlibatan manusia (seperti verifikasi paspor), Anda harus menyembunyikannya menggunakan tiruan. Karena semua alasan ini, tiruan adalah alat yang berharga untuk dipertimbangkan.
Pada saat yang sama, tiruan dapat memengaruhi akurasi pengujian karena merupakan tiruan, bukan pengalaman pengguna yang sebenarnya. Jadi, Anda perlu berhati-hati saat menggunakan tiruan dan stub.
Haruskah Anda membuat tiruan dalam pengujian menyeluruh?
Secara umum, tidak. Namun, terkadang, pembuatan tiruan dapat menyelamatkan Anda—jadi, jangan anggap remeh pembuatan tiruan.
Bayangkan skenario ini: Anda sedang menulis pengujian untuk fitur yang melibatkan layanan penyedia pembayaran pihak ketiga. Anda berada di lingkungan sandbox yang telah mereka sediakan, yang berarti tidak ada transaksi nyata yang terjadi. Sayangnya, sandbox mengalami kegagalan fungsi, sehingga menyebabkan pengujian Anda gagal. Perbaikan harus dilakukan oleh penyedia pembayaran. Yang dapat Anda lakukan hanyalah menunggu masalah tersebut diselesaikan oleh penyedia.
Dalam hal ini, akan lebih bermanfaat jika Anda mengurangi dependensi pada layanan yang tidak dapat Anda kontrol. Sebaiknya gunakan tiruan dengan hati-hati dalam pengujian integrasi atau menyeluruh karena akan menurunkan tingkat keyakinan pengujian Anda.
Spesifikasi pengujian: Anjuran dan larangan
Jadi, secara keseluruhan, apa yang ada dalam pengujian? Dan apakah ada perbedaan antara jenis pengujian? Mari kita pelajari lebih lanjut beberapa aspek spesifik yang disesuaikan dengan jenis pengujian utama.
Apa yang termasuk dalam pengujian unit yang baik?
Pengujian unit yang ideal dan efektif harus:
- Berkonsentrasilah pada aspek tertentu.
- Beroperasi secara independen.
- Mencakup skenario berskala kecil.
- Gunakan nama deskriptif.
- Ikuti pola AAA jika berlaku.
- Menjamin cakupan pengujian yang komprehensif.
Lakukan ✅ | Jangan ❌ |
---|---|
Buat pengujian sekecil mungkin. Uji satu hal per kasus pengujian. | Menulis pengujian di unit besar. |
Selalu isolasi pengujian dan buat tiruan dari hal-hal yang Anda perlukan yang berada di luar unit. | Sertakan komponen atau layanan lainnya. |
Pastikan pengujian tetap independen. | Mengandalkan pengujian sebelumnya atau membagikan data pengujian. |
Mencakup skenario dan jalur yang berbeda. | Batasi diri Anda untuk melakukan pengujian jalur tanpa error atau pengujian negatif maksimal. |
Gunakan judul pengujian deskriptif, sehingga Anda dapat langsung melihat isi pengujian. | Pengujian hanya berdasarkan nama fungsi, sehingga tidak cukup deskriptif: testBuildFoo() atau testGetId() . |
Usahakan cakupan kode yang baik atau rentang kasus pengujian yang lebih luas, terutama pada tahap ini. | Uji dari setiap class hingga tingkat database (I/O). |
Apa yang termasuk dalam pengujian integrasi yang baik?
Pengujian integrasi yang ideal juga memiliki beberapa kriteria yang sama dengan pengujian unit. Namun, ada beberapa poin tambahan yang perlu Anda pertimbangkan. Pengujian integrasi yang baik harus:
- Simulasikan interaksi antarkomponen.
- Mencakup skenario dunia nyata, dan menggunakan tiruan atau stub.
- Pertimbangkan performa.
Lakukan ✅ | Jangan ❌ |
---|---|
Uji titik integrasi: pastikan setiap unit berfungsi dengan baik saat diintegrasikan satu sama lain. | Menguji setiap unit secara terpisah—itulah tujuan pengujian unit. |
Menguji skenario dunia nyata: menggunakan data pengujian yang berasal dari data dunia nyata. | Menggunakan data pengujian berulang yang dibuat secara otomatis atau data lain yang tidak mencerminkan kasus penggunaan di dunia nyata. |
Gunakan tiruan dan stub untuk dependensi eksternal guna mempertahankan kontrol atas pengujian lengkap Anda. | Membuat dependensi pada layanan pihak ketiga, misalnya, permintaan jaringan ke layanan di luar. |
Gunakan rutinitas pembersihan sebelum dan sesudah setiap pengujian. | Lupa menggunakan tindakan pembersihan di dalam pengujian. Jika tidak, hal ini dapat menyebabkan kegagalan pengujian atau positif palsu, karena kurangnya isolasi pengujian yang tepat. |
Apa yang termasuk dalam pengujian menyeluruh yang baik?
Pengujian menyeluruh yang komprehensif harus:
- Mereplikasi interaksi pengguna.
- Mencakup skenario penting.
- Mencakup beberapa lapisan.
- Mengelola operasi asinkron.
- Verifikasi hasilnya.
- Perhitungkan performa.
Lakukan ✅ | Jangan ❌ |
---|---|
Menggunakan pintasan yang didukung API. Pelajari lebih lanjut. | Gunakan interaksi UI untuk setiap langkah, termasuk hook beforeEach . |
Gunakan rutinitas pembersihan sebelum setiap pengujian. Perhatikan isolasi pengujian lebih cermat daripada yang Anda lakukan dalam pengujian unit dan integrasi karena ada risiko efek samping yang lebih tinggi di sini. | Lupa membersihkan setelah setiap pengujian. Jika Anda tidak membersihkan status, data, atau efek samping yang tersisa, hal tersebut akan memengaruhi pengujian lain yang dijalankan nanti. |
Perlakukan pengujian menyeluruh sebagai pengujian sistem. Artinya, Anda perlu menguji seluruh stack aplikasi. | Menguji setiap unit secara terpisah—itulah tujuan pengujian unit. |
Gunakan tiruan minimal atau tidak sama sekali di dalam pengujian. Pertimbangkan dengan cermat apakah Anda ingin mengejek dependensi eksternal. | Sangat mengandalkan tiruan. |
Pertimbangkan performa dan beban kerja dengan, misalnya, tidak menguji skenario besar secara berlebihan dalam pengujian yang sama. | Mencakup alur kerja yang besar tanpa menggunakan pintasan. |