Kerugian Pengembangan Didorong Uji? [Tutup]

192

Apa yang saya kehilangan dengan mengadopsi desain yang digerakkan oleh tes?

Daftarkan hanya yang negatif; jangan mencantumkan manfaat yang ditulis dalam bentuk negatif.

IanL
sumber
Saya menambahkan jawaban yang menyatakan bahwa BDD dapat mengurangi beberapa dari hal-hal negatif ini. Saya mendorong Anda untuk mempertimbangkan faktor ini ketika mengumpulkan input negatif Anda, karena beberapa di antaranya dapat dihilangkan dan tidak lagi dianggap negatif.
Kilhoffer
25
Untuk klarifikasi, saya tidak menentang atau untuk. Saya mencoba membuat keputusan berdasarkan informasi tentang masalah ini, tetapi kebanyakan orang yang menganjurkan TDD tidak mengerti, atau tidak akan mengakui yang negatif.
IanL
1
Judulnya menyebutkan "Pengembangan Didorong Uji", tetapi tubuh pertanyaan menyebutkan "Desain Didorong Uji". Yang mana dari dua pertanyaan ini? Ada perbedaan penting, tetapi halus antara keduanya. Desain yang digerakkan tes adalah tentang membiarkan tes yang mendorong desain perangkat lunak. Pengembangan yang digerakkan oleh tes biasanya dikaitkan dengan tes menulis sebelum kode produksi (tetapi tidak harus membiarkan tes mempengaruhi desain).
Jim Hurne
3
TDD adalah sangkar yang menahan kreativitas pengembang.
Lewis
13
tolong berhenti menutup pertanyaan-pertanyaan penting, yesus
Casper Leon Nielsen

Jawaban:

129

Beberapa kerugian (dan saya tidak mengklaim tidak ada manfaat - terutama ketika menulis fondasi proyek - itu akan menghemat banyak waktu di akhir):

  • Investasi besar waktu. Untuk kasus sederhana, Anda kehilangan sekitar 20% dari implementasi sebenarnya, tetapi untuk kasus rumit, Anda kehilangan lebih banyak.
  • Kompleksitas Tambahan. Untuk kasus kompleks, kasus pengujian Anda lebih sulit untuk dihitung, saya sarankan dalam kasus seperti itu untuk mencoba dan menggunakan kode referensi otomatis yang akan berjalan secara paralel dalam versi debug / uji coba, daripada unit test kasus paling sederhana.
  • Dampak Desain. Terkadang desainnya tidak jelas di awal dan berkembang seiring berjalannya waktu - ini akan memaksa Anda untuk mengulang pengujian yang akan menghasilkan kerugian besar. Saya akan menyarankan menunda unit test dalam kasus ini sampai Anda memiliki pemahaman tentang desain.
  • Tweaking terus menerus. Untuk struktur data dan pengujian unit algoritme kotak hitam akan sempurna, tetapi untuk algoritme yang cenderung diubah, diubah atau disetel dengan baik, ini dapat menyebabkan investasi waktu besar yang mungkin diklaim tidak dapat dibenarkan. Jadi gunakan ketika Anda berpikir itu benar-benar cocok dengan sistem dan jangan memaksakan desain agar sesuai dengan TDD.
Adi
sumber
7
Poin utama (4) adalah - sistem apa pun yang tidak terdefinisi dengan baik dan cenderung terus berubah untuk mencocokkan perilaku visual yang berkembang, AI spec yang berbeda, algoritme perilaku, dll. Akan menyebabkan investasi waktu besar dalam definisi pengujian yang diulang karena kita terus tentang mengubah hasil tes yang diinginkan.
Adi
12
Benar, tapi bukankah itu sama tanpa TDD? Tanpanya, Anda harus melakukan lebih banyak pengujian manual, yang akan mengalami masalah yang sama.
sleske
50
Bukankah "Investasi besar waktu" akan menghemat waktu Anda nanti saat mengembangkan solusi Anda? Apalagi dengan yang kompleks? Saya kira itu akan menghemat waktu Anda. Tidak memikirkan fase pemeliharaan di mana perubahan kecil dapat dengan mudah merusak sistem. ( atau mungkin saya hanya naif tentang unit + test regresi yang mencegah bug di masa depan )
Robert Koritnik
6
Sergio / Robert, saya sangat mendukung memiliki unit testing untuk sistem generik dan pasti untuk komponen yang mewakili dasar untuk sistem. Karena itu, saya akan menambahkan bahwa kita perlu membedakan antara kasus-kasus ini dan terlalu menyederhanakan kehidupan nyata dengan mencoba mengklaim bahwa setiap sistem dapat diperlakukan dengan cara ini. Tidak semua sistem dapat digeneralisasikan dan disederhanakan untuk pengujian unit dan jika Anda mencoba memaksakan sifat pengujian unit pada sistem seperti itu, Anda dapat dengan mudah menghabiskan lebih banyak waktu untuk mengoreksi pengujian unit Anda daripada benar-benar menguji hasil nyata.
Adi
3
@Adi: Saya pikir kamu salah. Menurut saya setiap sistem dapat diuji dengan cara itu, itu hanya masalah disiplin diri.
BlueLettuce16
189

Jika Anda ingin melakukan TDD "nyata" (baca: uji dulu dengan langkah-langkah merah, hijau, refactor) maka Anda juga harus mulai menggunakan mengejek / bertopik, ketika Anda ingin menguji titik integrasi.

Ketika Anda mulai menggunakan mock, setelah beberapa saat, Anda akan ingin mulai menggunakan Dependency Injection (DI) dan wadah Inversion of Control (IoC). Untuk melakukan itu, Anda perlu menggunakan antarmuka untuk semuanya (yang memiliki banyak jebakan sendiri).

Pada akhirnya, Anda harus menulis lebih banyak kode, daripada hanya melakukannya dengan "cara lama biasa". Alih-alih hanya kelas pelanggan, Anda juga perlu menulis antarmuka, kelas tiruan, beberapa konfigurasi IoC dan beberapa tes.

Dan ingat bahwa kode tes juga harus dipelihara dan dirawat. Tes harus dapat dibaca seperti yang lainnya dan butuh waktu untuk menulis kode yang baik.

Banyak pengembang tidak begitu mengerti bagaimana melakukan semua ini dengan "cara yang benar". Tetapi karena semua orang memberi tahu mereka bahwa TDD adalah satu-satunya cara yang benar untuk mengembangkan perangkat lunak, mereka hanya mencoba yang terbaik yang mereka bisa.

Ini jauh lebih sulit daripada yang mungkin dipikirkan. Seringkali proyek yang dilakukan dengan TDD berakhir dengan banyak kode yang tidak ada yang benar-benar mengerti. Tes unit sering menguji hal yang salah, dengan cara yang salah. Dan tidak ada yang setuju bagaimana tes yang baik akan terlihat, bahkan guru yang disebut.

Semua tes itu membuat jauh lebih sulit untuk "mengubah" (berlawanan dengan refactoring) perilaku sistem Anda dan perubahan sederhana menjadi terlalu sulit dan memakan waktu.

Jika Anda membaca literatur TDD, selalu ada beberapa contoh yang sangat bagus, tetapi seringkali dalam aplikasi kehidupan nyata, Anda harus memiliki antarmuka pengguna dan database. Di sinilah TDD menjadi sangat sulit, dan sebagian besar sumber tidak menawarkan jawaban yang baik. Dan jika mereka melakukannya, itu selalu melibatkan lebih banyak abstraksi: benda tiruan, pemrograman ke antarmuka, pola MVC / MVP dll., Yang lagi-lagi membutuhkan banyak pengetahuan, dan ... Anda harus menulis lebih banyak kode.

Jadi berhati-hatilah ... jika Anda tidak memiliki tim yang antusias dan setidaknya satu pengembang berpengalaman yang tahu cara menulis tes yang baik dan juga tahu beberapa hal tentang arsitektur yang baik, Anda benar-benar harus berpikir dua kali sebelum turun ke jalan TDD .

Thomas Jespersen
sumber
7
Menggunakan alat-alat seperti Pex & Moles Anda dapat dengan mudah menghindari antarmuka penulisan untuk setiap hal kecil. Tahi lalat akan sangat membantu Anda dengan itu.
Robert Koritnik
24
Sepertinya kritik terhadap pengujian unit dan pemrograman berorientasi objek, bukan TDD.
plmaheu
5
Sebenarnya benar ** pengujian unit ** - tidak hanya TDD – membutuhkan mock / stubs. Dan pemrograman terhadap antarmuka seringkali merupakan ide yang bagus, begitu pula dengan pola. Jika Anda mencampur UI dan logika Anda akan memiliki waktu yang buruk. Jika Anda harus menguji interaksi DB, Anda masih dapat mengejek DAO Anda untuk tes unit dan menggunakan hal yang nyata untuk tes integrasi.
TheMorph
1
Saya menyetujui fakta bahwa satu kabut memiliki pengetahuan tentang desain dan pengujian sebelum melompat ke tdd. Ini penting dalam proyek-proyek dengan karyawan baru karena mereka baru di keduanya.
Hitesh Sahu
memberikan suara untuk Kebijaksanaan
sabsab
66

Ketika Anda sampai pada titik di mana Anda memiliki sejumlah besar tes, mengubah sistem mungkin perlu menulis ulang beberapa atau semua tes Anda, tergantung pada yang mana yang menjadi tidak valid oleh perubahan. Ini bisa mengubah modifikasi yang relatif cepat menjadi yang sangat memakan waktu.

Selain itu, Anda mungkin mulai membuat keputusan desain berdasarkan TDD daripada prioritas desain yang sebenarnya bagus. Sementara Anda mungkin memiliki solusi yang sangat sederhana dan mudah yang tidak mungkin untuk menguji cara TDD menuntut, Anda sekarang memiliki sistem yang jauh lebih kompleks yang sebenarnya lebih rentan terhadap kesalahan.

Eric Z Beard
sumber
3
Pasti bisa menjadi masalah, namun saya menemukan saya melihat perbedaan nyata dalam seberapa banyak saya terpengaruh oleh ini. Semua bermuara pada "menulis kode yang bisa diuji", saya kira.
Rob Cooper
2
Scott, contoh yang biasanya saya berikan adalah SqlDataSource yang tertanam di halaman ASPX. Anda tidak dapat mengotomatiskan tes untuk itu. Ini sederhana dan menyelesaikan pekerjaan, hanya dengan 1 file. Komponen yang dapat diuji adalah objek SqlDataSource MSFT, dan itu sudah dilakukan untuk kita. Tidak perlu bagi kita untuk melakukan lebih banyak.
Eric Z Beard
8
+1 "Anda mungkin mulai membuat keputusan desain berdasarkan TDD daripada prioritas desain yang sebenarnya bagus" - perangkap terbesar TDD IMHO.
András Szepesházi
2
@ScottSaad masalah IMO adalah desain harus diuraikan terlebih dahulu dan kemudian harus divalidasi dengan tes tertulis dan diperbaiki jika diperlukan. Saya telah melihat banyak kasus ketika orang membahayakan desain yang bagus hanya untuk dapat menulis tes. Akibatnya - sebagian besar sistem ditutupi oleh tes tetapi desainnya benar-benar jelek. Saya berpikir bahwa hal ini terjadi karena TDD didorong ke massa sebagai metodologi yang sangat sederhana dengan berikut kesalahpahaman : if part of the system is covered by tests and they pass, then everything is fine (including design).
Yuriy Nakonechnyy
3
@Yura: Sangat menarik apa yang Anda katakan bahwa orang membahayakan desain yang bagus hanya untuk bisa menulis tes. Menurut pendapat saya jika ada desain yang bagus, tidak perlu membahayakannya. Saya pernah melihat proyek seperti itu dan basis kode adalah mimpi buruk, tetapi orang-orang berpikiran sama - bahwa desainnya hebat. Saya setuju hanya dengan bagian bahwa TDD didorong ke massa sebagai metodologi yang sangat sederhana, namun justru sebaliknya. Menurut pendapat saya ketika kode ini dirancang dengan baik maka ketika Anda membuat satu perubahan kecil maka tidak ada kesempatan untuk mengerem semua tes atau sejumlah besar dari mereka.
BlueLettuce16
54

Saya pikir masalah terbesar bagi saya adalah hilangnya BESAR waktu yang dibutuhkan "untuk masuk ke dalamnya". Saya masih sangat banyak pada awal perjalanan saya dengan TDD (Lihat blog saya untuk pembaruan petualangan pengujian saya jika Anda tertarik) dan saya benar-benar menghabiskan berjam - jam untuk memulai.

Butuh waktu lama untuk memasukkan otak Anda ke "mode pengujian" dan menulis "kode yang dapat diuji" adalah keterampilan itu sendiri.

TBH, dengan hormat saya tidak setuju dengan komentar Jason Cohen tentang mempublikasikan metode privat, bukan itu masalahnya. Saya tidak lagi membuat metode publik dengan cara baru saya bekerja daripada sebelumnya . Namun, hal itu melibatkan perubahan arsitektur dan memungkinkan Anda untuk "menyambungkan" modul kode untuk membuat segala sesuatu yang lain lebih mudah untuk diuji. Anda seharusnya tidak membuat internal kode Anda lebih mudah diakses untuk melakukan ini. Kalau tidak, kita kembali ke titik awal dengan segala sesuatu bersifat publik, di mana enkapsulasi dalam hal itu?

Jadi, singkatnya:

  • Jumlah waktu yang diperlukan untuk berpikir (yaitu benar-benar melakukan pengujian ).
  • Pengetahuan baru diperlukan untuk mengetahui cara menulis kode yang dapat diuji.
  • Memahami perubahan arsitektur yang diperlukan untuk membuat kode dapat diuji.
  • Tingkatkan keahlian Anda "TDD-Coder" sembari mencoba untuk meningkatkan semua keterampilan lain yang diperlukan untuk keahlian pemrograman kami :)
  • Mengatur basis kode Anda untuk memasukkan kode uji tanpa mengacaukan kode produksi Anda.

PS: Jika Anda ingin tautan ke positif, saya telah bertanya dan menjawab beberapa pertanyaan tentang itu, lihat profil saya .

Rob Cooper
sumber
1
Sedihnya, jawaban masuk akal pertama yang saya lihat ...
Daniel C. Sobral
5
Jawaban yang cukup praktis dan sederhana - +1 untuk bagian "Pengaturan pikiran"
ha9u63ar
50

Dalam beberapa tahun saya mempraktikkan Test Driven Development, saya harus mengatakan kerugian terbesarnya adalah:

Jual ke manajemen

TDD paling baik dilakukan berpasangan. Untuk satu, sulit untuk menolak dorongan untuk hanya menulis implementasi ketika Anda TAHU cara menulis pernyataan if / else . Tetapi sepasang akan membuat Anda tetap pada tugas karena Anda membuatnya tetap pada tugas. Sayangnya, banyak perusahaan / manajer tidak berpikir bahwa ini adalah penggunaan sumber daya yang baik. Mengapa membayar dua orang untuk menulis satu fitur, padahal saya memiliki dua fitur yang perlu dilakukan sekaligus?

Jual ke pengembang lain

Beberapa orang tidak memiliki kesabaran untuk menulis tes unit. Beberapa sangat bangga dengan pekerjaan mereka. Atau, beberapa seperti melihat metode / fungsi yang berbelit-belit meredup di ujung layar. TDD bukan untuk semua orang, tapi saya benar-benar berharap begitu. Itu akan membuat pemeliharaan barang jadi lebih mudah bagi jiwa-jiwa miskin yang mewarisi kode.

Mempertahankan kode uji bersama dengan kode produksi Anda

Idealnya, tes Anda hanya akan rusak ketika Anda membuat keputusan kode yang buruk. Yaitu, Anda mengira sistem itu bekerja satu arah, dan ternyata tidak. Dengan memecahkan tes, atau set (kecil) tes, ini sebenarnya kabar baik. Anda tahu persis bagaimana kode baru Anda akan mempengaruhi sistem. Namun, jika tes Anda ditulis dengan buruk, berpasangan ketat atau, lebih buruk lagi, dihasilkan ( Tes VS batuk ), maka mempertahankan tes Anda dapat menjadi paduan suara dengan cepat. Dan, setelah tes yang cukup mulai menyebabkan lebih banyak pekerjaan daripada nilai yang dirasakan yang mereka ciptakan, maka tes akan menjadi hal pertama yang harus dihapus ketika jadwal menjadi padat (mis. Waktu yang diperlukan untuk mengerem)

Menulis tes sehingga Anda dapat menutupi semuanya (cakupan kode 100%)

Idealnya, sekali lagi, jika Anda mengikuti metodologi, kode Anda akan 100% diuji secara default. Biasanya, pikir, saya berakhir dengan cakupan kode di atas 90%. Ini biasanya terjadi ketika saya memiliki beberapa arsitektur gaya template, dan basis diuji, dan saya mencoba untuk mengambil jalan pintas dan tidak menguji kustomisasi template. Juga, saya telah menemukan bahwa ketika saya menemukan penghalang baru yang sebelumnya tidak saya temui, saya memiliki kurva belajar dalam mengujinya. Saya akan mengaku menulis beberapa baris kode dengan cara skool lama, tapi saya sangat suka memiliki 100% itu. (Kurasa aku terlalu berprestasi di sekolah, eh skool).

Namun, dengan itu saya akan mengatakan bahwa manfaat TDD jauh lebih besar daripada negatif untuk ide sederhana bahwa jika Anda dapat mencapai serangkaian tes yang baik yang mencakup aplikasi Anda tetapi tidak terlalu rapuh sehingga satu perubahan menghancurkan semuanya, Anda akan dapat terus menambahkan fitur baru pada hari 300 proyek Anda seperti yang Anda lakukan pada hari 1. Ini tidak terjadi pada semua orang yang mencoba TDD berpikir itu adalah peluru ajaib untuk semua kode bug-ridden mereka, dan sehingga mereka berpikir itu dapat bekerja, titik.

Secara pribadi saya telah menemukan bahwa dengan TDD, saya menulis kode yang lebih sederhana, saya menghabiskan lebih sedikit waktu untuk berdebat apakah solusi kode tertentu akan berfungsi atau tidak, dan bahwa saya tidak takut mengubah baris kode apa pun yang tidak memenuhi kriteria yang ditetapkan oleh tim.

TDD adalah disiplin yang sulit untuk dikuasai, dan saya sudah melakukannya selama beberapa tahun, dan saya masih belajar teknik pengujian baru sepanjang waktu. Ini adalah investasi waktu yang sangat besar di muka, tetapi, dalam jangka panjang, keberlanjutan Anda akan jauh lebih besar daripada jika Anda tidak memiliki tes unit otomatis. Sekarang, andai saja atasan saya bisa memikirkan ini.

casademora
sumber
7
Apa sisa kalimat yang diakhiri dengan "(tes VS batuk), lalu main"?
Andrew Grimm
+1 untuk masalah penjualan. :) Saya sekarang di perusahaan baru dan berpikir bagaimana menciptakan budaya yang memungkinkan keterampilan untuk menyebar dengan bebas.
Esko Luontola
2
Seperti yang saya pertimbangkan bahwa beberapa perusahaan konsultan mengambil keuntungan dari pemrograman pasangan dan TDD hanya untuk mendapatkan lebih banyak uang dari klien mereka. Sangat mengecewakan bagaimana klien ini membayar untuk ide-ide yang tampak masuk akal pada pandangan pertama seperti dua orang berpikir jauh lebih baik daripada 2 atau bahwa TDD memastikan bahwa setiap baris kode diuji, tetapi pada akhirnya mereka hanya alasan untuk membuat klien membayar lebih untuk sesuatu yang hanya bisa dilakukan satu orang.
lmiguelvargasf
24

Pada proyek TDD pertama Anda, ada dua kerugian besar, waktu dan kebebasan pribadi

Anda kehilangan waktu karena:

  • Membuat rangkaian unit yang komprehensif, refactored, dapat dipelihara dan tes penerimaan menambah waktu besar untuk iterasi pertama proyek. Ini mungkin menghemat waktu dalam jangka panjang tetapi sama-sama bisa jadi ini adalah waktu yang tidak perlu Anda luangkan waktu.
  • Anda perlu memilih dan menjadi ahli dalam seperangkat alat inti. Alat pengujian unit perlu dilengkapi dengan semacam kerangka kerja mengejek dan keduanya perlu menjadi bagian dari sistem build otomatis Anda. Anda juga ingin memilih dan menghasilkan metrik yang sesuai.

Anda kehilangan kebebasan pribadi karena:

  • TDD adalah cara yang sangat disiplin dalam menulis kode yang cenderung menggosok mentah terhadap mereka yang berada di atas dan bawah skala keterampilan. Selalu menulis kode produksi dengan cara tertentu dan menjadikan pekerjaan Anda sebagai peer review yang terus-menerus dapat membuat pengembang Anda yang terburuk dan terbaik dan bahkan menyebabkan hilangnya jumlah karyawan.
  • Sebagian besar metode Agile yang menanamkan TDD mengharuskan Anda berbicara dengan klien secara terus-menerus tentang apa yang ingin Anda capai (dalam cerita ini / hari / apa pun) dan apa trade-offnya. Sekali lagi ini bukan secangkir teh semua orang, baik di sisi pengembang pagar dan klien.

Semoga ini membantu

Garth Gilmour
sumber
1
Saya tidak tahu apakah itu karena saya terburuk atau terbaik .. tetapi TDD menggosok saya dengan cara yang salah. Itu karena memaksa saya ke mode pemeliharaan ganda terlalu dini. Setiap kali saya mengubah desain sebuah kelas, sekarang saya juga harus mengubah test case. Saya mengharapkan dan menerima itu dari kelas yang matang, tetapi bukan dari kelas yang baru saja saya tulis minggu lalu! Saya juga dapat mengatakan bahwa DI dan TDD tidak didukung dengan baik oleh bahasa seperti Java dan C #. Seseorang benar-benar perlu membuat bahasa baru sehingga biaya TDD dan DI benar-benar nol . Maka kita tidak akan memiliki percakapan ini lagi.
John Henckel
14

TDD mengharuskan Anda untuk merencanakan bagaimana kelas Anda akan beroperasi sebelum Anda menulis kode untuk lulus tes tersebut. Ini adalah plus dan minus.

Saya merasa sulit untuk menulis tes dalam "ruang hampa" - sebelum kode apa pun telah ditulis. Dalam pengalaman saya, saya cenderung tersandung tes saya setiap kali saya pasti memikirkan sesuatu saat menulis kelas saya yang saya lupa saat menulis tes awal saya. Maka saatnya untuk tidak hanya memperbaiki kelas saya, tetapi juga ujian saya. Ulangi ini tiga atau empat kali dan itu bisa membuat frustrasi.

Saya lebih suka menulis draf kelas saya terlebih dahulu kemudian menulis (dan memelihara) baterai unit test. Setelah saya memiliki konsep, TDD berfungsi dengan baik untuk saya. Misalnya, jika bug dilaporkan, saya akan menulis tes untuk mengeksploitasi bug itu dan kemudian memperbaiki kode sehingga tes berlalu.

Chrass
sumber
1
Meskipun Anda harus memiliki gambaran tentang bagaimana arsitektur sistem Anda akan terlihat, Anda tidak perlu tahu banyak sebelumnya tentang melakukan TDD. TDD berarti bahwa tes MENGEMUDI desain, sehingga itu akan berubah saat Anda menerapkan lebih banyak skenario pengujian
casademora
4
Saya setuju dengan ruang hampa. Tutorial asli TDD tempat Anda akan menulis tes tanpa kode APAPUN - dan mendapatkan kesalahan kompilasi - gila.
mparaz
Ini adalah asumsi yang salah bahwa Anda dapat menulis tes sekali dan tidak mengubahnya. Mereka adalah kode dan setiap kode membutuhkan refactoring akhirnya setelah Anda melakukan perubahan. Tes tidak terkecuali. Tes refactoring adalah suatu keharusan jika Anda ingin mempertahankannya.
Roman Konoval
12

Membuat prototipe bisa sangat sulit dengan TDD - ketika Anda tidak yakin jalan apa yang akan Anda ambil untuk solusi, menulis tes di muka bisa sulit (selain yang sangat luas). Ini bisa jadi menyebalkan.

Jujur saya tidak berpikir bahwa untuk "pengembangan inti" untuk sebagian besar proyek ada kelemahan nyata, meskipun; itu dibicarakan lebih banyak dari yang seharusnya, biasanya oleh orang-orang yang percaya kode mereka cukup baik sehingga mereka tidak perlu tes (tidak pernah ada) dan orang-orang yang hanya polos tidak dapat diganggu untuk menulisnya.

Calum
sumber
9

Nah, dan peregangan ini, Anda perlu men-debug tes Anda. Juga, ada biaya tertentu dalam waktu untuk menulis tes, meskipun kebanyakan orang setuju bahwa itu adalah investasi di muka yang terbayar selama masa pakai aplikasi dalam kedua waktu men-debug dan menjaga stabilitas.

Namun, masalah terbesar yang saya miliki secara pribadi adalah membangun disiplin untuk benar-benar menulis ujian. Dalam sebuah tim, terutama tim yang sudah mapan, mungkin sulit meyakinkan mereka bahwa waktu yang dihabiskan bermanfaat.

Tim Sullivan
sumber
13
Aha - tapi di situlah TDTDD masuk. Test Driven Test Driven Development.
Snowcrash
3
Saya kadang-kadang masih menemukan bug dalam tes pengujian saya. Jadi sekarang saya berlatih TDTDTDD.
HorseloverFat
@SnowCrash +1 Saya mencari di sekitar Google untuk melihat berapa banyak waktu yang dihabiskan orang untuk menguji tes mereka, dan kemudian saya melihat jawaban ini. Saya secara resmi menemukan ini karena saya bertanya-tanya tentang TDTDTDD.
BalinKingOfMoria Reinstate CMs
1
Saya percaya masa depan adalah (TD) <sup> ∞ </sup> TDD. Saya punya satu file sejauh ini: ini berisi huruf "x".
mike rodent
Saya setuju dengan @Tim. Meyakinkan anggota untuk mengadopsinya adalah bagian tersulit.
Olu Smith
7

Jika tes Anda tidak terlalu menyeluruh, Anda mungkin jatuh ke dalam pengertian yang salah tentang "semuanya bekerja" hanya karena Anda lulus ujian. Secara teoritis jika tes Anda lulus, kode tersebut berfungsi; tetapi jika kita bisa menulis kode dengan sempurna pertama kali kita tidak perlu tes. Moral di sini adalah memastikan untuk melakukan pemeriksaan kewarasan sendiri sebelum memanggil sesuatu yang lengkap, jangan hanya mengandalkan tes.

Pada catatan itu, jika pemeriksaan kewarasan Anda menemukan sesuatu yang tidak diuji, pastikan untuk kembali dan menulis tes untuk itu.

Aaron Lee
sumber
Saya tidak percaya pada klausa kewarasan sejak saya tumbuh dewasa.
mike rodent
7

Kelemahan dari TDD adalah bahwa hal itu biasanya terkait erat dengan metodologi 'Agile', yang tidak mementingkan dokumentasi sistem, melainkan pemahaman di balik mengapa tes 'harus' mengembalikan satu nilai spesifik daripada yang lain hanya berada di pengembang. kepala.

Segera setelah pengembang meninggalkan atau lupa alasan bahwa tes mengembalikan satu nilai tertentu dan bukan yang lain, Anda gagal. TDD baik-baik saja JIKA itu didokumentasikan secara memadai dan dikelilingi oleh dokumentasi yang dapat dibaca manusia (mis. Manajer runcing) yang dapat dirujuk dalam 5 tahun ketika dunia berubah dan aplikasi Anda juga perlu.

Ketika saya berbicara tentang dokumentasi, ini bukan uraian kode, ini adalah tulisan resmi yang ada di luar aplikasi, seperti kasus penggunaan dan informasi latar belakang yang dapat dirujuk oleh manajer, pengacara dan getah miskin yang harus memperbarui kode Anda pada tahun 2011.

Ron McMahon
sumber
1
Ditempatkan dengan sempurna. Saya sangat setuju. Bagi saya, tes tentu saja tidak membantu menggambarkan definisi masalah di dunia nyata, tingkat yang lebih tinggi. Dokumentasi yang baik telah membuktikan nilainya berkali-kali. Sebagai teknologinya. usia industri, gagasan yang teruji oleh waktu harus ditiadakan dengan menggunakan kehati-hatian yang semakin besar. Kode mendokumentasikan diri sendiri adalah gagasan yang konyol. Saya percaya pada prototyping, refactoring, dan kelincahan yang ditimbulkan karena tidak pernah mendefinisikan masalah di awal. Namun, ironisnya, tidak mendefinisikan masalah secara berlebihan pada awalnya membuat mematikan untuk TDD menjadi ladang ranjau.
wax_lyrical
1
Saya pikir ini tidak adil. Praktik TDD yang baik mengutuk angka ajaib dan tes tidak jelas. Pengujian harus sederhana dan, atau lebih baik dibaca daripada kode produksi Anda sendiri. tes Anda ADALAH dokumentasi. pastikan mereka terlihat seperti itu. jawaban ini terasa seperti mengatakan "dokumentasi itu jahat karena kadang-kadang orang menulis dokumentasi yang benar-benar buruk" atau "kelas itu buruk karena saya telah melihat beberapa kelas dewa yang sulit ditangani".
sara
6

Saya telah mengalami beberapa situasi di mana TDD membuat saya gila. Untuk beberapa nama:

  • Rawatan kasus uji:

    Jika Anda berada di perusahaan besar, banyak kemungkinan Anda tidak harus menulis sendiri test case atau setidaknya sebagian besar ditulis oleh orang lain ketika Anda masuk ke perusahaan. Fitur aplikasi berubah dari waktu ke waktu dan jika Anda tidak memiliki sistem, seperti HP Quality Center, untuk melacaknya, Anda akan menjadi gila dalam waktu singkat.

    Ini juga berarti bahwa itu akan mengambil anggota tim baru cukup waktu untuk mengambil apa yang terjadi dengan kasus-kasus uji. Pada gilirannya, ini dapat diterjemahkan menjadi lebih banyak uang yang dibutuhkan.

  • Kompleksitas uji otomatisasi:

    Jika Anda mengotomatiskan beberapa atau semua kotak uji ke dalam skrip uji yang dapat dijalankan mesin, Anda harus memastikan skrip uji ini selaras dengan kotak uji manual yang sesuai dan sejalan dengan perubahan aplikasi.

    Selain itu, Anda akan menghabiskan waktu untuk men-debug kode yang membantu Anda menangkap bug. Menurut pendapat saya, sebagian besar bug ini berasal dari kegagalan tim pengujian untuk mencerminkan perubahan aplikasi dalam skrip pengujian otomatisasi. Perubahan logika bisnis, GUI, dan hal-hal internal lainnya dapat membuat skrip Anda berhenti berjalan atau berjalan dengan tidak dapat diandalkan. Terkadang perubahannya sangat halus dan sulit dideteksi. Setelah semua skrip saya melaporkan kegagalan karena mereka mendasarkan perhitungan mereka pada informasi dari tabel 1 sementara tabel 1 sekarang tabel 2 (karena seseorang menukar nama objek tabel dalam kode aplikasi).

Martin08
sumber
Ini sama sekali tidak berurusan dengan TDD. Jika orang lain di departemen lain menulis kasus pengujian Anda, Anda tidak melakukan TDD. Jika Anda memiliki kasus uji manual, Anda tidak melakukan TDD. Jika kode pustaka Anda rusak dan tes Anda gagal karena perubahan pada GUI Anda kemungkinan besar tidak melakukan TDD juga. Ini tampaknya lebih seperti argumen terhadap departemen QA perusahaan besar yang tidak efektif.
sara
5

Masalah terbesar adalah orang-orang yang tidak tahu cara menulis unit test yang tepat. Mereka menulis tes yang saling bergantung (dan mereka bekerja sangat baik dengan Ant, tetapi tiba-tiba gagal ketika saya menjalankannya dari Eclipse, hanya karena mereka berjalan dalam urutan yang berbeda). Mereka menulis tes yang tidak menguji apa pun khususnya - mereka hanya men-debug kode, memeriksa hasilnya, dan mengubahnya menjadi tes, menyebutnya "test1". Mereka memperluas cakupan kelas dan metode, hanya karena akan lebih mudah untuk menulis unit test untuk mereka. Kode unit test mengerikan, dengan semua masalah pemrograman klasik (kopling berat, metode yang panjang 500 baris, nilai-nilai hard-kode, duplikasi kode) dan sangat sulit untuk dipertahankan. Untuk beberapa alasan aneh orang memperlakukan unit test sebagai sesuatu yang lebih rendah daripada kode "asli", dan mereka tidak t peduli tentang kualitas mereka sama sekali. :-(

rmaruszewski
sumber
4

Anda kehilangan banyak waktu yang dihabiskan untuk menulis tes. Tentu saja, ini mungkin disimpan pada akhir proyek dengan menangkap bug lebih cepat.

Joel Coehoorn
sumber
Apakah ini benar-benar cara negatif, atau diam-diam menyatakan positif.
IanL
3

Kelemahan terbesar adalah bahwa jika Anda benar-benar ingin melakukan TDD dengan benar, Anda harus banyak gagal sebelum Anda berhasil. Mengingat berapa banyak perusahaan perangkat lunak yang bekerja (dolar per KLOC), Anda pada akhirnya akan dipecat. Bahkan jika kode Anda lebih cepat, lebih bersih, lebih mudah dirawat, dan memiliki lebih sedikit bug.

Jika Anda bekerja di perusahaan yang membayar Anda oleh KLOC (atau persyaratan yang diterapkan - bahkan jika tidak diuji) tinggal jauh dari TDD (atau ulasan kode, atau pemrograman pasangan, atau Integrasi Berkelanjutan, dll. Dll.).

Vasco Duarte
sumber
3

Anda kehilangan kemampuan untuk mengatakan bahwa Anda "selesai" sebelum menguji semua kode Anda.

Anda kehilangan kemampuan untuk menulis ratusan atau ribuan baris kode sebelum menjalankannya.

Anda kehilangan kesempatan untuk belajar melalui debugging.

Anda kehilangan fleksibilitas untuk mengirimkan kode yang tidak Anda yakini.

Anda kehilangan kebebasan untuk memasangkan modul Anda dengan ketat.

Anda kehilangan pilihan untuk tidak menulis dokumentasi desain tingkat rendah.

Anda kehilangan stabilitas yang menyertai kode yang takut diubah oleh semua orang.

Paman Bob
sumber
1
Tergantung pada definisi Anda tentang "memberikan solusi tepat waktu" - apakah "solusi lama yang rusak sebagian tepat waktu" atau "memberikan solusi yang tepat waktu". Anda tentu kehilangan kemampuan untuk memberikan solusi yang rusak sebagian tepat waktu. Sejauh kecepatan dev berjalan - saya suka metrik "waktu yang telah berlalu antara awal dev dan satu minggu penyebaran langsung tanpa cacat". Jika Anda mengukurnya dengan adil, sulit bahkan menghentikan jam sama sekali pada bagian copmlex dari pekerjaan non-TDD.
Dafydd Rees
47
-1, ini adalah hal yang OP katakan tidak dia inginkan.
erikkallen
1
Banyak pernyataan benar, tetapi: apa kata erikkallen. -1.
j_random_hacker
@ j_random_hacker mengatakan hacker ... LOL
Dan
hanya pernyataan ketiga yang sah "pelajari melalui debugging yang hilang"
YEH
2

Saya menjawab kedua tentang waktu pengembangan awal. Anda juga kehilangan kemampuan untuk bekerja dengan nyaman tanpa keamanan tes. Saya juga dideskripsikan sebagai nutbar TDD, sehingga Anda dapat kehilangan beberapa teman;)

Chris Canal
sumber
2

Itu dianggap lebih lambat. Jangka panjang itu tidak benar dalam hal kesedihan itu akan menyelamatkan Anda di jalan, tetapi Anda akan berakhir menulis lebih banyak kode sehingga bisa dibilang Anda menghabiskan waktu pada "pengujian bukan pengkodean". Ini argumen yang salah, tetapi Anda memang bertanya!

MarcE
sumber
2

Pemfokusan ulang pada persyaratan yang sulit dan tidak terduga adalah kutukan konstan dari programmer. Pengembangan yang digerakkan oleh ujian memaksa Anda untuk fokus pada persyaratan duniawi yang sudah diketahui, dan membatasi pengembangan Anda pada apa yang telah dibayangkan.

Pikirkan tentang hal ini, Anda mungkin akan berakhir merancang kasus uji tertentu, sehingga Anda tidak akan menjadi kreatif dan mulai berpikir "itu akan keren jika pengguna bisa melakukan X, Y, dan Z". Oleh karena itu, ketika pengguna mulai bersemangat tentang kemungkinan kebutuhan keren X, Y, dan Z, desain Anda mungkin terlalu kaku pada kasus uji yang telah ditentukan, dan akan sulit untuk menyesuaikan.

Ini, tentu saja, adalah pedang bermata dua. Jika Anda menghabiskan seluruh waktu merancang untuk setiap yang dapat dibayangkan, dapat dibayangkan, X, Y, dan Z yang diinginkan seorang pengguna, Anda pasti tidak akan pernah menyelesaikan apa pun. Jika Anda menyelesaikan sesuatu, mustahil bagi siapa pun (termasuk diri Anda) untuk mengetahui apa yang Anda lakukan dalam kode / desain Anda.

Doug T.
sumber
Pikirkan tentang hal ini, Anda mungkin akan berakhir merancang kasus uji tertentu, sehingga Anda tidak akan menjadi kreatif dan mulai berpikir "itu akan keren jika pengguna bisa melakukan X, Y, dan Z". - Menurut saya itu justru sebaliknya. Jika Anda menulis unit test Anda bertanya-tanya tentang kasus bisnis yang berbeda dan itu berarti bahwa Anda kreatif dan memungkinkan untuk meramalkan sesuatu yang tidak terduga. Namun semua kreativitas itu tidak penting jika implementasi Anda memiliki bug.
BlueLettuce16
1

Ini bisa sulit dan memakan waktu tes menulis untuk data "acak" seperti XML-feed dan basis data (tidak terlalu sulit). Saya telah menghabiskan beberapa waktu belakangan ini bekerja dengan feed data cuaca. Ini tes menulis yang cukup membingungkan untuk itu, setidaknya karena saya tidak memiliki terlalu banyak pengalaman dengan TDD.

Vargen
sumber
Ini adalah masalah umum. Saya cenderung mengejek ini dengan objek kode keras, kemudian menguji database secara terpisah. Lapisan bisnis Anda kemudian hanya akan bekerja dengan data statis, Anda DAL kemudian akan diuji dalam lingkungan yang terkendali (di mana Anda dapat skrip data ke dalamnya dll.)
Rob Cooper
1

Anda akan kehilangan kelas besar dengan banyak tanggung jawab. Anda juga kemungkinan akan kehilangan metode besar dengan banyak tanggung jawab. Anda mungkin kehilangan beberapa kemampuan untuk refactor, tetapi Anda juga akan kehilangan beberapa kebutuhan untuk refactor.

Jason Cohen mengatakan sesuatu seperti: TDD membutuhkan organisasi tertentu untuk kode Anda. Ini mungkin salah secara arsitektur; misalnya, karena metode pribadi tidak dapat dipanggil di luar kelas, Anda harus membuat metode non-pribadi untuk membuatnya dapat diuji.

Saya mengatakan ini menunjukkan abstraksi yang terlewatkan - jika kode pribadi benar-benar perlu diuji, mungkin harus di kelas yang terpisah.

Dave Mann

Dave Mann
sumber
1

Anda harus menulis aplikasi dengan cara yang berbeda: yang membuatnya dapat diuji. Anda akan terkejut betapa sulitnya ini pada awalnya.

Beberapa orang menemukan konsep berpikir tentang apa yang akan mereka tulis sebelum mereka menulisnya terlalu keras. Konsep seperti mengejek bisa sulit untuk beberapa juga. TDD dalam aplikasi lawas bisa sangat sulit jika tidak dirancang untuk pengujian. TDD di sekitar kerangka kerja yang tidak ramah TDD juga bisa menjadi perjuangan.

TDD adalah keterampilan sehingga para junior devs mungkin berjuang pada awalnya (terutama karena mereka tidak diajarkan untuk bekerja dengan cara ini).

Secara keseluruhan meskipun kontra menjadi dipecahkan ketika orang menjadi terampil dan Anda akhirnya mengambil kode 'bau' dan memiliki sistem yang lebih stabil.

Peter Gillard-Moss
sumber
1

Butuh beberapa waktu untuk masuk ke dalamnya dan beberapa waktu untuk mulai melakukannya dalam sebuah proyek tapi ... Saya selalu menyesal tidak melakukan pendekatan Test Driven ketika saya menemukan bug konyol bahwa tes otomatis bisa menemukan sangat cepat. Selain itu, TDD meningkatkan kualitas kode.

aerlijman
sumber
1
  • unit test adalah lebih banyak kode untuk ditulis, sehingga biaya pengembangan dimuka lebih tinggi
  • lebih banyak kode untuk dipelihara
  • diperlukan pembelajaran tambahan
Bob Dizzle
sumber
1

Jawaban bagus semuanya. Saya akan menambahkan beberapa cara untuk menghindari sisi gelap TDD:

  • Saya telah menulis aplikasi untuk melakukan swa-uji sendiri secara acak. Masalah dengan menulis tes khusus adalah bahkan jika Anda menulis banyak dari mereka mereka hanya membahas kasus yang Anda pikirkan. Generator uji acak menemukan masalah yang tidak Anda pikirkan.

  • Seluruh konsep banyak unit test menyiratkan bahwa Anda memiliki komponen yang dapat masuk ke keadaan tidak valid, seperti struktur data yang kompleks. Jika Anda menjauh dari struktur data yang kompleks, ada jauh lebih sedikit untuk diuji.

  • Sejauh aplikasi Anda mengizinkannya, jangan desain yang bergantung pada urutan pemberitahuan yang tepat, acara dan efek samping. Mereka dapat dengan mudah dijatuhkan atau diacak sehingga mereka membutuhkan banyak pengujian.

Mike Dunlavey
sumber
Tes acak bisa gagal sesekali, dan membuat pengulangan sulit
David Sykes
@ Davidvidykes: Setiap kali Anda melakukan tes acak, Anda mencatat parameter, sehingga jika gagal Anda dapat mengulanginya, atau Anda dapat mengulanginya nanti bahkan jika itu tidak gagal. Intinya adalah tidak tergantung pada Anda untuk memikirkan kasus-kasus ujian. Jika Anda seperti saya, Anda secara naluriah cenderung ke tempat uji yang aman.
Mike Dunlavey
0

TDD memerlukan organisasi tertentu untuk kode Anda. Ini mungkin tidak efisien atau sulit dibaca. Atau bahkan secara arsitektur salah; misalnya, karena privatemetode tidak dapat dipanggil di luar kelas, Anda harus membuat metode non-pribadi untuk membuatnya dapat diuji, yang hanya salah.

Ketika kode berubah, Anda harus mengubah tes juga. Dengan refactoring, ini bisa menjadi pekerjaan ekstra.

Jason Cohen
sumber
9
Semua metode pribadi harus diuji melalui metode publik yang akan ada.
Garry Shutler
Ini tidak mungkin dengan semua kelas. Kadang-kadang Anda tidak ingin memalsukan semua dependensi dll. Dan Anda hanya ingin menguji metode utilitas.
Jason Cohen
+1, sangat benar. Tambahkan ke persyaratan ini untuk kadang-kadang menambahkan getter / setter ke bidang pribadi hanya untuk dapat mengatur dan membaca status dengan benar untuk unit test, meskipun negara harus privat ke kelas.
erikkallen
Pertimbangkan untuk menulis tes Anda seolah itu adalah dokumen persyaratan hidup. Maka Anda akan melihat cahaya. Baca juga Pola Tes XUnit.
Scott Nimrod
0

Izinkan saya menambahkan bahwa jika Anda menerapkan prinsip-prinsip BDD ke proyek TDD, Anda dapat mengurangi beberapa kelemahan utama yang tercantum di sini (kebingungan, kesalahpahaman, dll.). Jika Anda tidak terbiasa dengan BDD, Anda harus membaca pengantar Dan North. Dia muncul konsep sebagai jawaban untuk beberapa masalah yang timbul dari penerapan TDD di tempat kerja. Pengenalan Dan ke BDD dapat ditemukan di sini .

Saya hanya membuat saran ini karena BDD membahas beberapa hal negatif ini dan bertindak sebagai penghenti kesenjangan. Anda akan ingin mempertimbangkan ini ketika mengumpulkan umpan balik Anda.

Kilhoffer
sumber
Benar. Anda harus mempertimbangkan BDD saat mengevaluasi TDD.
user9991
Tampaknya BDD = pengembangan yang didorong oleh perilaku
hayalci
0

Anda harus memastikan tes Anda selalu terkini, saat Anda mulai mengabaikan lampu merah adalah saat tes menjadi tidak berarti.

Anda juga harus memastikan tes komprehensif, atau saat bug besar muncul, tipe manajemen pengap yang akhirnya Anda yakinkan untuk membiarkan Anda menghabiskan waktu menulis lebih banyak kode akan mengeluh.

qui
sumber
0

Orang yang mengajar pengembangan tim lincah saya tidak percaya pada perencanaan, Anda hanya menulis sebanyak untuk persyaratan terkecil.

Moto-nya adalah refactor, refactor, refactor. Saya memahami bahwa refactor berarti 'tidak merencanakan ke depan'.

Jack B Nimble
sumber
-1

Waktu pengembangan bertambah: Setiap metode perlu pengujian, dan jika Anda memiliki aplikasi besar dengan dependensi, Anda perlu menyiapkan dan membersihkan data Anda untuk pengujian.

Mouna Cheikhna
sumber
Saya telah mengembangkan selama 36 tahun sekarang posting ini dapat memberi Anda beberapa saran yang baik: stackoverflow.com/questions/738539/tdd-how/45971814#45971814
user2288580