Halo semuanya! Kursus
Pengembang JavaScript dimulai Kamis ini. Dalam hal ini, kami memutuskan untuk membagikan terjemahan materi menarik lainnya. Selamat membaca.
Jest selalu menjadi alat pengujian unit saya yang sangat diperlukan. Sangat dapat diandalkan sehingga saya mulai berpikir bahwa saya selalu kurang menggunakannya. Meskipun tes berhasil, lama-kelamaan saya refactored mereka di sana-sini, karena saya tidak tahu bahwa Jest bisa melakukan itu. Setiap kali ini adalah kode baru ketika saya memeriksa dokumentasi Jest.
Jadi, saya akan membagikan beberapa trik Jest favorit saya yang mungkin sudah diketahui oleh beberapa dari Anda karena Anda membaca dokumentasi dan tidak menyukai saya (malu), tetapi saya harap ini membantu mereka yang baru saja menjalankannya dengan cepat !
Omong-omong, saya menggunakan Jest v24.8.0 sebagai bahan referensi, jadi berhati-hatilah, beberapa hal mungkin tidak berfungsi pada versi Jest yang sedang Anda gunakan. Selain itu, contoh-contoh tidak mewakili kode tes yang sebenarnya, ini hanya sebuah demonstrasi.
# 1 .toBe vs .toEqual
Pada awalnya, semua pernyataan ini tampak normal bagi saya:
expect('foo').toEqual('foo') expect(1).toEqual(1) expect(['foo']).toEqual(['foo'])
Berdasarkan penggunaan
chai untuk pernyataan kesetaraan (to.equal), ini wajar saja. Bahkan, Jest tidak akan mengeluh, dan pernyataan ini berlalu seperti biasa.
Namun, Jest memiliki .toBe dan .toEqual. Yang pertama digunakan untuk
menyatakan kesetaraan menggunakan
Object.is , dan yang kedua adalah untuk memberikan perbandingan objek dan array yang mendalam. .toEqual memiliki fallback untuk menggunakan
Object.is jika ternyata Anda tidak memerlukan perbandingan yang mendalam, seperti menyatakan persamaan untuk nilai primitif, yang menjelaskan mengapa contoh sebelumnya berjalan sangat baik.
expect('foo').toBe('foo') expect(1).toBe(1) expect(['foo']).toEqual(['foo'])
Dengan begitu, Anda bisa melewati semua
if-else
di
.toEqual
menggunakan
.toBe
jika Anda sudah tahu nilai apa yang Anda uji.
Kesalahan umum adalah bahwa Anda akan menggunakan
.toBe
untuk menegaskan kesetaraan nilai-nilai primitif.
expect(['foo']).toBe(['foo'])
Jika Anda melihat
kode sumber saat .toBe lumpuh, ia akan mencoba menentukan apakah Anda benar-benar membuat kesalahan ini dengan
memanggil fungsi yang .toEqual gunakan. Ini bisa menjadi hambatan ketika mengoptimalkan tes Anda.
Jika Anda yakin menggunakan nilai primitif, kode Anda dapat ditata ulang untuk tujuan pengoptimalan:
expect(Object.is('foo', 'foo')).toBe(true)
Lebih detail dalam
dokumentasi .
# 2 Perbandingan yang lebih cocok
Secara teknis, Anda dapat menggunakan
.toBe
untuk memvalidasi nilai apa pun. Dengan Jest, Anda dapat secara khusus menggunakan alat perbandingan tertentu untuk membuat tes Anda lebih mudah dibaca (dan dalam beberapa kasus lebih pendek).
Ini hanya beberapa yang saya pilih dari daftar panjang kompiler Jest dalam dokumentasi, Anda dapat melihat sisanya sendiri.
# 3 Pengujian snapshot pada elemen tanpa antarmuka pengguna
Anda mungkin pernah mendengar tentang
pengujian snapshot di Jest , yang membantu melacak perubahan pada elemen antarmuka pengguna Anda. Tetapi pengujian dengan snapshot tidak terbatas pada hal ini.
Pertimbangkan contoh ini:
const allEmployees = getEmployees() const happyEmployees = giveIncrementByPosition(allEmployees) expect(happyEmployees[0].nextMonthPaycheck).toBe(1000) expect(happyEmployees[1].nextMonthPaycheck).toBe(5000) expect(happyEmployees[2].nextMonthPaycheck).toBe(4000)
Akan melelahkan jika Anda mengklaim semakin banyak karyawan. Selain itu, jika ternyata lebih banyak klaim diperlukan untuk setiap karyawan, kalikan jumlah klaim baru dengan jumlah karyawan dan Anda mendapatkan ide.
Dengan pengujian snapshot, semua ini bisa dilakukan hanya seperti ini:
const allEmployees = getEmployees() const happyEmployees = giveIncrementByPosition(allEmployees) expect(happyEmployees).toMatchSnapshot()
Setiap kali regresi terjadi, Anda akan tahu persis pohon mana di simpul yang tidak cocok dengan gambar.
Tetapi kenyamanan ada harganya: metode ini lebih rentan kesalahan. Ada kemungkinan Anda tidak akan tahu bahwa gambar itu sebenarnya salah, dan pada akhirnya Anda akan memotretnya. Jadi periksa ulang snapshot Anda seolah-olah itu adalah kode persetujuan Anda sendiri (karena memang begitu).
Tentu saja, pengujian tidak terbatas pada snapshot. Baca
dokumentasi lengkap.
# 4 deskripsikan. masing-masing dan uji
Pernahkah Anda menulis tes yang agak mirip dengan ini?
describe('When I am a supervisor', () => { test('I should have a supervisor badge', () => { const employee = new Employee({ level: 'supervisor' }) expect(employee.badges).toContain('badge-supervisor') }) test('I should have a supervisor level', () => { const employee = new Employee({ level: 'supervisor' }) expect(employee.level).toBe('supervisor') }) }) describe('When I am a manager', () => { test('I should have a manager badge', () => { const employee = new Employee({ level: 'manager' }) expect(employee.badges).toContain('badge-manager') }) test('I should have a manager level', () => { const employee = new Employee({ level: 'manager' }) expect(employee.level).toBe('manager') }) })
Ini monoton dan rutin, bukan? Bayangkan melakukan ini dengan banyak kasus.
Dengan
description.each
dan
test.each
Anda dapat memampatkan kode sebagai berikut:
const levels = [['manager'], ['supervisor']] const privileges = [['badges', 'toContain', 'badge-'], ['level', 'toBe', '']] describe.each(levels)('When I am a %s', (level) => { test.each(privileges)(`I should have a ${level} %s`, (kind, assert, prefix) => { const employee = new Employee({ level }) expect(employee[kind])[assert](`${prefix}${level}`) }) })
Namun, saya belum menggunakan ini dalam tes saya sendiri, karena saya lebih suka tes saya lebih rinci, tetapi saya hanya berpikir itu akan menjadi trik yang menarik.
Lihat
dokumentasi untuk detail lebih lanjut tentang argumen (spoiler: sintaks tabel benar-benar keren).
# 5 Imitasi tunggal dari fungsi global
Pada titik tertentu, Anda harus menguji sesuatu yang tergantung pada fungsi global dalam kasus uji tertentu. Misalnya, fungsi yang menerima informasi tentang tanggal saat ini menggunakan objek javascript Date, atau perpustakaan yang bergantung padanya. Kesulitannya adalah ketika sampai pada tanggal saat ini, Anda tidak akan pernah bisa mendapatkan pernyataan yang benar.
function foo () { return Date.now() } expect(foo()).toBe(Date.now())
Pada akhirnya, Anda harus mendefinisikan ulang objek Tanggal global agar konsisten dan dapat dikelola:
function foo () { return Date.now() } Date.now = () => 1234567890123 expect(foo()).toBe(1234567890123)
Namun, ini dianggap praktik yang buruk, karena redefinisi dipertahankan antara tes. Anda tidak akan melihat ini jika tidak ada tes lain berdasarkan Date.now, tetapi akan bocor juga.
test('First test', () => { function foo () { return Date.now() Date.now = () => 1234567890123 expect(foo()).toBe(1234567890123)
Saya dulu βmemecahkannyaβ agar tidak bocor:
test('First test', () => { function foo () { return Date.now() const oriDateNow = Date.now Date.now = () => 1234567890123 expect(foo()).toBe(1234567890123)
Namun, ada cara yang jauh lebih baik, lebih sedikit peretas untuk melakukan ini:
test('First test', () => { function foo () { return Date.now() jest.spyOn(Date, 'now').mockImplementationOnce(() => 1234567890123) expect(foo()).toBe(1234567890123)
Dengan demikian,
jest.spyOn
mengikuti objek Date global yang meniru implementasi fungsi now untuk hanya satu panggilan. Ini pada gilirannya akan membuat Date.sekarang utuh untuk sisa tes.
Pasti ada informasi lebih lanjut tentang bertopik di Jest. Lihat
dokumentasi lengkap untuk lebih jelasnya.
Artikel ini sudah cukup lama, jadi saya pikir itu saja untuk saat ini. Ini hanya mempengaruhi sebagian kecil dari kemampuan Jest, dan saya hanya menyoroti favorit saya. Jika Anda memiliki fakta menarik lainnya, beri tahu saya.
Juga, jika Anda sering menggunakan Jest, periksa
Majestic , yang merupakan GUI bebas GUI untuk Jest, alternatif yang sangat bagus untuk keluaran terminal yang membosankan. Saya tidak yakin apakah penulisnya ada di dev.to, tetapi tetap saja menghormati orang ini.
Seperti biasa, terima kasih atas perhatian Anda!
Itu saja. Sampai jumpa di lapangan.