it-swarm-id.com

Apa kerugian dari pemrograman test-first?

Ini semua kemarahan saat ini. "Semua orang" merekomendasikannya. Itu dengan sendirinya membuatku curiga.

Apa saja kerugian yang Anda temukan ketika melakukan pengembangan test-first (test-driven)? Saya mencari pengalaman pribadi dari praktisi yang berpengetahuan luas - saya dapat membaca renungan hipotetis dari seratus wannabes di tempat lain di internet.

Saya bertanya bukan karena saya ingin membenci TDD, tetapi karena itu adalah tugas saya untuk meningkatkan proses pengembangan perangkat lunak, dan semakin banyak yang dapat kita pelajari tentang masalah yang dihadapi orang, semakin besar peluang yang kita miliki untuk memperbaiki proses.

48
Alex Feinman

Ada beberapa, tetapi keuntungan jauh lebih besar daripada kerugiannya.

Ada kurva belajar yang curam.

Banyak pengembang tampaknya berharap bahwa mereka dapat efisien dengan pemrograman uji-pertama sejak hari pertama. Sayangnya butuh banyak waktu untuk mendapatkan pengalaman dan program dengan kecepatan yang sama seperti sebelumnya. Anda tidak bisa menyiasatinya.

Untuk lebih spesifik, sangat mudah salah. Anda dapat dengan mudah (dengan niat yang sangat baik) akhirnya menulis sejumlah tes yang sulit untuk mempertahankan atau menguji hal-hal yang salah. Sulit untuk memberikan contoh di sini - masalah seperti ini hanya membutuhkan pengalaman untuk dipecahkan. Anda harus memiliki perasaan yang baik untuk memisahkan masalah dan merancang untuk diuji. Saran terbaik saya di sini adalah melakukan pemrograman pasangan dengan seseorang yang mengenal TDD dengan sangat baik.

Anda melakukan lebih banyak pengkodean di muka.

Tes pertama berarti Anda tidak dapat melewati tes (yang bagus) dan berarti Anda akan berakhir dengan menulis lebih banyak kode di muka. Ini berarti lebih banyak waktu. Sekali lagi, Anda tidak bisa menyiasatinya. Anda mendapatkan imbalan dengan kode yang lebih mudah dipelihara, diperluas, dan umumnya lebih sedikit bug, tetapi butuh waktu.

Dapat menjadi penjualan yang sulit bagi manajer.

Manajer perangkat lunak umumnya hanya mementingkan waktu. Jika Anda beralih ke pemrograman pengujian pertama dan Anda tiba-tiba membutuhkan waktu 2 minggu untuk menyelesaikan fitur, bukan satu, mereka tidak akan menyukainya. Ini jelas merupakan pertarungan yang layak diperjuangkan dan banyak manajer cukup tercerahkan untuk mendapatkannya, tetapi ini bisa menjadi penjualan yang sulit.

Dapat menjadi penjualan yang sulit untuk sesama pengembang.

Karena ada kurva belajar yang curam, tidak semua pengembang menyukai pemrograman uji-pertama. Bahkan, saya akan menebak bahwa kebanyakan pengembang tidak suka pada awalnya. Anda dapat melakukan hal-hal seperti pemrograman pasangan untuk membantu mereka meningkatkan kecepatan, tetapi ini bisa menjadi penjualan yang sulit.

Pada akhirnya, keuntungannya melebihi kerugiannya, tetapi itu tidak membantu jika Anda mengabaikan kerugiannya. Mengetahui apa yang Anda hadapi sejak awal membantu Anda menegosiasikan beberapa kelemahan, jika tidak semua.

41
Jaco Pretorius

Tes-pertama mengasumsikan Anda sedang menulis kode yaitu:

  • diuji dalam cara unit-test
  • bahwa apa yang Anda kembangkan memiliki pendekatan yang jelas dan tidak akan memerlukan prototipe atau eksperimen yang luas
  • anda tidak perlu melakukan refactor terlalu banyak atau Anda memiliki waktu untuk menulis ulang ratusan atau ribuan kasus uji berulang kali
  • tidak ada yang disegel
  • semuanya modular
  • semuanya bisa disuntikkan atau bisa dipermainkan
  • bahwa organisasi Anda menempatkan nilai yang cukup tinggi pada cacat rendah untuk membenarkan sumber daya yang tenggelam
  • bahwa ada sesuatu yang bermanfaat untuk diuji pada tingkat unit test

Jika proyek Anda tidak memenuhi persyaratan tersebut, Anda akan mengalami kesulitan. Promotor TDD tidak memiliki jawaban yang baik untuk yang lain ini untuk menyarankan agar Anda mendesain ulang produk Anda agar lebih baik berada dalam garis itu. Ada situasi di mana itu tidak mungkin atau tidak diinginkan.

Dalam praktiknya, ada juga masalah besar bagi saya ketika orang berpikir tes pertama benar-benar membuktikan apa pun tentang fungsi program yang benar. Dalam banyak kasus ini tidak benar, tetapi bahkan dalam kasus di mana itu benar itu jauh dari gambaran lengkap tentang kebenaran. Orang melihat ratusan tes yang lulus dan menganggap aman untuk menguji kurang karena sebelum TDD mereka hanya melakukan beberapa ratus kasus uji. Dalam pengalaman saya TDD berarti bahwa Anda perlu memiliki lebih banyak tes integrasi karena pengembang juga akan memiliki keamanan palsu dan rasa sakit karena mengubah semua tes untuk melakukan redactor besar dapat membuat pengembang membuat pekerjaan yang menarik di sekitarnya.

Contoh:

Contoh terbaik pribadi saya adalah ketika menulis kode keamanan untuk asp.net. Jika mereka dimaksudkan untuk berjalan dalam lingkungan yang tidak bersahabat dari konfigurasi mesin, mereka dihadang, ditandatangani, dan disegel, dan karena mereka berlari melawan objek dewa IIS objek-objek dewa mereka sangat sulit untuk diejek banyak dengan benar. Tambahkan beberapa kendala untuk kinerja dan penggunaan memori dan Anda sangat cepat kehilangan fleksibilitas untuk menggunakan objek placeholder di area yang tersisa.

Segala jenis pengontrol mikro atau kode lingkungan sumber daya rendah lainnya tidak mungkin dilakukan dengan benar-benar gaya desain OO karena abstraksi tidak dioptimalkan dan Anda memiliki batas sumber daya yang rendah. Hal yang sama dapat dikatakan untuk rutinitas kinerja tinggi dalam banyak kasus juga.

36
Bill

Kelemahan terbesar yang saya lihat bukan dengan TDD itu sendiri tetapi dengan praktisi. Mereka mengambil pendekatan dogmatis dan fanatik di mana semuanya harus diuji . Terkadang (berkali-kali), itu tidak perlu. Juga, ini mungkin tidak praktis (mis. Memperkenalkan organisasi ke TDD.)

Seorang insinyur yang baik menemukan timbal balik dan menerapkan keseimbangan yang tepat kapan/di mana/bagaimana menerapkan tes-pertama. Juga, jika Anda menemukan diri Anda terus-menerus menghabiskan lebih banyak waktu mengembangkan tes daripada kode yang sebenarnya (dengan faktor 2-3 atau lebih), Anda dalam masalah.

Dengan kata lain, bersikap pragmatis dan masuk akal dengan TDD (atau apa pun dalam pengembangan perangkat lunak dalam hal ini.)

26
luis.espinal

Saya mulai melakukan TDD pada awal Agustus 2009 dan meyakinkan seluruh perusahaan saya untuk beralih ke hal itu pada bulan September/Oktober 2009. Saat ini, seluruh tim pengembang sepenuhnya dikonversi, dan melakukan kode yang belum diuji ke repo dianggap sebagai Hal Buruk dan dibuang. Ini telah bekerja dengan baik bagi kami, dan saya tidak bisa membayangkan beralih kembali ke pengkodean koboi.

Namun, ada dua masalah yang cukup mencolok.

Test suite harus dipertahankan

Ketika Anda serius tentang TDD, Anda akan berakhir menulis lot tes. Selain itu, perlu beberapa waktu dan pengalaman untuk menyadari apakah granularitas benar (terlalu banyak bekerja sama buruknya dengan melakukan yang terlalu rendah). Tes-tes ini juga kode , dan mereka rentan terhadap bitrot. Ini berarti bahwa Anda harus mempertahankannya seperti yang lainnya: perbarui ketika Anda memutakhirkan pustaka yang menjadi andalannya, refactor dari waktu ke waktu ... Saat Anda membuat perubahan besar dalam kode Anda, banyak tes tiba-tiba akan menjadi ketinggalan zaman atau bahkan jelas salah. Jika Anda beruntung, Anda bisa menghapusnya, tetapi sering kali Anda akan mengekstraksi bit yang berguna dan mengadaptasinya ke arsitektur baru.

Pengujian abstraksi bocor dari waktu ke wakt

Kami menggunakan Django, yang memiliki kerangka pengujian yang cukup bagus. Namun, terkadang ia membuat asumsi yang sedikit bertentangan dengan kenyataan. Misalnya, beberapa middleware dapat memecahkan tes. Atau, beberapa tes membuat asumsi tentang backend caching. Juga, jika Anda menggunakan "nyata" db (bukan SQLite3), maka mempersiapkan db untuk tes akan memakan banyak waktu. Tentu, Anda dapat (dan harus) menggunakan SQLite3 dan db dalam-memori untuk tes yang Anda lakukan secara lokal, tetapi beberapa kode hanya akan berperilaku berbeda tergantung pada database yang Anda gunakan. Menyiapkan server integrasi berkelanjutan yang berjalan dalam pengaturan realistis adalah suatu keharusan.

(Beberapa orang akan memberi tahu Anda bahwa Anda harus mengejek semua hal seperti database, atau tes Anda tidak "murni," tetapi itu hanya berbicara tentang ideologi. Jika Anda membuat kesalahan dalam kode ejekan Anda (dan percayalah, Anda akan), testuite Anda akan menjadi tidak berharga.)

Ini semua mengatakan, masalah yang saya jelaskan mulai terlihat hanya ketika Anda cukup maju dengan TDD ... Ketika Anda baru mulai dengan TDD (atau mengerjakan proyek yang lebih kecil) tes refactoring tidak akan menjadi masalah.

6
Ryszard Szopa

Bagi saya ada beberapa masalah psikologis yang mendalam dengan tes setiap kali saya mencoba menerapkannya secara luas, seperti pada TDD: jika ada, saya kode sembarangan karena saya percaya bahwa tes akan menangkap masalah. Tetapi jika tidak ada tes untuk menyediakan jaring pengaman, saya kode dengan hati-hati, dan hasilnya selalu lebih baik daripada dengan tes.

Mungkin hanya aku. Tetapi saya juga pernah membaca di suatu tempat bahwa mobil dengan semua jenis lonceng & peluit cenderung lebih sering menabrak (karena pengemudi tahu bahwa fitur keselamatan ada di sana), jadi mungkin ini sesuatu yang perlu diketahui; TDD dapat tidak kompatibel dengan beberapa individu.

4
Joonas Pulakka

Satu situasi di mana tes pertama benar-benar menghalangi saya adalah ketika saya ingin dengan cepat mencoba beberapa ide dan melihat apakah itu bisa berfungsi sebelum saya menulis implementasi yang tepat.

Pendekatan saya biasanya:

  1. Menerapkan sesuatu yang berjalan (proof of concept).
  2. Jika berhasil, berkonsolidasi dengan menambahkan tes, meningkatkan desain, refactoring.

Terkadang saya tidak sampai ke langkah 2.

Dalam hal ini, menggunakan TDD ternyata memiliki lebih banyak kerugian daripada keuntungan bagi saya:

  • Menulis tes selama implementasi bukti konsep hanya memperlambat saya dan mengganggu aliran pemikiran saya: Saya ingin memahami sebuah ide dan saya tidak ingin membuang waktu untuk menguji rincian implementasi kasar pertama saya.
  • Mungkin butuh waktu lebih lama untuk mengetahui apakah ide saya berharga atau tidak.
  • Jika ternyata ide itu tidak berguna, saya harus membuang kedua kode saya dan tes unit yang ditulis dengan baik.

Jadi, ketika saya harus menjelajahi beberapa ide baru, saya tidak menggunakan TDD dan hanya memperkenalkan unit test ketika saya merasa kode baru tersebut mencapai suatu tempat.

2
Giorgio

Kekurangan atau Biaya TDD

Catatan: Ada berbagai jenis TDD. Terlepas dari unit, BDD, ATDD, atau varian lain banyak kesulitan tetap

Efek samping

Baik itu mengejek, perlengkapan atau tes fungsional, ketergantungan pada kondisi eksternal atau sistem sering kali menjadi sumber paling rumit dalam pengujian, kebingungan dalam cara menguji, dan risiko terbesar jika salah melakukannya. Beberapa masalah yang pernah saya lihat:

  • Mengejek: lupa menegaskan urutan panggilan
  • Mengolok-olok: mengolok-olok tidak cocok dengan panggilan atau respons nyata
  • Fixture: tes bergantung pada data yang tidak realistis, menutupi masalah lain
  • Fixture: menguji keadaan yang mustahil dalam produksi
  • Fungsional: false build break karena sistem dependen tidak tersedia untuk sementara
  • Fungsional: kecepatan tes sangat lambat

Anda harus mengubah pendekatan Anda ke pengkodean, untuk beberapa itu akan menjadi perubahan drastis.

Kode orang berbeda dengan cara yang sangat berbeda. Di TDD Anda harus mulai dengan tes yang menegaskan perilaku tertentu, dan kemudian menerapkannya sehingga tes berlalu. Saya telah melihat dan merupakan seorang programmer yang pemrogramannya tidak kondusif untuk TDD. Butuh waktu sekitar 2 bulan ketika saya awalnya mulai terbiasa mengubah pendekatan pengembangan saya.

Butuh waktu untuk memahami apa yang Anda pedulikan tentang pengujian dan apa yang tidak Anda pedulikan tentang pengujian.

Setiap tim harus membuat keputusan eksplisit tentang di mana mereka ingin menarik garis dalam pengujian. Hal-hal apa yang mereka nilai yang ingin mereka uji, dan apa yang tidak. Seringkali proses yang menyakitkan mempelajari cara menulis tes yang baik, dan apa yang sebenarnya Anda pedulikan tentang pengujian. Sementara itu kode akan terus dalam keadaan fluks sampai ada konsistensi dalam gaya dan pendekatan.

ji Unit spesifik: refaktor besar

Sebuah refactor besar atau mendasar dari basis kode signifikan dengan puluhan ribu unit test akan menghasilkan biaya besar untuk memperbarui semua tes. Ini akan sering terwujud dalam pushback terhadap melakukan refactor bahkan jika itu adalah hal yang benar untuk dilakukan hanya karena biaya yang terkait dengan melakukannya.

1
dietbuddha

Analogi saya adalah hambatan pada trek Scalextric. Jika Anda memakainya, Anda menjadi kurang berhati-hati.

Orang-orang juga mendapatkan sedikit ruang cadetish tentang tes mereka - karena mereka berjalan dengan baik, mereka percaya kode tersebut sepenuhnya diuji padahal itu hanyalah awal dari proses pengujian.

Dalam pikiran saya TDD adalah batu loncatan ke BDD. Rakit tes yang berjalan tidak benar-benar membantu mendukung pengembang tanpa mengetahui apa yang dilakukan tes. Dengan BDD, output tes dalam bahasa Inggris yang mendokumentasikan pengujian dan dengan demikian membangun pemahaman sistem.

0
Robbie Dee