Di beberapa organisasi, tampaknya, bagian dari proses rilis perangkat lunak adalah dengan menggunakan pengujian unit, tetapi pada setiap titik waktu semua tes unit harus lulus. Misalnya mungkin ada beberapa layar yang menunjukkan semua tes unit lulus berwarna hijau - yang seharusnya bagus.
Secara pribadi, saya pikir ini bukan seperti yang seharusnya karena alasan berikut:
Ini mempromosikan gagasan bahwa kode harus sempurna dan tidak ada bug yang seharusnya ada - yang di dunia nyata jelas tidak mungkin untuk program dengan ukuran berapa pun.
Disinsentif untuk memikirkan unit test yang akan gagal. Atau tentu saja muncul dengan unit test yang akan sulit untuk diperbaiki.
Jika pada suatu saat semua tes unit lulus, maka tidak ada gambaran besar dari keadaan perangkat lunak pada suatu titik waktu. Tidak ada roadmap / tujuan.
Ini menghalangi tes unit menulis di muka - sebelum implementasi.
Saya bahkan akan menyarankan bahwa bahkan merilis perangkat lunak dengan tes unit gagal tidak perlu buruk. Setidaknya Anda tahu bahwa beberapa aspek dari perangkat lunak memiliki keterbatasan.
Apakah saya melewatkan sesuatu di sini? Mengapa organisasi mengharapkan semua tes unit lulus? Bukankah ini hidup di dunia mimpi? Dan bukankah itu benar-benar menghalangi pemahaman kode sebenarnya?
sumber
Jawaban:
Pertanyaan ini mengandung beberapa kesalahpahaman IMHO, tetapi yang utama yang ingin saya fokuskan adalah bahwa ia tidak membedakan antara cabang pengembangan lokal, trunk, staging atau rilis cabang.
Di cabang dev setempat, kemungkinan akan mengalami beberapa tes unit yang gagal hampir setiap saat. Dalam bagasi, itu hanya dapat diterima pada tingkat tertentu, tetapi sudah merupakan indikator yang kuat untuk memperbaiki hal-hal secepatnya. Perhatikan bahwa kegagalan unit test di bagasi dapat mengganggu anggota tim lainnya, karena mereka mengharuskan setiap orang untuk memeriksa apakah perubahan terbaru yang menyebabkan kegagalan.
Dalam cabang pementasan atau rilis, tes gagal adalah "peringatan merah", menunjukkan ada yang salah dengan beberapa perubahan, ketika digabungkan dari bagasi ke cabang rilis.
Melepaskan perangkat lunak dengan beberapa bug yang dikenal di bawah tingkat keparahan tertentu tidak selalu buruk. Namun, gangguan yang diketahui ini seharusnya tidak menyebabkan tes unit gagal. Jika tidak, setelah setiap unit tes dijalankan, seseorang harus melihat ke dalam 20 unit test yang gagal dan memeriksa satu per satu apakah kegagalannya dapat diterima atau tidak. Ini menjadi rumit, rawan kesalahan, dan membuang sebagian besar aspek otomatisasi dari tes unit.
Jika Anda benar-benar memiliki tes untuk bug yang dapat diterima dan diketahui, gunakan fitur menonaktifkan / mengabaikan alat pengujian unit Anda (sehingga Anda tidak dijalankan secara default, hanya berdasarkan permintaan). Selain itu, tambahkan tiket prioritas rendah ke pelacak masalah Anda, sehingga masalahnya tidak akan terlupakan.
sumber
Ini adalah baik. Tidak "seharusnya" tentang itu.
Tidak. Ini membuktikan bahwa Anda telah menguji kodenya sebaik yang Anda bisa hingga saat ini. Sangat mungkin bahwa tes Anda tidak mencakup setiap kasus. Jika demikian, kesalahan apa pun pada akhirnya akan muncul dalam laporan bug dan Anda akan menulis tes [gagal] untuk mereproduksi masalah dan kemudian memperbaiki aplikasi sehingga tes lulus.
Tes yang gagal atau negatif memberi batasan tegas pada apa yang akan dan tidak akan diterima aplikasi Anda. Sebagian besar program yang saya tahu akan menolak "tanggal" tanggal 30 Februari. Juga, Pengembang, tipe kreatif kita, tidak ingin mematahkan "bayi mereka". Fokus yang dihasilkan pada kasus "happy-path" mengarah ke aplikasi rapuh yang sering rusak.
Untuk membandingkan pola pikir Pengembang dan Penguji:
Ini adalah perspektif yang sangat berbeda dan sulit bagi banyak Pengembang untuk melakukan rekonsiliasi.
Anda tidak menulis tes untuk bekerja sendiri. Anda menulis tes untuk memastikan bahwa kode Anda melakukan apa yang seharusnya dilakukan dan, yang lebih penting, bahwa itu terus melakukan apa yang seharusnya dilakukan setelah Anda mengubah implementasi internalnya.
Satu-satunya "gambar" pengujian memberi Anda adalah snapshot bahwa kode "bekerja" pada titik waktu itu diuji. Bagaimana itu berkembang setelah itu adalah cerita yang berbeda.
Itulah yang seharusnya Anda lakukan. Tulis tes yang gagal (karena metode pengujiannya belum diimplementasikan) kemudian tulis kode metode untuk membuat metode ini bekerja dan, karenanya, lulus uji. Itulah inti dari Pengembangan Berbasis Tes.
Melepaskan kode dengan tes yang rusak berarti bahwa beberapa bagian dari fungsinya tidak lagi berfungsi seperti sebelumnya. Itu mungkin tindakan yang disengaja karena Anda telah memperbaiki bug atau meningkatkan fitur (tetapi kemudian Anda harus mengubah tes terlebih dahulu sehingga gagal, lalu mengkodekan perbaikan / peningkatan, membuat tes bekerja dalam proses). Lebih penting lagi: kita semua adalah Manusia dan kita membuat kesalahan. Jika Anda memecahkan kode, maka Anda harus memecahkan tes dan tes yang rusak harus mengatur bel alarm berbunyi.
Jika ada, itu hidup di Dunia Nyata , mengakui bahwa Pengembang tidak mahatahu atau tidak salah, bahwa kita memang membuat kesalahan dan bahwa kita membutuhkan jaring pengaman untuk menangkap kita jika dan ketika kita memang berantakan!
Masukkan Tes.
Mungkin. Anda tidak perlu memahami implementasi sesuatu untuk menulis tes untuk itu (itu bagian dari titik mereka). Tes menentukan perilaku dan batasan aplikasi dan memastikan bahwa mereka tetap sama kecuali Anda sengaja mengubahnya.
sumber
Mereka tidak - pengembangan tes didorong dibangun di atas gagasan gagal tes. Tes unit gagal untuk mendorong pengembangan, gagal tes penerimaan untuk mendorong sebuah cerita ....
Yang Anda lewatkan adalah konteks ; di mana tes unit diizinkan gagal?
Jawaban yang biasa adalah bahwa tes unit diperbolehkan gagal hanya di kotak pasir pribadi.
Gagasan dasarnya adalah ini: di lingkungan di mana tes yang gagal dibagikan, dibutuhkan upaya ekstra untuk memahami apakah perubahan pada kode produksi telah menyebabkan kesalahan baru. Perbedaan antara nol dan bukan nol jauh lebih mudah untuk dideteksi dan dikelola daripada perbedaan antara N dan bukan N.
Selain itu, menjaga kode bersama bersih berarti bahwa pengembang dapat tetap mengerjakan tugas. Ketika saya menggabungkan kode Anda, saya tidak perlu mengubah konteks dari masalah yang saya bayar untuk menyelesaikan untuk mengkalibrasi pemahaman saya tentang berapa banyak tes yang harus gagal. Jika kode bersama melewati semua tes, setiap kegagalan yang muncul ketika saya menggabungkan perubahan saya harus menjadi bagian dari interaksi antara kode saya dan baseline bersih yang ada.
Demikian pula, selama naik pesawat, pengembang baru dapat menjadi lebih cepat produktif, karena mereka tidak perlu menghabiskan waktu untuk menemukan tes gagal mana yang "dapat diterima".
Untuk lebih tepatnya: disiplinnya adalah tes yang dijalankan selama build harus lulus.
Ada, seperti yang bisa saya katakan, tidak ada yang salah dengan memiliki tes gagal yang dinonaktifkan .
Misalnya, dalam lingkungan "integrasi berkelanjutan", Anda akan berbagi kode pada irama tinggi. Integrasi sering kali tidak berarti bahwa perubahan Anda harus siap dirilis. Ada berbagai macam teknik penyebaran gelap yang mencegah lalu lintas dirilis ke bagian kode sampai mereka siap.
Teknik-teknik yang sama dapat digunakan untuk menonaktifkan tes gagal juga.
Salah satu latihan yang saya lalui pada rilis poin adalah berurusan dengan pengembangan produk dengan banyak tes gagal. Jawaban yang kami ajukan adalah hanya melalui suite, menonaktifkan tes yang gagal dan mendokumentasikan masing-masing. Itu memungkinkan kami untuk dengan cepat mencapai titik di mana semua tes diaktifkan berlalu, dan manajemen / donor tujuan / pemilik emas semua bisa melihat perdagangan apa yang telah kami lakukan untuk sampai ke titik itu, dan dapat membuat keputusan tentang pembersihan dan pekerjaan baru.
Singkatnya: ada teknik lain untuk melacak pekerjaan yang tidak dilakukan selain meninggalkan banyak tes yang gagal di menjalankan suite.
sumber
Ada banyak jawaban bagus, tetapi saya ingin menambahkan sudut lain yang saya yakini belum tercakup dengan baik: apa gunanya melakukan tes.
Tes unit tidak ada untuk memeriksa apakah kode Anda bebas bug.
Saya pikir ini adalah kesalahpahaman utama. Jika ini adalah peran mereka, Anda tentu berharap akan gagal tes di semua tempat. Melainkan,
Tes unit memeriksa apakah kode Anda melakukan apa yang Anda pikirkan.
Dalam kasus ekstrem, ini mungkin termasuk memeriksa bahwa bug yang diketahui tidak diperbaiki. Intinya adalah untuk memiliki kontrol atas basis kode Anda dan menghindari perubahan yang tidak disengaja. Ketika Anda melakukan perubahan itu baik-baik saja dan sebenarnya diharapkan untuk memecahkan beberapa tes - Anda mengubah perilaku kode. Tes yang baru saja rusak sekarang merupakan jejak bagus dari apa yang Anda ubah. Periksa apakah semua kerusakan sesuai dengan yang Anda inginkan dari perubahan Anda. Jika demikian, perbarui saja tes dan lanjutkan. Jika tidak - yah, kode baru Anda pasti bermasalah, kembali dan perbaiki sebelum mengirimkan!
Sekarang, semua hal di atas hanya berfungsi jika semua tes berwarna hijau, memberikan hasil positif yang kuat: beginilah cara kode bekerja. Tes merah tidak memiliki properti itu. "Ini yang tidak dilakukan kode ini" jarang merupakan informasi yang berguna.
Tes penerimaan mungkin apa yang Anda cari.
Ada yang namanya pengujian penerimaan. Anda dapat menulis serangkaian tes yang harus dipenuhi untuk memanggil tonggak sejarah berikutnya. Ini ok untuk menjadi merah, karena itulah mereka dirancang untuk itu. Tetapi mereka sangat berbeda dari unit test dan tidak bisa atau tidak harus menggantikannya.
sumber
Saya melihatnya sebagai perangkat lunak yang setara dengan sindrom jendela pecah .
Tes kerja memberi tahu saya bahwa kode tersebut berkualitas dan pemilik kode peduli.
Adapun ketika Anda harus peduli dengan kualitas, itu lebih tergantung pada apa kode cabang / repositori yang sedang Anda kerjakan. Kode pengembangan mungkin telah melanggar tes yang mengindikasikan pekerjaan sedang berlangsung (mudah-mudahan!).
Tes yang rusak pada cabang / repositori untuk sistem live harus segera mengatur dering bel alarm. Jika tes yang rusak dibiarkan terus gagal atau jika itu secara permanen ditandai sebagai "abaikan" - perkirakan jumlahnya akan meningkat seiring waktu. Jika ini tidak ditinjau secara teratur preseden akan ditetapkan bahwa tidak apa-apa jika tes yang rusak dibiarkan.
Tes yang rusak dipandang sangat merendahkan di banyak toko sehingga memiliki batasan apakah kode yang rusak dapat dilakukan .
sumber
Berikut adalah kesalahan logis yang mendasarinya:
Dengan unit test, itu IS baik ketika semua tes lulus. Hal ini JUGA BAIK ketika tes gagal. Keduanya tidak perlu dalam oposisi.
Tes gagal adalah masalah yang ditangkap oleh alat Anda sebelum mencapai pengguna. Ini adalah kesempatan untuk memperbaiki kesalahan sebelum dipublikasikan. Dan itu hal yang baik.
sumber
Jawaban Phill W bagus. Saya tidak bisa menggantinya.
Namun, saya ingin fokus pada bagian lain yang mungkin menjadi bagian dari kebingungan.
"Kapan saja" ini melebih-lebihkan kasus Anda. Yang penting adalah bahwa unit test lulus setelah perubahan tertentu diterapkan, sebelum Anda mulai menerapkan perubahan lain.
Ini adalah cara Anda melacak perubahan yang menyebabkan bug muncul. Jika unit test mulai gagal setelah menerapkan perubahan 25 tetapi sebelum menerapkan perubahan 26, maka Anda tahu bahwa perubahan 25 menyebabkan bug.
Selama implementasi perubahan, tentu saja unit test bisa gagal; sangat tergantung pada seberapa besar perubahan itu. Jika saya mengembangkan kembali fitur inti, yang lebih dari sekadar perubahan kecil, saya mungkin akan mematahkan tes untuk sementara waktu sampai saya selesai mengimplementasikan versi baru dari logika.
Ini dapat membuat konflik sebagai aturan tim. Saya sebenarnya mengalami ini beberapa minggu yang lalu:
Entah aturan akan baik-baik saja. Namun kedua aturan tersebut tidak dapat bekerja bersama. Jika saya diberi perubahan besar yang membutuhkan beberapa hari untuk menyelesaikan, saya tidak akan dapat mematuhi kedua aturan secara bersamaan. Kecuali jika saya akan mengomentari perubahan saya setiap hari dan hanya melakukannya tanpa komentar setelah semuanya dilakukan; yang hanya kerja tidak masuk akal.
Dalam skenario ini, masalah di sini bukanlah bahwa tes unit tidak memiliki tujuan; itu adalah bahwa perusahaan memiliki harapan yang tidak realistis . Aturan sewenang-wenang mereka tidak mencakup semua kasus, dan kegagalan untuk mematuhi aturan secara membabi buta dianggap sebagai kegagalan pengembang daripada kegagalan aturan (yang, dalam kasus saya).
sumber
Jika Anda tidak memperbaiki semua tes unit, Anda dapat dengan cepat masuk ke kondisi di mana tidak ada yang memperbaiki tes yang rusak.
Tidak benar karena lulus tes unit tidak menunjukkan kode sempurna
Merupakan disinsentif untuk menghasilkan kode yang sulit untuk diuji juga, yang bagus dari sudut pandang desain
Cakupan kode dapat membantu di sana (meskipun itu bukan obat mujarab). Juga tes unit hanyalah salah satu aspek pengujian - Anda juga ingin tes integrasi / penerimaan.
sumber
Untuk menambahkan beberapa poin ke jawaban yang sudah bagus ...
Ini menunjukkan kurangnya pemahaman tentang proses rilis. Kegagalan pengujian dapat menunjukkan fitur yang direncanakan di bawah TDD yang belum diimplementasikan; atau mungkin mengindikasikan masalah yang diketahui yang memiliki perbaikan yang direncanakan untuk rilis di masa mendatang; atau mungkin hanya sesuatu di mana manajemen telah memutuskan ini tidak cukup penting untuk diperbaiki karena pelanggan tidak mungkin memperhatikan. Hal utama dari semua bagian ini adalah bahwa manajemen telah membuat keputusan tentang kegagalan.
Jawaban lain telah mencakup batas pengujian.
Saya tidak mengerti mengapa Anda berpikir menghilangkan bug adalah kerugian. Jika Anda tidak ingin mengirimkan kode yang telah Anda periksa (sesuai kemampuan Anda) melakukan apa yang seharusnya, mengapa Anda bahkan bekerja dalam perangkat lunak?
Mengapa harus ada peta jalan?
Tes unit pada awalnya memeriksa apakah fungsionalitas berfungsi, tetapi kemudian (sebagai tes regresi) periksa apakah Anda tidak sengaja merusak apa pun. Untuk semua fitur dengan tes unit yang ada, tidak ada peta jalan . Setiap fitur diketahui berfungsi (dalam batas pengujian). Jika kode itu selesai, ia tidak memiliki peta jalan karena tidak perlu lagi bekerja.
Sebagai insinyur profesional, kita perlu menghindari jebakan pelapisan emas. Penggemar dapat membuang waktu untuk bermain-main dengan sesuatu yang berhasil. Sebagai profesional, kita perlu mengirimkan produk. Itu berarti kami membuat sesuatu berfungsi, memverifikasi bahwa itu berfungsi, dan beralih ke pekerjaan berikutnya.
sumber
Tidak benar. mengapa Anda pikir itu tidak mungkin? di sini contoh untuk program yang berfungsi:
Dalam hal ini mungkin bukan tes unit, tetapi tes integrasi jika rumit
benar, ini disebut unit test karena suatu alasan, itu memeriksa unit kode kecil.
Pengembang
akanmencegah menulis tes apa pun jika mereka tidak memahami manfaatnyamenurut sifatnya (kecuali jika mereka datang dari QA)sumber
Jelas tidak. Ini mempromosikan gagasan bahwa tes Anda tidak boleh gagal, tidak lebih dan tidak kurang. Dengan asumsi bahwa melakukan tes (bahkan banyak dari mereka) mengatakan sesuatu tentang "sempurna" atau "tidak ada bug" adalah kesalahan. Memutuskan seberapa dangkal atau dalam pengujian Anda seharusnya merupakan bagian penting dari penulisan tes yang baik, dan alasan mengapa kami memiliki kategori tes yang terpisah secara terpisah (tes "unit", tes integrasi, "skenario" dalam arti mentimun, dll.).
Dalam pengembangan yang digerakkan oleh tes, adalah wajib bahwa setiap tes unit gagal terlebih dahulu, sebelum mulai kode. Ini disebut "siklus merah-hijau" (atau "siklus merah-hijau-reaktor") karena alasan ini.
Tes lebih merupakan tujuan mikro. Dalam pengembangan test-driven, programmer akan menulis tes (tunggal) terlebih dahulu, dan kemudian memiliki tujuan yang jelas untuk mengimplementasikan beberapa kode; maka tes selanjutnya, dan seterusnya.
Fungsi tes tidak ada di sana dalam kelengkapan sebelum kode ditulis.
Ketika dilakukan dengan benar, dalam bahasa dan dengan pustaka pengujian yang sangat cocok untuk pendekatan ini, ini sebenarnya dapat mempercepat pengembangan secara besar-besaran, karena pesan kesalahan (pengecualian / stacktraces) dapat langsung mengarahkan pengembang ke tempat ia perlu melakukan pekerjaan lanjut.
Saya tidak melihat bagaimana pernyataan ini benar. Tes menulis idealnya harus menjadi bagian dari implementasi.
Karena organisasi mengharapkan tes memiliki relevansi dengan kode. Menulis tes yang berhasil berarti Anda telah mendokumentasikan beberapa bagian dari aplikasi Anda, dan telah membuktikan bahwa aplikasi tersebut melakukan apa yang dikatakan (tes). Tidak lebih dan tidak kurang.
Juga, bagian yang sangat besar dari tes adalah "regresi". Anda ingin dapat mengembangkan atau memperbaiki kode baru dengan percaya diri. Memiliki sejumlah besar tes hijau memungkinkan Anda melakukan itu.
Ini beranjak dari organisasi ke level psikologis. Seorang pengembang yang tahu bahwa kesalahannya kemungkinan besar akan tertangkap oleh tes akan jauh lebih bebas untuk menghasilkan solusi yang cerdas dan berani untuk masalah yang perlu dipecahkan. Di sisi lain, seorang pengembang yang tidak memiliki tes, setelah beberapa waktu, akan terhenti (karena takut) karena dia tidak pernah tahu jika perubahan yang dilakukannya merusak sisa aplikasi.
Tidak. Bekerja dengan aplikasi yang digerakkan oleh ujian adalah kegembiraan murni - kecuali jika Anda tidak menyukai konsep untuk alasan apa pun ("lebih banyak usaha" dll.) Yang dapat kita bahas dalam pertanyaan lain.
Sama sekali tidak, mengapa?
Anda menemukan banyak proyek open source besar (yang manajemen "pemahaman" dan pengetahuan tentang kode adalah topik yang sangat mendesak) yang benar-benar menggunakan tes sebagai dokumentasi utama dari perangkat lunak, dengan, selain sebagai tes, juga memberikan contoh nyata, yang berfungsi, yang secara sintaksis benar untuk pengguna atau pengembang aplikasi / perpustakaan. Ini sering berhasil dengan sangat baik.
Jelas, menulis tes buruk itu buruk. Tapi itu tidak ada hubungannya dengan fungsi tes itu sendiri.
sumber
(Dari komentar asli saya)
Ada perbedaan antara fungsionalitas yang diperlukan dan tujuan masa depan. Tes untuk fungsionalitas yang diperlukan: mereka tepat, formal, dapat dieksekusi, dan jika gagal, perangkat lunak tidak berfungsi. Sasaran masa depan mungkin tidak tepat atau formal, apalagi dapat dieksekusi, jadi lebih baik dibiarkan dalam bahasa alami seperti di pelacak isu / bug, dokumentasi, komentar, dll.
Sebagai latihan, coba ganti frase "unit test" dalam pertanyaan Anda dengan "kesalahan kompiler" (atau "kesalahan sintaksis", jika tidak ada kompiler). Jelas bahwa suatu rilis seharusnya tidak memiliki kesalahan kompiler, karena itu tidak dapat digunakan; namun kesalahan penyusun dan kesalahan sintaksis adalah keadaan normal pada mesin pengembang saat mereka menulis kode. Kesalahan hanya hilang saat mereka selesai; dan saat itulah kode harus didorong. Sekarang ganti "kesalahan kompiler" dalam paragraf ini dengan "unit test" :)
sumber
Tujuan dari tes otomatis adalah untuk memberi tahu Anda ketika Anda telah memecahkan sesuatu sedini mungkin . Alur kerjanya terlihat seperti ini:
Jika tes Anda sudah gagal maka langkah # 3 tidak bekerja secara efektif - tes akan gagal, tetapi Anda tidak tahu apakah itu berarti Anda memecahkan sesuatu atau tidak tanpa menyelidiki. Mungkin Anda bisa menghitung jumlah tes gagal, tetapi kemudian perubahan mungkin memperbaiki satu bug dan memecahkan bug lain, atau tes mungkin mulai gagal karena alasan yang berbeda. Ini berarti Anda perlu menunggu beberapa saat sebelum Anda tahu apakah ada sesuatu yang rusak, baik sampai semua masalah telah diperbaiki atau sampai setiap tes gagal diselidiki.
Kemampuan untuk pengujian unit untuk menemukan bug yang baru diperkenalkan sedini mungkin adalah hal yang paling berharga tentang pengujian otomatis - semakin lama kerusakan tidak ditemukan, semakin mahal biaya perbaikannya.
Tes untuk hal-hal yang tidak bekerja tidak mengatakan apa-apa - menulis unit test untuk hal-hal yang dilakukan pekerjaan, atau bahwa Anda akan memperbaikinya. Itu tidak berarti perangkat lunak Anda bebas cacat, itu berarti bahwa tidak ada cacat yang sebelumnya Anda buat untuk unit test yang kembali lagi.
Jika itu berhasil untuk Anda kemudian tulis tes di depan, tapi jangan periksa ke master / trunk Anda sampai lulus.
Tes unit bukan untuk menetapkan peta jalan / sasaran, mungkin menggunakan jaminan simpanan untuk itu? Jika semua tes Anda lulus maka "gambaran besarnya" adalah bahwa perangkat lunak Anda tidak rusak (jika cakupan pengujian Anda baik). Sudah selesai dilakukan dengan baik!
sumber
Jawaban yang ada tentu baik, tetapi saya belum melihat ada yang membahas kesalahpahaman mendasar ini dalam pertanyaan:
Tidak. Paling pasti, ini tidak akan benar. Saat saya sedang mengembangkan perangkat lunak, NCrunch paling sering berwarna cokelat (gagal bangun) atau merah (gagal uji).
Di mana NCrunch harus berwarna hijau (semua tes lulus) adalah ketika saya siap untuk mendorong komit ke server kontrol sumber, karena pada saat itu orang lain mungkin memerlukan ketergantungan pada kode saya.
Ini juga dimasukkan ke dalam topik membuat tes baru: tes harus menegaskan logika dan perilaku kode. Kondisi batas, kondisi kesalahan, dll. Ketika saya menulis tes baru, saya mencoba mengidentifikasi "hot spot" ini dalam kode.
Tes unit mendokumentasikan bagaimana saya mengharapkan kode saya dipanggil - prasyarat, keluaran yang diharapkan, dll.
Jika tes gagal mengikuti perubahan, saya perlu memutuskan apakah kode atau tes tersebut salah.
Sebagai catatan, pengujian unit terkadang berjalan seiring dengan Test Driven Development. Salah satu prinsip TDD adalah bahwa tes yang rusak adalah tiang petunjuk Anda. Ketika tes gagal, Anda harus memperbaiki kode sehingga tes lulus. Ini adalah contoh nyata dari awal minggu ini:
Latar Belakang : Saya menulis dan sekarang mendukung perpustakaan yang digunakan oleh pengembang kami yang digunakan untuk memvalidasi permintaan Oracle. Kami memiliki tes yang menyatakan bahwa kueri cocok dengan beberapa nilai yang diharapkan, yang menjadikan case penting (bukan di Oracle) dan dengan senang hati menyetujui kueri yang tidak valid selama mereka benar-benar cocok dengan nilai yang diharapkan.
Sebagai gantinya, perpustakaan saya mem-parsing kueri menggunakan Antlr dan sintaks Oracle 12c, dan kemudian membungkus berbagai pernyataan pada pohon sintaksis itu sendiri. Hal-hal seperti, itu valid (tidak ada kesalahan parse dinaikkan), semua parameternya dipenuhi oleh koleksi parameter, semua kolom yang diharapkan dibaca oleh pembaca data ada dalam kueri, dll. Semua ini adalah item yang telah diselipkan ke produksi pada berbagai waktu.
Salah satu rekan insinyur saya mengirimi saya pertanyaan pada hari Senin yang gagal (atau lebih tepatnya, berhasil ketika seharusnya gagal) selama akhir pekan. Perpustakaan saya mengatakan sintaksinya baik-baik saja, tetapi meledak ketika server mencoba menjalankannya. Dan ketika dia melihat permintaan, jelas mengapa:
Saya memuat proyek dan menambahkan tes unit yang menyatakan bahwa permintaan ini seharusnya tidak valid. Jelas, tes gagal.
Berikutnya, saya debugged tes gagal, melangkah melalui kode di mana saya harapkan untuk membuang pengecualian, dan tahu bahwa Antlr itu menaikkan kesalahan pada paren terbuka, hanya saja tidak dengan cara kode sebelumnya mengharapkan. Saya memodifikasi kode, memverifikasi bahwa tes sekarang hijau (lulus) dan tidak ada orang lain yang rusak dalam proses, berkomitmen, dan mendorong.
Ini mungkin memakan waktu 20 menit, dan dalam prosesnya saya benar-benar meningkatkan perpustakaan secara signifikan karena sekarang mendukung seluruh jajaran kesalahan yang sebelumnya telah diabaikan. Jika saya tidak memiliki tes unit untuk perpustakaan, meneliti dan memperbaiki masalah ini bisa memakan waktu berjam-jam.
sumber
Satu hal yang menurut saya tidak keluar dari jawaban sebelumnya adalah bahwa ada perbedaan antara tes internal dan tes eksternal (dan saya pikir banyak proyek tidak cukup hati-hati untuk membedakan keduanya). Tes internal menguji bahwa beberapa komponen internal berfungsi sebagaimana mestinya; tes eksternal menunjukkan bahwa sistem secara keseluruhan berfungsi sebagaimana mestinya. Tentu saja sangat mungkin untuk memiliki kegagalan dalam komponen yang tidak mengakibatkan kegagalan sistem (mungkin ada fitur komponen yang tidak digunakan sistem, atau mungkin sistem pulih dari kegagalan sistem). komponen). Kegagalan komponen yang tidak mengakibatkan kegagalan sistem seharusnya tidak menghentikan Anda melepaskannya.
Saya telah melihat proyek yang lumpuh karena terlalu banyak tes komponen internal. Setiap kali Anda mencoba dan menerapkan peningkatan kinerja, Anda memecahkan puluhan tes, karena Anda mengubah perilaku komponen tanpa benar-benar mengubah perilaku sistem yang terlihat secara eksternal. Hal ini menyebabkan kurangnya kelincahan dalam proyek secara keseluruhan. Saya percaya investasi dalam pengujian sistem eksternal umumnya memiliki hasil yang jauh lebih baik daripada investasi dalam pengujian komponen internal, terutama ketika Anda berbicara tentang komponen yang sangat rendah.
Ketika Anda menyarankan bahwa tes unit gagal tidak terlalu penting, saya bertanya-tanya apakah ini yang Anda pikirkan? Mungkin Anda harus menilai nilai tes unit dan membuang yang menyebabkan lebih banyak masalah daripada nilainya, sambil lebih fokus pada tes yang memverifikasi perilaku aplikasi yang terlihat secara eksternal.
sumber
"tetapi pada setiap titik waktu semua tes unit harus lulus"
Jika itu sikap di perusahaan Anda, itu masalah. Pada waktu TERTENTU, yaitu, ketika kami menyatakan bahwa kode siap untuk pindah ke lingkungan berikutnya, semua tes unit harus lulus. Tetapi selama pengembangan, kita harus secara rutin berharap banyak unit test gagal.
Tidak ada orang yang beralasan mengharapkan seorang programmer untuk mendapatkan pekerjaannya sempurna pada percobaan pertama. Apa yang kami harapkan secara wajar adalah bahwa ia akan terus mengerjakannya sampai tidak ada masalah yang diketahui.
"Adalah disinsentif untuk memikirkan unit test yang akan gagal. Atau tentu saja muncul dengan unit test yang akan sulit untuk diperbaiki." Jika seseorang di organisasi Anda berpikir bahwa mereka tidak boleh menyebutkan tes yang mungkin karena mungkin gagal dan menyebabkan mereka lebih banyak pekerjaan untuk memperbaikinya, orang itu benar-benar tidak memenuhi syarat untuk pekerjaan mereka. Ini adalah sikap yang membawa malapetaka. Apakah Anda ingin dokter yang mengatakan, "Ketika saya melakukan operasi, saya sengaja tidak memeriksa apakah jahitannya benar, karena jika saya melihat mereka tidak, saya harus kembali dan melakukannya lagi dan itu akan memperlambat penyelesaian operasi "?
Jika tim memusuhi programmer yang mengidentifikasi kesalahan sebelum kode diproduksi, Anda memiliki masalah nyata dengan sikap tim itu. Jika manajemen menghukum programmer yang mengidentifikasi kesalahan yang memperlambat pengiriman, kemungkinan perusahaan Anda menuju kebangkrutan.
Ya, memang benar bahwa kadang-kadang orang yang rasional mengatakan, "Kami mendekati tenggat waktu, ini masalah sepele dan tidak layak mencurahkan sumber daya sekarang karena diperlukan untuk memperbaikinya." Tetapi Anda tidak dapat membuat keputusan itu secara rasional jika Anda tidak tahu. Dengan dingin memeriksa daftar kesalahan dan menetapkan prioritas dan jadwal untuk memperbaikinya adalah rasional. Sengaja membuat diri Anda tidak mengetahui masalah sehingga Anda tidak harus membuat keputusan ini bodoh. Apakah Anda pikir pelanggan tidak akan mengetahuinya hanya karena Anda tidak ingin tahu?
sumber
Ini adalah contoh spesifik bias konfirmasi , di mana orang cenderung mencari informasi yang menegaskan keyakinan mereka yang ada.
Salah satu contoh terkenal dari ini terjadi, adalah dalam permainan 2,4,6.
Kebanyakan orang memilih aturan, katakan "kesenjangan antara angka 1 dan 2 sama dengan perbedaan antara angka 2 dan 3."
Mereka akan menguji beberapa angka:
Mereka berkata, "Ya, setiap pengamatan menegaskan hipotesis saya, itu pasti benar." Dan umumkan aturan mereka kepada orang yang memberikan teka-teki.
Tetapi mereka tidak pernah menerima satu pun 'gagal' untuk set tiga angka. Aturannya bisa saja 'tiga angka perlu angka' untuk semua informasi yang mereka miliki.
Aturannya sebenarnya hanya bahwa angkanya dalam urutan menaik. Orang-orang biasanya hanya mendapatkan teka-teki ini dengan benar jika mereka menguji kegagalan. Kebanyakan orang salah, dengan memilih aturan yang lebih spesifik, dan hanya menguji angka yang memenuhi aturan khusus ini.
Mengenai mengapa orang-orang jatuh ke bias konfirmasi, dan mungkin melihat unit test gagal sebagai bukti masalah, ada banyak psikolog yang dapat menjelaskan bias konfirmasi lebih baik daripada saya, pada dasarnya turun ke orang-orang yang tidak menyukai kesalahan, dan berjuang untuk benar-benar berusaha untuk membuktikan diri mereka salah.
sumber