Pengujian TDD dan unit tampaknya menjadi rave besar saat ini. Tetapi apakah benar-benar berguna dibandingkan dengan bentuk pengujian otomatis lainnya?
Secara intuitif saya akan menebak bahwa pengujian integrasi otomatis jauh lebih berguna daripada pengujian unit. Dalam pengalaman saya, sebagian besar bug tampaknya berada dalam interaksi antara modul, dan tidak begitu banyak logika aktual (biasanya terbatas) dari masing-masing unit. Kemunduran juga sering terjadi karena perubahan antarmuka antar modul (dan perubahan pra dan pasca-kondisi.)
Apakah saya salah paham akan sesuatu, atau mengapa pengujian unit mendapatkan begitu banyak fokus dibandingkan dengan pengujian integrasi? Ini hanya karena diasumsikan bahwa pengujian integrasi adalah sesuatu yang Anda miliki, dan pengujian unit adalah hal berikutnya yang perlu kita pelajari untuk diterapkan sebagai pengembang?
Atau mungkin pengujian unit hanya menghasilkan perolehan tertinggi dibandingkan dengan kompleksitas mengotomatisasi itu?
Apa yang Anda alami dengan pengujian unit otomatis, pengujian integrasi otomatis, dan pengujian penerimaan otomatis, dan menurut pengalaman Anda apa yang menghasilkan ROI tertinggi? dan mengapa?
Jika Anda harus memilih hanya satu bentuk pengujian untuk diotomatiskan pada proyek Anda berikutnya, manakah itu?
Terima kasih sebelumnya.
sumber
Jawaban:
Salah satu faktor penting yang membuat unit test sangat berguna adalah umpan balik cepat .
Pertimbangkan apa yang terjadi ketika aplikasi Anda sepenuhnya tertutup dengan tes integrasi / Sistem / fungsional (yang sudah merupakan situasi ideal, jauh dari kenyataan di sebagian besar toko pengembangan). Ini sering dijalankan oleh tim pengujian khusus.
Ini semua mungkin butuh berhari-hari atau bahkan berminggu-minggu. Pada saat ini Anda sudah mengerjakan tugas-tugas lain, sehingga Anda tidak memiliki rincian menit dari kode yang ditulis sebelumnya dalam pikiran Anda. Selain itu, Anda biasanya tidak memiliki bukti langsung tentang di mana bug itu berada, sehingga perlu waktu yang cukup lama untuk menemukan dan memperbaiki bug tersebut.
Sedangkan dalam unit testing (TDD)
Ini semua terjadi dalam hitungan menit .
Ini bukan untuk mengatakan bahwa tes integrasi / sistem tidak berguna; mereka hanya melayani tujuan yang berbeda. Dengan unit test yang ditulis dengan baik, Anda dapat menangkap sebagian besar bug dalam kode sebelum mereka mencapai tahap integrasi, di mana sudah jauh lebih mahal untuk menemukan dan memperbaikinya. Anda benar bahwa tes integrasi diperlukan untuk menangkap jenis bug yang sulit atau tidak mungkin ditangkap dengan tes unit. Namun, dalam pengalaman saya itu adalah jenis yang lebih jarang; sebagian besar bug yang saya lihat disebabkan oleh kelalaian sederhana atau bahkan sepele di suatu tempat di dalam suatu metode.
Belum lagi pengujian unit juga menguji antarmuka Anda untuk kegunaan / keselamatan, dll., Sehingga memberi Anda umpan balik yang sangat penting untuk meningkatkan desain dan API Anda. Yang IMHO dapat sangat mengurangi kemungkinan bug / susbsystem integrasi bug: semakin mudah dan bersih API adalah, semakin sedikit kemungkinan kesalahpahaman atau kelalaian.
ROI tergantung pada banyak faktor, mungkin yang terpenting adalah apakah proyek Anda adalah greenfield atau warisan. Dengan pengembangan greenfield saran saya (dan pengalaman sejauh ini) adalah melakukan pengujian unit gaya TDD dari awal. Saya yakin ini adalah metode yang paling hemat biaya dalam kasus ini.
Namun, dalam proyek warisan, membangun cakupan pengujian unit yang memadai adalah pekerjaan besar yang akan sangat lambat untuk menghasilkan manfaat. Akan lebih efisien untuk mencoba mencakup fungsionalitas paling penting dengan tes sistem / fungsional melalui UI jika memungkinkan. (aplikasi GUI desktop mungkin sulit untuk diuji secara otomatis melalui GUI, meskipun alat pendukung pengujian otomatis secara bertahap membaik ...). Ini memberi Anda jaring pengaman yang kasar tapi efektif dengan cepat. Kemudian Anda dapat mulai secara bertahap membangun unit test di sekitar bagian paling kritis dari aplikasi.
Itu adalah pertanyaan teoretis dan saya merasa tidak ada gunanya. Semua jenis tes digunakan dalam kotak peralatan dari insinyur SW yang baik, dan semua ini memiliki skenario di mana mereka tidak tergantikan.
sumber
Semua jenis pengujian sangat penting, dan memastikan berbagai aspek sistem berada dalam spesifikasi. Jadi untuk bekerja mundur, "Jika saya harus memilih satu jenis pengujian ..." Saya tidak akan melakukannya. Pengujian unit memberi saya umpan balik yang berbeda dari pengujian integrasi atau pengujian interaktif oleh seseorang.
Inilah jenis / manfaat pengujian yang kami lakukan:
Opsional tetapi direkomendasikan pengujian:
Hanya untuk memahami mengapa Pengujian Unit memiliki keunggulan dibandingkan pengujian integrasi, Anda harus memahami urutan pengujian tambahan yang besar yang Anda perlukan untuk menjadi komprehensif. Untuk setiap kemungkinan hasil untuk unit A, perlu ada tes. Sama untuk unit B. Sekarang, jika keduanya bekerja bersama untuk solusi yang lebih lengkap, jumlah tes adalah kombinatorial. Singkatnya, untuk menguji setiap permutasi interaksi antara unit A dan unit B, Anda memerlukan tes A * B. Tambahkan unit C, dan jumlah tes untuk ketiganya adalah A * B * C.
Di sinilah konsep antarmuka dan batas-batas objek menjadi sangat penting. Antarmuka mewakili kontrak tertentu. Seorang pelaksana antarmuka setuju bahwa itu akan berperilaku dengan cara tertentu. Demikian pula, konsumen dari sebuah antarmuka setuju bahwa ia akan menggunakan implementasi dengan cara tertentu. Dengan menulis tes yang mengumpulkan setiap kelas yang mengimplementasikan antarmuka, Anda dapat dengan mudah menguji bahwa setiap implementasi mengamati kontrak antarmuka. Itu setengah dari persamaan. Setengah lainnya adalah untuk menguji sisi konsumen - yang merupakan tempat benda tiruan untuk bermain. Mock dikonfigurasi untuk memastikan bahwa interaksi selalu dalam spesifikasi. Pada titik ini, yang diperlukan hanyalah beberapa tes integrasi untuk memastikan bahwa kami telah mendapatkan kontrak implementor / konsumen yang benar.
sumber
Ini adalah alat yang berbeda dengan tujuan yang berbeda:
Pengujian unit adalah alat desain (TDD), dan hampir merupakan prasyarat untuk refactoring.
Tes integrasi sangat bagus untuk memvisualisasikan kemajuan proyek, dan juga bagus untuk menghindari bug regresi.
Poin yang perlu diingat adalah bahwa Anda tidak dapat benar-benar mendesain dengan tes integrasi, dan Anda tidak akan menemukan regresi dengan tes unit.
sumber
Saya telah menggunakan Selenium secara ekstensif untuk pemeriksaan kewarasan.
Di sebuah perusahaan penerbitan web besar, ketika rilis baru dibuat, biasanya dibutuhkan sekitar 3 penguji sekitar satu atau dua jam untuk mengunjungi semua keluarga situs dan memastikan semuanya baik-baik saja, sesuai skrip pengujian. Dengan Selenium, kami dapat mengotomatiskan pengujian, dan mendistribusikannya melalui beberapa mesin dan browser. Saat ini, ketika skrip uji dijalankan, dibutuhkan 3 PC sekitar 10 menit untuk secara otomatis melakukan hal yang sama DAN mengeluarkan laporan cantik.
Hal hebat tentang selenium adalah Anda dapat mengikatnya dengan kerangka kerja pengujian unit seperti XUnit, TestNG, atau MSTest.
Dalam pengalaman saya, itu sangat berharga, namun pengaturan sesuatu seperti itu sangat tergantung pada proyek Anda dan tim Anda, jadi ROI pasti akan bervariasi.
sumber
ROI terbaik biasanya adalah pengujian paling awal yang dapat menemukan jenis bug itu.
Pengujian unit harus menemukan sebagian besar bug yang ada hanya dalam satu metode, atau mungkin satu komponen. Ia menemukan bug yang biasanya dapat diperbaiki dalam hitungan menit, dengan waktu putaran total kurang dari satu jam. SANGAT tes murah, SANGAT bug murah untuk menemukan dan memperbaiki! Jika bug-bug itu membuatnya menjadi pengujian integrasi, turn-around bisa lebih seperti sehari (pengujian sering terjadi setiap malam), dengan asumsi bug tidak tersumbat oleh bug lain; ditambah kemungkinan ada lebih banyak bug yang diperkenalkan karena kode lain ditulis terhadap kode kereta awal; ditambah desain ulang apa pun akan memengaruhi lebih banyak potongan kode. Juga, membiarkan lebih banyak bug melalui cara harus melakukan lebih banyak pengujian berjalan sebelum pengujian integrasi dapat diselesaikan. Pengujian unit yang buruk sering kali merupakan jantung dari waktu yang lama, berat, mahalmenguji siklus integrasi. Melewati pengujian unit mungkin mengurangi separuh waktu pengembangan, tetapi pengujian akan memakan waktu 3 hingga 4 kali setidaknya, keseluruhan proyek akan berlipat ganda, dan Anda masih akan memiliki kualitas yang lebih rendah daripada jika Anda ingin unit menguji IME.
Pengujian integrasi biasanya merupakan pengujian aktual paling awal yang dapat menemukan bug integrasi (walaupun proses peninjauan dapat menemukan beberapa bug sebelum perangkat lunak ditulis, atau sebelum kode diuji). Anda ingin menemukan bug itu sebelum mulai menunjukkan perangkat lunak kepada pengguna atau melepaskannya, karena memperbaiki bug pada saat terakhir (atau hot-fixing!) Sangat mahal. Anda tidak dapat menemukan bug itu lebih awal, ketika itu akan lebih murah untuk diperbaiki, karena Anda memerlukan beberapa komponen kerja untuk diintegrasikan (menurut definisi). Pengujian integrasi akan diperlambat ketika bug yang tidak ada hubungannya dengan bagian yang berinteraksi (seperti kesalahan ketik kecil) harus diselesaikan terlebih dahulu sebelum pengujian yang lebih menarik bahkan dapat dimulai.
Pengujian penerimaan pengguna memastikan bahwa perangkat lunak melakukan apa yang diinginkan pelanggan (meskipun pelanggan semoga telah terlibat sepanjang waktu, untuk menurunkan risiko menemukan kesenjangan besar antara harapan dan perangkat lunak aktual tepat di akhir proyek - SANGAT mahal !). Pada saat Anda sampai pada tahap pengujian ini, Anda harus benar-benar percaya bahwa sebagian besar bug dalam produk Anda, dibandingkan dengan spesifikasi setidaknya, telah ditemukan. Pengujian penerimaan pengguna lebih pada memastikan produk sesuai dengan kebutuhan pelanggan daripada memastikan tidak ada bug dibandingkan dengan spesifikasinya.
Jika saya hanya akan mengotomatisasi satu jenis pengujian, itu akan menjadi unit testing. Tes integrasi dapat dilakukan secara manual dan dilakukan dengan cara seperti itu oleh banyak perusahaan besar selama bertahun-tahun. Ini lebih memakan waktu untuk secara manual melakukan pekerjaan yang dapat dilakukan oleh komputer berulang-ulang, dan jauh lebih mahal untuk sebagian besar proyek, belum lagi membosankan dan rawan kesalahan, tetapi itu bisa dilakukan. Tes penerimaan pengguna seringkali manual, karena pengguna sering tidak tahu bagaimana mengotomatiskan pengujian mereka sambil tetap menguji apa yang mereka pedulikan. Tes unit HARUS otomatis. Anda harus dapat menjalankan semua pengujian unit dalam beberapa detik sesuai permintaan sesering setiap beberapa menit. Manusia bahkan tidak bisa mendekati dengan tes manual. Belum lagi unit test ada dalam kode, dan tidak dapat dijalankan tanpa memanggil mereka melalui kode, yaitu mengotomatiskannya.
Satu hal yang perlu diingat adalah bahwa ini adalah forum terutama untuk pengembang, bukan penguji. Pengujian integrasi terutama diterapkan oleh penguji. Pengujian unit diimplementasikan oleh pengembang. Secara alami, pengembang berbicara lebih banyak tentang pengujian unit daripada jenis pengujian lainnya. Ini tidak berarti mereka tidak menganggap pengujian lain itu penting. Itu hanya berarti mereka tidak benar - benar melakukannya (atau melakukannya lebih jarang).
sumber
Saya merasa seperti tes penerimaan adalah raja dalam skenario ini.
Jika komit mematahkan tes penerimaan, itu perlu disortir.
Tes penerimaan memberi tahu Anda di mana perangkat lunak Anda berada, tes unit tidak.
Oleh karena itu unit test dapat memberikan rasa aman yang sangat palsu.
sumber
Pertanyaannya bukan apa yang lebih penting, seperti apa yang dapat diotomatisasi dan berjalan dengan cepat.
Tes unit menunjukkan apakah komponen kecil cocok untuk tujuan dengan cara tertentu, dan biasanya kecil dan cepat dijalankan. Karena kecil, biasanya cukup mudah untuk diotomatisasi.
Tes integrasi menunjukkan apakah komponen bekerja bersama. Mereka biasanya jauh lebih besar, dan mungkin tidak mudah untuk diotomatisasi. Mereka bisa membutuhkan waktu lebih lama untuk berlari. Ada nilai dalam menjalankannya secara otomatis, tetapi ini adalah tugas yang lebih besar dan mereka tidak akan sering berjalan.
Tes penerimaan menunjukkan apakah suatu proyek dapat diterima atau tidak. Ini biasanya tidak mungkin untuk diotomatisasi sepenuhnya (meskipun tes otomatis mungkin berperan), karena biasanya tidak mungkin untuk memakukan persyaratan yang tepat dan lengkap dalam masalah formal yang tidak terlalu rumit daripada kode sumber itu sendiri. Pengujian penerimaan biasanya mencakup pengguna potensial yang melakukan sesuatu dengan sistem dan mengamati bahwa hasilnya memuaskan dalam semua hal, yang biasanya sebagian subjektif. Karena pengujian penerimaan biasanya dijalankan sekali (pelanggan yang berbeda biasanya ingin melakukan tes penerimaan terpisah mereka sendiri) itu benar-benar tidak layak diotomatisasi.
sumber