Apa nilai memeriksa dalam gagal unit test?

13

Meskipun ada beberapa cara untuk mencegah pengujian unit agar tidak dieksekusi, berapakah nilai pemeriksaan pada pengujian unit yang gagal?

Saya akan menggunakan contoh sederhana: Sensitivitas Kasus. Kode saat ini peka terhadap huruf besar-kecil. Input yang valid ke dalam metode adalah "Cat" dan itu akan mengembalikan enum dari Animal.Cat. Namun, fungsionalitas yang diinginkan dari metode ini tidak boleh peka huruf besar-kecil. Jadi, jika metode yang dijelaskan lulus "kucing" itu mungkin bisa mengembalikan sesuatu seperti Animal.Null bukan Animal.Cat dan unit test akan gagal. Meskipun perubahan kode sederhana akan berhasil, masalah yang lebih kompleks mungkin memerlukan waktu berminggu-minggu untuk diperbaiki, tetapi mengidentifikasi bug dengan unit test bisa menjadi tugas yang tidak terlalu rumit.

Aplikasi saat ini sedang dianalisis memiliki kode 4 tahun yang "berfungsi". Namun, diskusi terbaru tentang unit test telah menemukan kekurangan dalam kode. Beberapa hanya perlu dokumentasi implementasi eksplisit (mis. Case sensitif atau tidak), atau kode yang tidak mengeksekusi bug berdasarkan bagaimana itu disebut. Tetapi unit test dapat dibuat dengan menjalankan skenario tertentu yang akan menyebabkan bug dilihat dan merupakan input yang valid.

Apa nilai memeriksa unit test yang menjalankan bug sampai seseorang dapat memperbaiki kode?

Haruskah pengujian unit ini ditandai dengan pengabaian, prioritas, kategori dll, untuk menentukan apakah membangun berhasil berdasarkan tes yang dilaksanakan? Akhirnya tes unit harus dibuat untuk mengeksekusi kode begitu seseorang memperbaikinya.

Di satu sisi itu menunjukkan bahwa bug yang diidentifikasi belum diperbaiki. Di sisi lain, mungkin ada ratusan unit test gagal muncul di log dan menyaring yang gagal vs kegagalan karena kode check-in akan sulit ditemukan.

Jim G.
sumber
Itu salah satu cara untuk meningkatkan angka cakupan tes tersebut.
JeffO
Jika Anda sudah berupaya menulis unit test, mengapa Anda ingin harus menulis ulang ketika Anda memutuskan untuk memperbaiki masalah? Hanya karena sudah diperiksa, tidak berarti harus dijalankan di suite. (Anda dapat membuat kategori untuk "Masalah yang Diketahui", dan memperlakukan tes-tes tersebut sebagai daftar jaminan / TODO.)
Caleb

Jawaban:

17

Saya tidak suka unittests rusak check in karena mereka menghasilkan suara yang tidak perlu. Setelah setiap unittest saya harus memeriksa semua masalah yang gagal (merah). Apakah merah karena ada masalah baru atau karena ada yang lama terbuka untuk dilakukan / diperbaiki. Ini tidak apa-apa jika ada lebih dari 20 unittests.

Sebaliknya saya gunakan

  • [Ignore("Reason")]atribut yang membuat hasilnya kuning atau
  • throw new NotImplementedException()yang membuat hasilnya abu-abu

Catatan: Saya menggunakan NUnit untuk .net. Saya tidak yakin apakah fitur "abu-abu" ada di kerangka kerja lain yang belum dikirim.

Jadi saya suka arti berikut dari hasil tes unit.

  • hijau: semua selesai
  • abu-abu: fitur baru terencana yang perlu dilakukan tetapi dengan prioritas rendah
  • kuning: bug belum diperbaiki. Harus segera diperbaiki
  • merah: bug baru. Harus segera diperbaiki

Semuanya kecuali "merah" dapat diperiksa.

Untuk menjawab pertanyaan: ada lebih banyak ruginya daripada nilai untuk memeriksa "test-gagal-merah" tetapi memeriksa "tes-tes yang diabaikan-kuning" atau "tes-abu-Tidak-terimplentasikan-Namun" dapat berguna sebagai daftar tugas.

k3b
sumber
masalah yang saya lihat dengan pendekatan ini adalah, bahwa tes yang diabaikan mungkin tidak akan pernah diperbaiki. Anda juga bisa menghapus seluruh kode tes, apa bedanya (saya agak sombong di sini)
Lovis
4
will probably never be fixedadalah keputusan politis jika Anda ingin mengeluarkan uang dalam tes otomatis atau tidak. Dengan "tes yang diabaikan" Anda memiliki kesempatan untuk memperbaikinya. Membuang "tes yang diabaikan" berarti "meninggalkan tes otomatis pada dan sampai tidak ada lagi"
k3b
8

Saya tidak akan berpura-pura bahwa ini adalah standar industri, tetapi saya memeriksa tes yang rusak sebagai cara untuk mengingatkan saya atau anggota proyek saya yang lain bahwa masih ada masalah dengan kode atau tes unit itu sendiri.

Saya kira satu hal yang perlu dipertimbangkan adalah apakah kebijakan pengembangan Anda memungkinkan untuk tes gagal tanpa penalti. Saya punya teman yang bekerja di toko yang melakukan pengembangan berbasis tes, jadi mereka selalu memulai dengan tes yang gagal ...

Tieson T.
sumber
5
Tetapi Anda seharusnya tidak pernah memeriksa dalam tes yang gagal, karena server build Anda seharusnya tidak membangun proyek dengan tes yang rusak.
CaffGeek
@ Chad: Membangun dan menguji adalah dua bagian terpisah dari satu langkah otomatis. Bangunan memastikan semuanya terkompilasi. Tes memastikan bahwa hasil build valid. Penafsiran saya terhadap pertanyaan itu bukan, "haruskah saya memeriksa kode yang tidak dikompilasi?" Sebaliknya, "haruskah saya memeriksa tes yang saya tahu akan gagal?"
unholysampler
1
Saya baru saja menambahkan satu hal untuk dipertimbangkan, beberapa integrasi berkelanjutan membangun server menjalankan tes, dan jika gagal, mereka tidak dapat digunakan. Benar, seolah-olah membangun gagal, kode gagal, dan tidak ada gunanya menyebarkan produk yang dikenal rusak.
CaffGeek
@ Chad: Benar, saya benar-benar lupa tentang server CI. Itu pasti akan menjadi titik untuk dipertimbangkan. Perlu juga mengklarifikasi apa yang kami maksud dengan tes "rusak"; apakah itu sekadar tes "buruk", atau apakah tes gagal karena API berubah dalam beberapa cara?
Tieson T.
Pertanyaannya seharusnya lebih jelas. Seharusnya tes tersebut akan dikompilasi, tetapi hasil yang diharapkan akan gagal.
6

Uji unit yang gagal memberikan visibilitas tim pengembangan ke dalam apa yang harus dilakukan untuk memenuhi spesifikasi yang disepakati.

Singkatnya, tes unit yang gagal memberi tim daftar "TODO".

Untuk alasan ini, kegagalan unit test jauh lebih baik daripada tidak ada unit test sama sekali. *
Tidak adanya unit test membuat tim pengembangan dalam kegelapan; spesifikasi harus berulang kali dikonfirmasi secara manual .

[* Asalkan unit test benar-benar menguji sesuatu yang bermanfaat.]

Jim G.
sumber
2
Ada cara yang lebih baik untuk mempertahankan daftar agenda, misalnya papan tulis, aplikasi daftar tugas, atau sistem pelacakan masalah. Jauh lebih mudah untuk menggunakan test suite jika Anda mengharapkannya untuk selalu lulus penuh, dan setiap kegagalan tes yang muncul adalah masalah baru untuk segera diperbaiki.
bdsl
6

Tujuan dari unit test adalah untuk menegaskan perilaku yang diharapkan dari suatu sistem, bukan untuk mendokumentasikan kerusakan. Jika kita menggunakan unit test untuk mendokumentasikan cacat, maka kegunaannya untuk menegaskan perilaku yang diharapkan berkurang. Jawaban untuk pertanyaan "Mengapa tes ini gagal?" bukan sederhana "Oh, ada sesuatu yang rusak yang saya tidak harapkan akan rusak." Sudah menjadi tidak diketahui apakah tes gagal diharapkan atau tidak terduga.

Ini adalah paragraf dari awal bab 13 tentang Bekerja Secara Efektif dengan Kode Legacy :

Tes unit otomatis adalah alat yang sangat penting, tetapi tidak untuk menemukan bug - setidaknya tidak secara langsung. Secara umum, tes otomatis harus menentukan tujuan yang ingin kami penuhi atau berusaha untuk mempertahankan perilaku yang sudah ada. Dalam arus perkembangan alami, tes yang menentukan menjadi tes yang dipertahankan . Anda akan menemukan bug, tetapi biasanya bukan kali pertama tes dijalankan. Anda menemukan bug di kemudian berjalan ketika Anda mengubah perilaku yang tidak Anda harapkan.

Matthew Rodatus
sumber
3

Tetapi yang rusak yang mengidentifikasi bug dalam proyek baru, dinamai demikian. Dengan begitu Anda dapat melihat bahwa mereka HARUS rusak ... Ketika mereka diperbaiki, mereka akan berubah menjadi hijau, dan dipindahkan ke ruang uji normal.

CATATAN: Proyek itu harus disetel agar tidak dibangun di server build, jika server build Anda mencegah checkin yang merusak build (dengan asumsi Anda mendefinisikan build rusak sebagai salah satu di mana semua tes tidak lulus)

CaffGeek
sumber
+1 meskipun tidak ada jawaban jika ingin checkin atau tidak ada argumen penting: build server
k3b
Saya lebih suka menggunakan atribut untuk menandai tes seperti itu daripada memindahkannya ke proyek terpisah.
CodesInChaos
2

Tes unit harus menguji kasus kesalahan selain kasus keberhasilan suatu fungsi. Suatu fungsi harus secara eksplisit menolak input yang buruk atau harus memiliki dokumentasi untuk menjelaskan input apa yang dianggap valid.

Jika Anda memiliki fungsi yang tidak melakukan hal-hal tersebut, itu adalah bug dan Anda harus memiliki cara untuk merekam bahwa itu ada. Membuat unit test yang menunjukkan masalah ini adalah salah satu cara untuk melakukannya. Mengajukan tiket bug adalah pilihan lain.

Maksud dari pengujian unit bukanlah untuk mencapai kesuksesan 100%, intinya adalah untuk menemukan dan memperbaiki bug dalam kode. Tidak melakukan tes adalah cara mudah untuk mencapai kesuksesan 100%, tetapi itu tidak terlalu bermanfaat bagi proyek.

unholysampler
sumber
Woah ... "Inti dari pengujian unit bukanlah untuk mencapai kesuksesan 100%", apakah Anda mengatakan bahwa mereka tidak semua harus lulus !?
CaffGeek
2
@Chad: Intinya adalah lebih baik memiliki tes yang Anda tahu akan gagal, tetapi menunjukkan masalah nyata daripada tidak memiliki tes hanya sehingga Anda dapat memiliki tanda centang hijau di akhir build / test malam.
unholysampler
8
@ unholysampler, tidak pernah memiliki tes yang rusak, kecuali jika mereka ditandai dengan jelas sebagai "harus" rusak (dengan berada di proyek yang berbeda). Jika tidak, mereka menjadi bising, dan Anda tidak tahu kapan tes yang seharusnya lulus, telah rusak. Ini benar-benar mengalahkan tujuan Integrasi Berkelanjutan dan memiliki UnitTests
CaffGeek
2
@ Chad: Saya pikir ini masuk ke semantik definisi. Berdasarkan OP, sepertinya dia sedang berbicara tentang membuat tes yang valid yang melatih bug. Namun, bug adalah prioritas rendah dan tidak mungkin diperbaiki segera. Anda adalah orang yang mengangkat Integrasi Berkelanjutan, yang memberikan batasan lebih ketat pada proses otomatis.
unholysampler
4
@ unholysampler, CI, atau tanpa CI, intinya adalah, ketika Anda menjalankan tes, dan terbiasa melihat beberapa lampu Merah, Anda menjadi terbiasa. Jadi, ketika sesuatu yang berwarna hijau, berubah menjadi merah ... bagaimana Anda tahu?!? Ini adalah praktik yang mengerikan, dan salah satu alasan pengujian gagal diterima di banyak organisasi.
CaffGeek
1

Ajukan bug untuk setiap kegagalan, dan perhatikan itu dalam hasil pengujian. Kemudian jika Anda pernah bertindak bersama-sama dan memperbaiki bug, tes Anda lulus dan Anda menghapusnya dari hasil tes. Jangan pernah mengabaikan masalah.

SnoopDougieDoug
sumber
-3

Bagaimana saya melihat TDD dilakukan dengan menerapkan tes untuk kode yang belum selesai, tulis tes terlebih dahulu dengan atribut [ExpectedException] atau serupa. Ini harus lulus pada awalnya karena kode yang tidak lengkap tidak akan memiliki logika di dalamnya dan menulis kode Exception () baru di dalamnya. Meskipun pengecualian yang salah adalah salah, ini setidaknya akan membuat tes lulus pada awalnya dan cocok untuk checkin. Kami mungkin lupa tes yang diabaikan tetapi mungkin dapat merapikan atau mengisi kode yang tidak lengkap. Ketika kami melakukannya, secara otomatis tes terkait yang mengharapkan pengecualian sekarang akan mulai gagal dan alarm Anda untuk memperbaikinya. Ini mungkin melibatkan sedikit perubahan tes untuk menyingkirkan ExpectException dan sebagai gantinya melakukan pernyataan nyata. CI, Dev, penguji dan pelanggan semua senang dan situasi win-win?

pengguna211764
sumber
1
Ini tidak menjawab pertanyaan. Tidak bertanya apa itu TDD dan mengapa menguji pengecualian yang diharapkan.
Andy Wiesendanger