Kami telah mencoba memperkenalkan pengujian otomatis pengembang beberapa kali di perusahaan saya. Tim QA kami menggunakan Selenium untuk mengotomatisasi tes UI, tetapi saya selalu ingin memperkenalkan tes unit dan tes integrasi. Di masa lalu, setiap kali kami mencobanya, semua orang bersemangat untuk satu atau dua bulan pertama. Kemudian, beberapa bulan kemudian, orang-orang berhenti melakukannya.
Beberapa pengamatan dan pertanyaan:
Apakah pengujian otomatis benar-benar berfungsi? Sebagian besar kolega saya yang dulu bekerja di perusahaan lain telah mencoba dan gagal menerapkan strategi pengujian otomatis. Saya masih belum melihat perusahaan perangkat lunak kehidupan nyata yang benar-benar menggunakannya dan tidak hanya membicarakannya. Begitu banyak pengembang melihat pengujian otomatis sebagai sesuatu yang hebat dalam teori tetapi tidak berhasil dalam kenyataan. Tim bisnis kami akan senang pengembang untuk melakukannya bahkan dengan biaya waktu tambahan 30% (setidaknya mereka mengatakan demikian). Tetapi pengembang skeptis.
Tidak ada yang benar-benar tahu cara melakukan pengujian otomatis dengan benar. Ya, kita semua membaca contoh pengujian unit di internet, tetapi menggunakannya untuk proyek besar adalah hal lain. Penyebab utama adalah mengejek / mematikan database atau hal lain yang tidak sepele. Anda akhirnya menghabiskan lebih banyak waktu mengejek daripada menulis tes yang sebenarnya. Kemudian ketika mulai memakan waktu lebih lama untuk menulis tes daripada kode, saat itulah Anda menyerah.
Apakah ada contoh yang baik dari tes unit / tes integrasi sistem yang digunakan dalam aplikasi web data centric yang kompleks? Adakah proyek sumber terbuka? Aplikasi kami adalah data centric tetapi juga memiliki banyak logika domain. Saya mencoba pendekatan repositori di beberapa titik dan menemukan itu cukup bagus untuk pengujian unit, tetapi itu datang pada harga untuk dapat mengoptimalkan akses data dengan mudah dan menambah lapisan kompleksitas.
Kami memiliki proyek besar yang dikerjakan oleh 20 pengembang berpengalaman. Ini akan menjadi lingkungan yang ideal untuk memperkenalkan pengujian unit / pengujian integrasi.
Mengapa itu tidak berhasil untuk kita? Bagaimana Anda membuatnya bekerja di perusahaan Anda?
sumber
Jawaban:
Bagian tersulit dari melakukan pengujian unit adalah mendapatkan disiplin untuk menulis tes pertama / awal. Sebagian besar pengembang terbiasa hanya menyelam ke dalam kode. Ini juga memperlambat proses pengembangan sejak Anda mencoba mencari cara untuk menulis tes untuk kode. Namun, saat Anda menjadi lebih baik dalam pengujian, ini mempercepat. Dan karena tes penulisan, kualitas awal kode dimulai lebih tinggi.
Saat memulai, cobalah menulis tes saja. Jangan terlalu khawatir tentang mengejek / mematikan hal pada awalnya. Buat tes sederhana. Tes adalah kode dan dapat / harus di refactored. Meskipun sepanjang garis itu jika ada sesuatu yang sulit untuk diuji, itu bisa juga desain. TDD memang bergerak ke arah menggunakan sebagian besar pola desain (dalam pengalaman saya, terutama pola Pabrik).
Pastikan bahwa tes mendapatkan tingkat visibilitas. Integrasikan mereka dalam proses rilis, selama tinjauan kode, tanyakan tentang mereka. Setiap bug yang ditemukan harus mendapatkan tes. Di sinilah TDD bersinar.
Berikut adalah beberapa sumber yang menurut saya berguna:
http://misko.hevery.com/attachments/Guide-Writing%20Testable%20Code.pdf
http://www.agitar.com/downloads/TheWayOfTestivus.pdf
Sunting:
Satu hal yang perlu diingat ketika Anda menulis tes. Anda tidak mencoba menentukan apa pun tentang implementasi kode, hanya perilaku. Saat Anda menulis kode, Anda mengujinya setiap saat. Mencoba menjalankannya dengan pernyataan debug dan sebagainya. Tes menulis memformalkan ini dan memberikan catatan tes yang Anda miliki. Dengan begitu Anda dapat memeriksa fungsionalitas Anda dengan percaya diri tanpa sengaja melewatkan test case yang Anda ingat di tengah proses pengembangan.
sumber
Dalam banyak hal saya setuju dengan tim Anda.
Sebagian besar unit test dipertanyakan nilainya. Karena sebagian besar tes tampaknya terlalu sederhana.
Adalah jauh lebih sulit untuk menulis kode yang dapat diuji dengan baik daripada hanya kode yang berfungsi. Ada sebagian besar komunitas pengembang yang percaya hanya membuatnya berfungsi, versus kualitas kode / desain itu sendiri. Dan persentase yang lebih besar lagi yang bahkan tidak tahu kode kualitas itu.
Diperlukan waktu lebih lama untuk menulis kode uji unit daripada kode yang sebenarnya.
Mencari cara untuk menguji secara memadai kode yang lebih rumit (mis. Hal-hal yang Anda benar-benar tertarik untuk menguji secara menyeluruh) berada di luar kemampuan banyak pengembang.
Mempertahankan tes unit membutuhkan waktu terlalu banyak. Perubahan kecil dapat memiliki efek riak besar. Tujuan utama dari tes unit otomatis adalah untuk mengetahui apakah perubahan memecahkan kode. Namun, 99% dari waktu yang akhirnya melanggar adalah tes dan bukan kode.
Dengan semua masalah di atas, masih belum ada cara yang lebih baik untuk dapat membuat perubahan kode dan memiliki tingkat kepercayaan bahwa sesuatu tidak putus secara tidak terduga daripada mengotomatisasi tes Anda.
Beberapa hal di atas dapat dikurangi sampai taraf tertentu dengan tidak membaca buku teks unit testing.
Banyak jenis desain / aplikasi yang lebih baik diuji dengan mengotomatisasi tes di tingkat modul / paket. Dalam pengalaman saya, sebagian besar kesalahan pengkodean bukan karena kode dalam suatu kelas dikodekan secara tidak benar tetapi karena pengkode tidak mengerti bagaimana kelas mereka seharusnya bekerja dengan kelas-kelas lain. Saya telah melihat banyak bang untuk uang dalam jenis pengujian ini. Tetapi sekali lagi, tes ini lebih sulit untuk ditulis daripada tes unit (level kelas).
Itu benar-benar bermuara pada apakah pengembang percaya pada proses atau tidak. Jika ya, maka mereka akan menulis unit test yang baik, menemukan kesalahan lebih awal dan menjadi pendukung. Jika tidak, maka unit test mereka pada umumnya tidak berguna dan tidak akan menemukan kesalahan dan teori unit test mereka menjadi tidak berguna akan terbukti benar (dalam pikiran mereka).
Intinya adalah bahwa saya belum pernah melihat pendekatan pengujian unit otomatis penuh sesak nafas bekerja selama lebih dari beberapa bulan sendiri, tetapi gagasan tes unit otomatis masih bertahan meskipun kami selektif dalam apa yang benar-benar membutuhkan pengujian. Pendekatan ini cenderung memiliki jauh lebih sedikit kritik dan lebih diterima oleh semua pengembang daripada hanya sedikit.
sumber
Frobinate()
metode tingkat atas (bukan lusinan metode yang lebih kecil disebut di bawahnya) setelah sistem telah diverifikasi dengan cara lain untuk melayani sebagai tes asap bahwa tidak ada perubahan level bawah yang merusak apapun. Umumnya tes ini menggunakan data yang sama yang merupakan bagian dari pound pada tes pengguna keyboard yang disediakan sehingga pelanggan dapat melihat bahwa sistem melakukan apa yang mereka inginkan. Setelah itu alat kode cakupan dapat mengidentifikasi di mana kasus tepi belum tercakup.Dan ada masalah Anda.
Setiap orang membuat poin bagus tentang bagaimana mengintegrasikan pengujian unit ke lingkungan Anda. Cara memaksa orang untuk melakukannya cukup sehingga mereka melihat nilai praktis dan "melekat". Tetapi jika itu sangat menyakitkan untuk dilakukan, dan / atau tidak memberikan manfaat, itu tidak akan melekat.
Mematikan database seharusnya sederhana. Alih-alih antarmuka Anda pergi ke beberapa dukungan DB untuk memberikan hasilnya, Anda memasukkan objek hardcode sederhana. Jika Anda tidak dapat melakukan itu, maka desain / arsitektur Anda memiliki masalah. Kode Anda menganggap itu akan ke database, atau Anda tidak memiliki abstraksi antarmuka untuk memvariasikannya.
Ini bukan hanya masalah pengujian / kualitas. Segera setelah Anda ingin mengubah penyedia DB, atau pergi ke cloud, atau mendukung aplikasi seluler yang tidak terhubung, desain Anda gagal. Jika Anda tidak dapat mendukung kasus fleksibilitas yang paling sederhana, Anda tentu tidak dapat mendukung hal-hal yang lebih rumit yang pasti akan dibutuhkan bisnis Anda.
sumber
Anda harus mulai dengan sesuatu yang kecil, mudah diotomatisasi, dan bernilai tinggi. Tarik beberapa buah manis, tergantung rendah, dan Anda akan dapat menjual prosesnya. Perlihatkan bagaimana hal itu menyelamatkan seseorang pada larut malam atau panggilan akhir pekan. Maka Anda dapat memperluas dari sana.
Untuk melakukan pengujian otomatis dengan baik, Anda membutuhkan seseorang yang merupakan sumber daya dan penginjil, dan yang telah membeli dari manajemen tingkat yang lebih tinggi.
Perlakukan pengembangan pengujian otomatis Anda seperti proyek gesit lainnya. Menghasilkan tes selesai secara teratur.
Menambahkan dari komentar: Itu lebih merupakan masalah manajemen. Apakah kode dianggap "selesai" sebelum didokumentasikan? Sebelum diperiksa? Sebelum itu termasuk dan lulus tes unit?
Cara Anda mendekati ini sangat tergantung pada peran Anda. Apakah Anda seorang teman? Jika demikian, perlihatkan kepada orang lain bagaimana hal itu membuat kode Anda lebih mudah bagi mereka untuk digunakan kembali dan dipelihara. Apakah Anda seorang pemimpin? Pilih programmer Anda yang memiliki masalah kode terbanyak dan bantu mereka menambahkan tes untuk menghindari masalah tersebut. Apakah Anda seorang bos? Tetapkan sebagai standar bahwa "kode tidak dilakukan sampai unit test masuk dan lewat.
sumber
Ikuti aturan dasar ini. Tes:
harus berjalan teratur! Anda dapat menjalankan tes pada setiap bangunan, sebelum / sesudah setiap checkin, atau setiap pagi. Dipicu secara otomatis lebih disukai daripada dipicu secara manual. Karena sementara dalam teori Anda dapat membuat semua orang di tim bertanggung jawab untuk memastikan mereka menjalankan tes, jika tidak otomatis, mungkin itu tidak cukup sering terjadi! Dan jika Anda tidak menjalankan tes Anda cukup sering, mereka berdua menemukan bug terlambat mendorong banyak tes yang rusak, yang mengarah ke poin 2:
Anda masih akan berhasil jika tes-tes itu, yang sekarang berjalan secara teratur, tidak menghalangi . Maksud kami tes:
Sebuah. tidak boleh terlalu lama berjalan (secara subyektif) untuk nilai yang mereka berikan! Buat tes Anda sangat cepat. Jangan biarkan orang memeriksa tes yang akan membuang-buang waktu Anda untuk membiarkannya berjalan!
b. tidak boleh tidak bisa diandalkan. Hindari tes multithreaded jika memungkinkan. Terapkan praktik rekayasa pada pengujian Anda seperti halnya kode Anda yang lain: terutama - kode tinjau pengujian Anda!
c. tidak boleh lebih sulit untuk diperbaiki dan dirawat daripada kode aktual yang diuji. Kecepatan coding Anda benar-benar akan menyedot jika perubahan satu baris kecil ke basis kode Anda mengharuskan Anda untuk memperbaiki 10 tes yang berbeda.
Dan akhirnya, aturan nomor 3. Tes tidak hanya gagal memberikan nilai negatif, seperti pada aturan 2, mereka harus memberikan nilai positif. Tes ...
Salah satu cara populer untuk melanggar aturan # 3 adalah menguji hal yang salah . Ini kadang-kadang karena tes terlalu besar atau terlalu tidak fokus. Tapi biasanya itu datang dari tidak menguji sesuatu yang akan diperhatikan pelanggan, dan menguji detail implementasi yang tidak relevan. (Tapi kadang-kadang menguji detail implementasi membuat tes juga efisien - IMO hanya perlu latihan memutuskan mana.)
Kesimpulan: aturan-aturan dasar ini mengarahkan Anda ke arah umum dari suatu disiplin pengujian berkelanjutan , yang sangat Anda idam-idamkan. Saat menguji, tanyakan pada diri Anda apakah tes ini benar-benar berkelanjutan dan dapat dipertahankan. Ingat:
Pengujian sebenarnya sulit. Anda harus berharap bahwa tes tim Anda pada dasarnya akan menyedot ketika Anda mulai menulis tes . Jangan berkecil hati. Apakah membuang tes tua, setiap kali Anda melihat mereka mengisap dan tidak berkelanjutan.
sumber
Ya, benar - jika dilakukan dengan benar. Intinya adalah bahwa penguji perlu menyesuaikan dan memperluas skrip otomatis mereka setelah insinyur menerapkan fitur baru.
Dapatkan konsultan (seseorang yang tahu bagaimana melakukannya dengan benar). Atau, investasikan lebih banyak waktu. Alternatifnya adalah memiliki tim pengujian yang lebih besar, yang melakukan pengujian yang sama secara manual (yang rawan kesalahan).
Saya tidak akan menyebut mereka "pengembang berpengalaman yang baik", jika mereka menolak untuk melakukan tes unit. Ada banyak artikel bagus tentang manfaat positif dari pengujian (baik pengujian unit maupun integrasi), dan pada akhirnya itu bermuara pada seberapa banyak bug yang membebani perusahaan Anda . Sebagai contoh, saya bekerja di sebuah perusahaan di mana kualitas penting, oleh karena itu pengujian unit dan integrasi tidak dapat dihindari. Anda dapat dengan mudah menemukan banyak artikel yang memberi tahu bahwa hanya unit test yang mengurangi jumlah bug hingga 30%! (Sebenarnya, itu berada dalam kisaran 20-90%, rata-rata 30%, tetapi masih banyak.)
Untuk membuatnya bekerja di perusahaan Anda, baik menyewa konsultan, atau menugaskan tugas ini ke insinyur senior (itu akan memakan waktu cukup lama untuk melakukannya). Dan kemudian, paksa semua orang untuk mematuhi aturan.
sumber
Mereka banyak alasan mengapa memperkenalkan pengujian otomatis mungkin gagal. Saya pikir itu bermuara pada kenyataan bahwa programmer cenderung tidak mengubah kebiasaan pengkodean mereka dan tidak sepenuhnya mampu merangkul pengujian unit.
Banyak orang yang ingin memulai dengan pengujian otomatis mencoba memperkenalkan mereka untuk basis kode yang ada. Mereka akan mencoba menulis tes integrasi yang menguji banyak fungsi aplikasi yang ada sekaligus. Tes integrasi seperti itu terkenal terlalu sulit dan terlalu mahal untuk dipertahankan. Saran: Perkenalkan pengujian otomatis untuk basis kode baru.
Tes unit adalah tes yang bagus untuk diotomatisasi. Segala sesuatu di atas (tes integrasi, tes komponen, tes sistem) dapat juga diuji secara otomatis, tetapi rasio biaya-manfaat dengan cepat menurun semakin banyak fungsionalitas diuji sekaligus. Efek negatif ini diperkuat, jika Anda membuat tes seperti itu pada fungsionalitas unit-test yang buruk. Saran: Perkenalkan pengujian otomatis pada tingkat pengujian unit dan bangun pengujian integrasi otomatis di atas dasar kokoh pengujian unit .
Dari poin di atas banyak keberhasilan pengujian otomatis tergantung pada seberapa efektif pengujian unit. Anda memiliki unit test yang efektif jika Anda merasa produktif dengan unit test. Ketika orang mulai dengan pengujian unit, mereka cenderung untuk memperbaiki kode yang ada dan kebiasaan pengkodean ke dalam tes unit. Ironisnya, ini adalah cara tersulit untuk mempelajari pengujian unit. Juga pengujian unit mengharuskan Anda mengubah cara kode Anda (misalnya menerapkan prinsip SOLID ). Sebagian besar programmer segera berhenti menulis unit test karena mereka berpikir bahwa learing curve terlalu curam dan merasa canggung untuk membungkus unit test dengan kode yang didesain tidak begitu dapat diuji. Saran: Pelajari pengujian unit dari awal dengan kode baru dan hadapi fakta bahwa Anda perlu mengubah kebiasaan pengkodean Anda.
Ada banyak faktor lain, tetapi saya menemukan bahwa bagi kebanyakan programmer sulit untuk mengubah cara mereka ke kode. Kode yang ditulis tanpa tes hanya terlihat berbeda. Jika Anda tidak dapat memasukkan kode Anda ke dalam desain yang dapat diuji, kemungkinan besar Anda akan gagal menulis tes unit yang efektif. Ini menghancurkan tanah untuk pengujian otomatis yang efektif.
Saya mengalaminya sendiri dan sekarang saya senang bekerja di perusahaan yang berhasil memperkenalkan tes otomatis. Saya bisa menulis lebih banyak tentang faktor-faktor lain, tetapi saya berpikir bahwa kebiasaan pengkodean dan pengujian unit adalah yang paling penting. Untungnya ada orang lain yang memiliki pengalaman lebih dari saya dan mengisi buku dengan pengetahuan mereka. Salah satu buku ini adalah Pengembangan Aplikasi Brownfield di .NET yang benar-benar dapat saya sarankan, karena Anda menggunakan tumpukan teknologi Microsoft.
sumber
Introduce automated tests on the unit test level and build automated integration tests on a solid foundation of unit tests.
+1Satu hal yang belum saya lihat dengan jelas dibahas dalam jawaban di atas adalah bahwa pengujian unit pada dasarnya adalah barang publik dan biaya pribadi. Saya sudah menulis posting blog di sini .
Apa yang terjadi adalah bahwa sementara serangkaian tes menguntungkan tim atau pengembang individu, menulis tes adalah biaya bagi yang melakukannya, sebagian besar waktu.
Singkatnya, kecuali menulis tes itu diberlakukan entah bagaimana - dan jawaban di atas daftar sejumlah cara berbeda untuk melakukan itu - tidak ada alasan bagi pengembang individu untuk melakukan ini.
Di salah satu perusahaan tempat saya bekerja, menulis unit test adalah bagian yang diperlukan untuk memberikan fitur. Kode baru tidak diterima kecuali tes unit adalah bagian dari komit atau fitur baru - ada ulasan kode singkat untuk setiap "tugas" yang diberikan pengembang. Mungkin bermanfaat untuk menerapkan kebijakan serupa di tempat kerja Anda.
sumber
Sangat menarik bahwa bisnis ini lebih pro-pengujian daripada pengembang! Bagi saya sepertinya tantangan terbesar Anda adalah mengatasi resistensi pengembang Anda terhadap perubahan; mereka perlu mendefinisikan kembali pemahaman mereka tentang pekerjaan mereka untuk memasukkan pengujian unit.
Tidak ada yang dapat membantu Anda lebih dari kesuksesan pengujian unit awal untuk membantu pengembang Anda mengatasi penolakan mereka dalam menulis tes ini. Jika Anda mendorong mereka untuk melakukan sesuatu yang baru, pastikan Anda mendorong dulu untuk sesuatu dengan hadiah yang hampir dijamin.
@ SkipHuffman menyentuh ini, tapi saya akan mengatakannya langsung. Beberapa hal jauh lebih cocok untuk pengujian otomatis daripada yang lain. Untuk pass pertama, saya TIDAK akan menguji database atau UI. Input dari database bisa sangat sulit diatur dan diruntuhkan. Tes output UI cenderung cepat rusak oleh perubahan tampilan dan perubahan yang sama sekali tidak relevan dengan tes Anda.
Apa yang saya sebut "middleware" sangat cocok untuk pengujian unit. Kode yang memiliki kondisi input dan output yang jelas. Jika Anda mengikuti prinsip KERING (Jangan Ulangi Diri Sendiri), Anda akan menulis beberapa kelas kecil atau fungsi untuk memecahkan masalah berulang yang unik untuk aplikasi Anda.
Unit testing adalah alat yang hebat untuk membatasi risiko mengubah komponen internal yang ada. Tulis pengujian unit sebelum mengubah komponen internal yang telah bekerja lama. Tes-tes ini membuktikan bahwa fungsi yang saat ini berfungsi dipertahankan. Ketika Anda telah membuat perubahan dan semua tes unit lulus, Anda tahu Anda belum merusak apa pun "hilir." Jika Anda menemukan masalah hilir, tambahkan unit test untuk itu!
Ron Heifitz akan mengatakan untuk "mengatasi konflik dalam nilai-nilai yang dipegang orang, atau untuk mengurangi kesenjangan antara nilai-nilai yang diperjuangkan orang dan kenyataan yang mereka hadapi. Pekerjaan adaptif membutuhkan perubahan dalam nilai, kepercayaan, atau perilaku." Setelah Anda mengatasi resistensi manusia untuk berubah, Anda dapat bercabang ke area pengujian yang lebih sulit yang sesuai.
sumber
Satu hal tentang pengujian otomatis adalah mengharuskan Anda untuk menulis kode agar dapat diuji. Ini bukan hal yang buruk di dalam dan dari dirinya sendiri (sebenarnya itu baik karena itu mencegah banyak praktik yang sebagai aturan harus dihindari), tetapi jika Anda mencoba menerapkan pengujian unit ke kode yang ada maka kemungkinan tidak telah ditulis dengan cara yang dapat diuji.
Hal-hal seperti lajang, metode statis, pendaftar, pelacak layanan dan sebagainya memperkenalkan dependensi yang sangat sulit untuk diejek. Pelanggaran Hukum Demeter berarti bahwa terlalu banyak bagian dari basis kode Anda yang tahu terlalu banyak tentang bagaimana bagian-bagian lain dari basis kode Anda berfungsi, memperkenalkan ketergantungan tersembunyi lebih lanjut yang mungkin sulit untuk dipatahkan. Semua hal ini membuatnya sulit untuk mengisolasi modul dari sisa basis kode, dan jika Anda tidak dapat menguji modul Anda dalam isolasi maka unit test kehilangan banyak nilainya. Jika tes gagal apakah itu karena kesalahan dalam unit yang diuji, atau karena kesalahan dalam salah satu dependensinya, atau mungkin itu karena data yang ditarik melalui sumber data dependen bukan seperti yang diharapkan oleh penulis tes ? Jika kamu bisa'
Kebanyakan basis kode yang saya lihat yang tidak dibangun dengan pengujian unit dalam pikiran cenderung secara inheren tidak dapat diuji, karena pembuat kode cenderung berfokus pada membuat kode berfungsi seperti yang mereka harapkan daripada melakukan pekerjaan yang diperlukan untuk menjaga sambungan tetap longgar dan ketergantungan secara eksplisit. . Kode yang ditulis dengan pengujian unit dalam pikiran cenderung terlihat sangat berbeda.
Banyak orang mengambil pendekatan naif untuk pengujian unit ketika mereka mulai melakukannya untuk pertama kalinya, mereka pikir mereka bisa menulis banyak tes untuk basis kode yang ada dan semuanya akan baik, tetapi tidak pernah berhasil seperti itu karena masalah yang disebutkan di atas. Mereka mulai menemukan bahwa mereka harus mengesampingkan jumlah pengaturan dalam tes unit untuk menjalankannya sama sekali, dan hasilnya sering dipertanyakan karena kurangnya isolasi dalam kode berarti Anda tidak dapat melacak apa yang menyebabkan kegagalan pengujian. Mereka juga cenderung mulai mencoba untuk menulis tes "pintar" yang menunjukkan beberapa aspek yang sangat abstrak tentang bagaimana sistem seharusnya bekerja. Ini cenderung gagal karena unit test "pintar" adalah sumber potensi bug itu sendiri. Apakah tes gagal karena bug dalam modul yang diuji, atau karena bug dalam ujian? Tes harus sangat sederhana sehingga jelas tidak ada kemungkinan bug bisa bersembunyi di dalamnya. Sebenarnya tes terbaik jarang lebih dari 2 baris, baris pertama memerintahkan unit yang diuji untuk melakukan sesuatu, yang kedua menyatakan bahwa apa yang dilakukannya adalah apa yang diharapkan.
Jika tim Anda serius untuk mengadopsi pengujian unit, maka tidak bijaksana untuk memulai dengan proyek yang ada. Proyek tim Anda yang sudah ada mungkin tidak dapat diuji tanpa refactoring besar. Anda lebih baik menggunakan proyek baru sebagai dasar belajar tentang pengujian unit, karena Anda memiliki batu tulis yang bersih untuk bekerja dengannya. Anda dapat mendesain basis kode baru untuk mendukung injeksi ketergantungan lebih dari lajang, pendaftar dan dependensi tersembunyi lainnya, Anda dapat menulisnya bergantung pada antarmuka alih-alih implementasi dan sebagainya. Anda juga dapat (dan harus) menulis tes di samping kode yang diuji, karena menulis tes kemudian menghasilkan tes unit yang memastikan modul yang diuji melakukan apa yang menurut Anda seharusnya dilakukan daripada tes yang menguji yang dilakukannya. apa yang harus dilakukan oleh spesifikasi.
Setelah Anda mendapatkan kepercayaan diri dengan pengujian unit, tim Anda mungkin akan mulai menyadari kekurangan dalam kode mereka yang ada yang akan menjadi hambatan untuk tes unit. Ini adalah saat Anda dapat mulai bekerja untuk memperbaiki kode yang ada agar lebih dapat diuji. Jangan ambisius dan berusaha melakukan ini sekaligus, atau mencoba mengganti sistem yang bekerja dengan yang sama sekali baru, cukup mulai dengan menemukan bit basis kode yang dapat dengan mudah diuji (yang tidak memiliki dependensi atau di mana dependensi terlihat jelas) dan tulis tes untuk itu. Saya tahu saya katakan menulis tes di samping kode lebih disukai daripada menulis tes setelah, tetapi bahkan tes yang ditulis kemudian masih memiliki nilai sebagai titik awal. Tulis tes seolah-olah Anda tidak tahu apa-apa tentang cara kerja kelas selain apa yang harus dilakukan spesifikasinya. Ketika Anda menjalankan tes dan mendapatkan kegagalan, maka spesifikasi atau implementasinya salah. Periksa keduanya untuk menentukan yang salah dan perbarui tes atau kode yang sesuai.
Setelah Anda memilih buah yang menggantung rendah, pekerjaan Anda yang sebenarnya dimulai. Anda harus mulai menemukan dependensi tersembunyi di basis kode Anda dan memperbaikinya, satu per satu. Jangan terlalu ambisius pada saat ini, cukup lakukan satu modul pada satu waktu, atau bahkan hanya satu masalah dalam satu modul, sampai hambatan untuk pengujian diperbaiki dan Anda dapat beralih ke bit berikutnya.
TL: DR: Sebagian besar orang berpikir pengujian itu mudah dan Anda dapat memasang kembali tes ke kode yang ada dengan mudah. Kedua asumsi ini salah. Jika Anda memulai suatu proyek untuk mendapatkan unit testing ke dalam proyek Anda dengan kedua fakta ini dalam pikiran Anda lebih mungkin untuk berhasil.
sumber
Jika tidak, inisiatif pengujian otomatis mungkin akan gagal. Pengujian otomatis adalah keterampilan, seperti banyak keterampilan lain dalam pemrograman, dan jika Anda tidak memiliki orang yang berpengalaman melakukannya, tidak mudah untuk mengatakan apakah tes otomatis adalah tes otomatis yang baik dengan nilai nyata, atau yang buruk yang akan gagal secara acak / memerlukan pembaruan yang sering / sebenarnya tidak menggunakan kode menarik.
Jika tidak ada yang mendengarkan, tidak masalah jika mereka mengatakan tes ini tidak baik. (Perhatikan bahwa kekuatan kepemimpinan tidak harus diformalkan. Memiliki tim yang peduli juga baik.)
Pengembang malas. Anda perlu membuat hal-hal yang Anda ingin mereka lakukan mudah dicapai, dan hal-hal yang Anda tidak ingin mereka lakukan lebih sulit untuk dicapai. Anda harus memastikan perpustakaan pengujian membuatnya mudah untuk melakukan tugas-tugas yang terkait dengan pengaturan uji dan teardown, terutama pengaturan yang berhubungan dengan lingkungan, seperti database pengujian atau sejenisnya. (Mengejek basis data dibahas dalam beberapa komentar ini tetapi harus digunakan dengan hati-hati. Basis data nyata harus mudah diputar, dan memungkinkan Anda menguji interaksi komponen dan proses siklus hidup, seringkali lebih penting dan lebih efektif daripada pengujian unit pengakses data individu.)
Anda juga harus memastikan bahwa IDE Anda memiliki cara yang baik untuk meluncurkan test suite. Anda harus menjalankan test suite sesering mungkin agar orang-orang memperhatikan ketika itu gagal daripada membiarkannya bertahan dalam kesengsaraan. Pengembang juga merespons dengan baik umpan balik, misalnya sistem integrasi otomatis mengembalikan perubahan mereka jika mereka telah melanggar tes. Atau, umpan balik positif yang lebih baik: sistem integrasi otomatis yang menangkap bug, dan menyelamatkan Anda dari kerusakan.
sumber
Pertama, jika pengembang Anda tidak melihat nilai tes Anda, maka itu mungkin karena tes Anda tidak berharga, bukan karena pengembang Anda tidak mengetahui nilai tes mereka, atau dengan nilai tes pada umumnya. Di antara penginjilnya, ada kecenderungan untuk percaya bahwa pengembangan yang digerakkan oleh ujian tidak dapat gagal, itu hanya dapat gagal oleh pengembang yang malas dan malas. Saya pikir ini salah dan kontraproduktif.
Ketika saya diperkenalkan dengan pengembangan yang digerakkan oleh tes, itu berarti, secara efektif, menulis tes untuk memverifikasi bahwa metode yang tidak akan pernah gagal tidak pernah gagal. Yang bagus, pada awalnya, karena Anda mendapatkan cek hijau yang indah dan rasa prestasi. Kemudian, setelah Anda membuat ulang kode, Anda memiliki puluhan X merah yang menyebalkan, tidak ada yang mengatakan lebih dari itu kode telah berubah, bahwa tes tidak lagi valid, dan bahwa Anda membuang banyak waktu untuk menulisnya.
Anda ingin menghindarinya.
Sejak itu, saya mengambil pendekatan berbeda untuk tes. Alih-alih pasangan implementasi antarmuka , saya memiliki antarmuka, implementasi, test triple . Antarmuka menentukan perilaku, implementasi melakukan perilaku, tes memeriksa perilaku.
Saya kira itu tampak jelas, tetapi bagi saya, itu membedakan antara kode Anda harus membuktikan bekerja sebagaimana ditentukan dan kode Anda dapat menguji sebanyak atau sesedikit yang Anda anggap tepat. Kode yang harus Anda buktikan adalah antarmuka yang Anda tawarkan ke luar; sisanya adalah urusanmu sendiri.
Dalam hal ini, saya akan bertanya kepada pengembang apakah mereka melihat pembagian alami dalam kode di mana tes semacam ini akan sesuai. Apakah ada antarmuka yang mengimplementasikan Tim A dan menggunakan Tim B? Dalam hal ini, adalah kepentingan Tim B untuk memastikan bahwa antarmuka berperilaku seperti yang mereka harapkan. Minta Tim B untuk menulis tes untuk itu, kemudian beri tahu Tim A untuk memastikan bahwa implementasi mereka sesuai dengan tes; atau, jika tidak, dan dengan sengaja tidak, untuk mendiskusikan perubahan yang tidak terduga dengan tim lain, sehingga mereka dapat bersiap untuk itu.
Saya pikir ini akan menggambarkan nilai tes. Itu bukan tujuan itu sendiri, cek hijau yang indah. Itu ada untuk membuat secara eksplisit janji yang dibuat oleh satu pengembang ke pengembang lain, dan untuk memastikan bahwa janji itu dipenuhi untuk kepuasan keduanya.
sumber
Menambahkan banyak unit test ke proyek besar yang sudah ada sebelumnya adalah kerja keras. Jika Anda sudah menemukan kerangka kerja mengejek yang bagus yang cocok untuk Anda, maka Anda seharusnya sudah memecahkan masalah yang paling sulit.
Saya sarankan mencoba menambahkan tes saat Anda menambahkan fitur / memperbaiki bug. Memperbaiki bug menjadi yang paling mudah. Tulis tes yang gagal karena bug Anda dan kemudian perbaiki bug. Pada saat yang sama Anda mungkin akan menemukan diri Anda menulis beberapa tes sederhana yang lulus. Tentu saja Anda benar-benar ingin menggunakan kode yang kecil dan mudah diuji untuk ini.
Begitu orang-orang mulai terbiasa menulis tes untuk hal-hal yang lebih mudah, semoga Anda mendapati mereka menulis kode mereka agar lebih mudah diuji.
Saya juga merekomendasikan agar Anda mengukur cakupan kode dari tes Anda (sebelumnya saya pernah menggunakan cobertura untuk Java). Anda ingin memiliki server integrasi berkelanjutan yang menjalankan tes dan memproduksi metrik secara teratur (setiap hari, setiap check-in). Jika rekan pengembang Anda tertarik maka mereka akan ingin melihat cakupan meningkat dari waktu ke waktu dan mereka dapat melihat celah cakupan menganga di beberapa dari Anda
sumber
Saya pikir Anda mungkin harus memainkan permainan panjang. Satu hal yang dapat Anda lakukan untuk mendapatkan penerimaan adalah mencoba menguji unit secara menyeluruh pada fitur berikutnya yang Anda tulis dan kemudian melacak jumlah bug dari waktu ke waktu. Mudah-mudahan Anda seharusnya menemukan bahwa bug utama akan ditangkap sejak dini (terutama jika Anda menyandingkan ini dengan Desain yang Didorong oleh Tes) dan jumlah regresi harus sangat rendah. Setelah jangka waktu tertentu, katakanlah 1 tahun, bandingkan statistik dengan fitur yang tidak diuji dalam unit dengan kompleksitas yang sama. Jika Anda dapat menunjukkan bahwa jumlah bug dan regresi baru jauh lebih rendah maka Anda telah memberikan justifikasi keuangan untuk itu dan itu menjadi lebih sulit untuk diabaikan oleh tim produk.
Saya memiliki situasi di mana saya dapat menggunakan TDD dan pengujian unit untuk fitur utama. Setelah akhir fase pengembangan, tidak ada satu bug pun yang dilaporkan dalam lebih dari 5 tahun. Ketika peningkatan baru - dan berisiko - diminta, saya dapat mengimplementasikannya dan menangkap semua regresi dalam unit test.
sumber
Pendapat saya yang kuat bahwa nilai unit test sebagian besar diremehkan oleh banyak tim karena beberapa faktor, banyak yang sudah disorot dalam jawaban.
Seringkali pengembang berada di bawah tekanan untuk "menyelesaikan sesuatu", sehingga membuktikan bahwa blok kode berfungsi adalah bukti yang cukup bagi pelanggan. Ini hampir selalu berlaku untuk perusahaan konsultan dan QA yang digerakkan manusia: jika pelanggan tidak memerlukan pengujian unit dan memberikan demo langsung yang cukup maka pelanggan telah gagal total karena dia akan menandatangani persetujuan untuk kode yang mungkin menyembunyikan kesalahan.
Seringkali pengembang frustrasi. Menjadi seorang programmer adalah pekerjaan yang berat: menyelesaikan tugas dan pergi ke yang berikutnya adalah memuaskan, jadi semua orang ingin bergegas dan menyelesaikannya. Sampai mereka tertabrak bus dengan bug besar yang muncul berbulan-bulan setelah QA asli. Dalam skenario ini, QA otomatis dan berkelanjutan adalah masalah manajemen daripada pengembang (mereka masih akan dibayar untuk pekerjaan mereka, mungkin lembur).
Namun ada pengecualian
Saya sangat percaya bahwa penerimaan model tes otomatis adalah fungsi dari "kemanusiaan" dari tes yang dilakukan. Jika Anda menguji modul web dengan ujung depan, Anda lebih mungkin, meskipun alat seperti Selenium, untuk mengisi formulir sendiri, lihat hasilnya dan percaya pada determinisme. Anda akan lupa untuk menjalankan kembali pengujian nanti atau Anda hanya akan terlalu malas untuk melakukan tes lama lagi, dan inilah sebabnya bug terkadang ditemukan kemudian. Untuk meningkatkan ini, modularisasi kode yang kuat dan aturan ketat tentang "modifikasi kode lama" telah terbukti dapat diterima di lingkungan perbankan (dalam pengalaman kerja pribadi saya).
Alih-alih, jika pengembang bertanggung jawab mengembangkan modul data yang sangat otomatis dan bervolume tinggi, ia akan lebih cenderung menulis tes unit menyeluruh dan mengirimkannya ke batch uji. Ini karena mengisi muatan XML yang besar dengan data yang dikonversi dari sumber data eksternal (diejek atau tidak) bukanlah pekerjaan yang rentan terhadap manusia. Beberapa pengembang pengujian pada akhirnya akan membuat ujung depan yang mungil dan lucu untuk jenis pengujian khusus ini. Ketika saya bekerja di tesis Master saya, saya sedang mengerjakan bus logging yang menangani 6000+ pesan syslog per detik dan saya harus mengukur packet loss dan korupsi: Saya secara alami menulis unit dan stress test untuk hampir semua komponen, terutama parser Syslog.
Agar pengembang lebih rentan terhadap unit test
Saya percaya mereka harus dipaksa. Jika Anda adalah pelanggan yang cerdas, Anda akan meminta konsultan Anda untuk menjalankan test suite lengkap di setiap QA. Jika Anda adalah pemimpin tim yang baik, Anda mungkin berpikir menugaskan tugas berikut untuk pengembang yang cerdas: membangun platform pengujian dalam. Itu tidak ada yang terlihat dengan antipatter platform efek dalam, tetapi sebaliknya adalah satu set kelas pembantu, bohongan basis data, konfigurasi, parser, konverter, pisau tentara swiss untuk membantu pengembang membuat tes dalam waktu singkat.
Platform pengujian saat ini seperti NUnit bersifat umum dan memungkinkan Anda untuk memverifikasi pernyataan umum. Menggunakan injeksi ketergantungan dengan benar dan pabrik khusus proyek membantu pengembang menulis lebih sedikit kode untuk pengujian dan lebih bahagia. Saya belum memiliki kesempatan untuk melakukan percobaan ini pada proyek penuh, saya tidak dapat memberikan umpan balik kehidupan nyata.
sumber
Pengujian otomatis seperti pengembangan perangkat lunak. Sayangnya orang yang Anda pekerjakan untuk pengujian pada awalnya dimaksudkan untuk menulis kasus pengujian, rencana, strategi, mengikuti proses peninjauan, menguji secara manual, dan mencatat bug.
Segera setelah mereka diberikan tanggung jawab pengujian otomatis, ini mencakup sejumlah pengembangan perangkat lunak. Masalahnya di sini adalah, bahwa pengujian otomatis, terlepas dari alat apa yang Anda gunakan (dan demi kebaikan jangan berdebat tentang hal ini), perlu pemeliharaan dan pembaruan setiap hari. Saat pengembang mengubah kode,
non-functional
tes terpisah, dan jangan berharap mereka menjalankannya setiap hari, butuh waktu untuk menjaga ini uptodate, dan bagus. Tapi jangan menyerah, pastikan mereka dipertahankan.Anda gagal karena alasan ini
if
danwhile
loop. Karena terus terang tidak ada kursus yang mengajarkan pengujian otomatis, mereka hanya mengajarkan pengujian manual.Ini dari pengalaman saya bekerja untuk perusahaan yang menganggap pengujian otomatis sangat serius dan memahami bahwa dev penting sebagai insinyur pengujian otomatis. Dan dari pengalaman saya bekerja untuk orang yang tidak tahu, mengerti perbedaannya, tidak peduli seberapa banyak Anda menjelaskannya kepada mereka.
sumber