pengembangan-web-mp.com

Mengapa TDD tidak lebih populer di universitas?

Baru-baru ini, seseorang di sini mengajukan pertanyaan dasar tentang bagaimana cara menghitung dalam Python semua permutasi elemen dari daftar. Adapun sebagian besar pertanyaan yang diajukan oleh siswa, saya belum memberikan kode sumber aktual di jawaban saya, tetapi lebih menjelaskan bagaimana mendekati masalah, yang pada dasarnya berakhir dengan presentasi dasar pengembangan yang digerakkan oleh tes.

Memikirkan masalah itu sendiri, saya ingat semua masalah yang sama yang harus saya pecahkan ketika saya sendiri belajar pemrograman di universitas. Kami tidak pernah diajarkan tentang pengembangan yang digerakkan oleh tes, atau metode apa pun yang sebanding, tetapi tetap diminta untuk menulis algoritma yang mengurutkan elemen dari daftar, atau memecahkan teka-teki Menara Hanoi, dll. Juga tidak semua siswa yang datang dengan SoftwareEngineering.SE tampaknya untuk mengetahui bagaimana TDD (Test Driven Development) akan membantu mereka memecahkan masalah yang diberikan kepada mereka: jika ya, mereka akan merumuskan pertanyaan mereka dengan sangat berbeda.

Faktanya adalah, tanpa TDD, semua masalah itu memang cukup menantang. Saya menganggap diri saya sebagai pengembang profesional, tetapi saya masih akan menghabiskan waktu menulis algoritma daftar-pemesanan tanpa TDD, jika ditanya, dan saya akan kebanyakan tidak mengerti jika saya diminta untuk menghitung semua permutasi elemen-elemen dalam daftar, masih tanpa menggunakan TDD. Dengan TDD, di sisi lain, saya memecahkan masalah permutasi dalam hitungan menit ketika menulis jawaban kepada siswa.

Apa alasan TDD tidak diajarkan sama sekali atau paling tidak sangat terlambat di universitas? Dengan kata lain, apakah akan bermasalah untuk menjelaskan pendekatan TDD sebelumnya meminta siswa untuk menulis algoritma pengurutan daftar dan hal-hal serupa?


Mengikuti komentar dalam dua pertanyaan:

Dalam pertanyaan Anda, Anda tampaknya menyajikan TDD sebagai "perangkat pemecahan masalah" [...] Di masa lalu, TDD telah disajikan sebagai "mekanisme penemuan solusi," tetapi bahkan Bob Martin (pendukung utama TDD) mengakui bahwa Anda harus membawa sejumlah besar pengetahuan sebelumnya ke teknik ini.

dan khususnya:

Saya ingin tahu mengapa Anda berpikir TDD membuat masalah algoritme rumit dengan spesifikasi yang terdefinisi lebih mudah.

Saya merasa perlu untuk menjelaskan sedikit lebih banyak tentang apa, menurut pendapat saya, sangat ajaib tentang TDD ketika datang untuk memecahkan masalah.

Di sekolah menengah dan di universitas, saya tidak memiliki teknik khusus untuk menyelesaikan masalah, dan ini berlaku untuk pemrograman dan matematika. Dalam retrospektif, saya kira bahwa salah satu dari teknik tersebut adalah untuk meninjau pelajaran/kuliah terakhir/terakhir dan mencari hubungan dengan latihan. Jika pelajarannya tentang integral, ada kemungkinan masalah yang diminta guru untuk diselesaikan membutuhkan penggunaan integral. Jika kuliah itu tentang rekursi, ada kemungkinan bahwa teka-teki yang diberikan kepada siswa dapat diselesaikan dengan menggunakan rekursi. Saya juga yakin ada pendekatan yang diformalkan dengan baik untuk memecahkan masalah dalam matematika, dan pendekatan itu dapat diterapkan untuk pemrograman juga; Namun, saya tidak pernah mempelajarinya.

Ini berarti bahwa dalam prakteknya, pendekatan saya hanya untuk menyodok masalah, mencoba menebak bagaimana seharusnya diselesaikan. Saat itu, jika saya diberi tantangan untuk menghasilkan permutasi elemen dari daftar, saya tidak akan mulai dengan daftar kosong sebagai input, melainkan contoh ilustratif, seperti [4, 9, 2], mencoba mencari tahu mengapa ada enam kemungkinan permutasi, dan bagaimana saya bisa menghasilkannya melalui kode. Dari sana, saya perlu banyak pemikiran untuk menemukan cara yang mungkin untuk menyelesaikan masalah. Ini pada dasarnya adalah apa yang penulis dalam pertanyaan asli lakukan, akhirnya menggunakan random. Demikian pula, ketika saya masih mahasiswa, tidak ada siswa seusia saya yang akan memulai dengan []: semua akan langsung bergegas ke case dengan dua atau tiga elemen, dan kemudian tetap macet selama setengah jam, kadang-kadang berakhir dengan kode yang tidak dikompilasi atau tidak berjalan.

Pendekatan TDD, bagi saya, tampaknya kontra-intuitif. Maksud saya, ini bekerja dengan sangat baik, tetapi saya tidak akan pernah tahu sendiri, sebelum membaca beberapa artikel tentang TDD, bahwa (1) saya harus mulai dengan kasus paling sederhana, (2) menulis tes sebelum menulis kode, dan (3) ) tidak pernah Rush, mencoba memenuhi beberapa skenario dalam kode. Melihat bagaimana programmer pemula berpikir, saya memiliki kesan bahwa saya bukan satu-satunya yang menemukan itu kontra-intuitif. Mungkin, saya percaya, lebih intuitif untuk programmer yang memiliki pemahaman yang baik tentang bahasa fungsional. Saya mengira bahwa dalam Haskell, misalnya, adalah wajar untuk menangani masalah permutasi dengan mempertimbangkan pertama kasus daftar kosong, kemudian kasus daftar dengan satu elemen, dan kemudian kasus daftar beberapa elemen. Dalam bahasa di mana algoritma rekursif dimungkinkan, tetapi tidak sealami di Haskell, pendekatan seperti itu jauh lebih alami, kecuali, tentu saja, seseorang mempraktikkan TDD.

123
Arseni Mourzenko

Saya seorang guru pemrograman paruh waktu di sebuah perguruan tinggi setempat.

Kursus pertama yang diajarkan di perguruan tinggi ini adalah Java Programming and Algorithms. Ini adalah kursus yang dimulai dengan loop dan kondisi dasar, dan berakhir dengan pewarisan, polimorfisme, dan pengantar koleksi. Semua dalam satu semester, untuk siswa yang belum pernah menulis sebaris kode sebelumnya, kegiatan yang benar-benar eksotis bagi kebanyakan dari mereka.

Saya pernah diundang ke dewan peninjau kurikulum. Dewan mengidentifikasi sejumlah masalah dengan kurikulum CS perguruan tinggi:

  1. Terlalu banyak bahasa pemrograman yang diajarkan.
  2. Tidak ada kursus tentang Siklus Hidup Pengembangan Perangkat Lunak.
  3. Tidak ada kursus basis data.
  4. Kesulitan dalam mendapatkan kredit untuk ditransfer ke universitas negeri dan lokal, sebagian karena sekolah-sekolah ini tidak dapat menyepakati definisi yang seragam untuk istilah "Ilmu Komputer," "Teknologi Informasi," dan "Rekayasa Perangkat Lunak."

Saran saya kepada mereka? Tambahkan kelas batu penjuru dua semester ke kurikulum di mana siswa dapat menulis aplikasi penuh-tumpukan, kursus yang akan mencakup seluruh siklus hidup pengembangan perangkat lunak dari mengumpulkan persyaratan untuk penyebaran. Ini akan membuat mereka dapat dipekerjakan di perusahaan lokal (di tingkat magang).

Jadi di mana TDD cocok dengan semua ini? Sejujurnya aku tidak tahu.

Dalam pertanyaan Anda, Anda tampaknya menghadirkan TDD sebagai "perangkat pemecahan masalah;" Saya melihat TDD sebagian besar sebagai cara untuk meningkatkan desain dan testabilitas kode. Di masa lalu, TDD telah disajikan sebagai "mekanisme penemuan solusi," tetapi bahkan Bob Martin (pendukung utama TDD) mengakui bahwa Anda harus membawa sejumlah besar pengetahuan sebelumnya ke dalam teknik ini.

Dengan kata lain, Anda masih harus tahu bagaimana menyelesaikan masalah dalam kode terlebih dahulu. TDD hanya mendorong Anda ke arah umum yang benar relatif terhadap spesifikasi desain perangkat lunak. Itu membuatnya kursus tingkat atas, bukan yang lebih rendah.

135
Robert Harvey

Pertama-tama, kita harus membedakan secara mendasar antara Ilmu Komputer dan Rekayasa Perangkat Lunak . (Dan mungkin lebih sedikit antara Rekayasa Perangkat Lunak dan Pemrograman atau "Coding".)

Seperti yang dikatakan oleh salah satu profesor CS saya: jika Anda membutuhkan keyboard, Anda tidak melakukan CS.

TDD sangat banyak praktik Rekayasa Perangkat Lunak. Itu tidak benar-benar memiliki banyak hubungan dengan Ilmu Komputer. Jadi, jika Anda bertanya mengapa siswa CS tidak belajar TDD, itu karena TDD tidak terlalu terkait dengan CS.

Sekarang, Rekayasa Perangkat Lunak, itu adalah ketel ikan yang sama sekali berbeda. Saya sangat setuju bahwa TDD harus diajarkan di sana. Saya memiliki satu kelas Rekayasa Perangkat Lunak (90 menit per minggu selama satu semester) dan di kelas ini kami belajar Waterfall, V-Model, RUP, CMM, CASE , RAD, Spiral, Iterative, dan mungkin beberapa hal lain yang saya lupa. Tentunya, akan ada ruang untuk memeras dalam TDD, terutama jika Anda mengintegrasikannya dengan sisa kursus dan menerapkan TDD untuk semua pekerjaan rumah dan pekerjaan kelas di semua kursus di mana pemrograman diperlukan.

Agar adil, dalam kasus saya, Agile Manifesto belum ditulis, dan TDD adalah teknik niche yang tidak jelas.

Jika Anda melihat favorit pribadi saya untuk mengajar pemrograman, Cara Mendesain Program , Anda akan menemukan bahwa mereka mengajar dengan sangat sejak awal fungsi-fungsi tersebut harus disertai dengan contoh penggunaan dan hanya sedikit kemudian, buku ini memperkenalkan pengujian unit otomatis dan menyarankan bahwa contoh penggunaan tersebut harus ditulis dalam bentuk tes. Mereka juga mengajarkan bahwa contoh penggunaan dan apa yang mereka sebut "pernyataan tujuan" (Anda dapat menganggapnya sebagai baris ringkasan dari komentar JavaDoc) harus ditulis sebelum kode.

Mereka tidak secara eksplisit mengajar TDD (mereka memiliki metodologi sendiri), tetapi ini setidaknya agak dekat. HtDP dirancang untuk siswa sekolah menengah untuk diajarkan dalam waktu kurang dari satu tahun, jadi saya pikir lebih dari layak untuk mengajarnya dalam satu semester di universitas.

Jujur saja, itu akan menjadi kemenangan besar bagi para siswa hanya diajarkan bahwa mereka benar-benar dapat menjalankan kode yang mereka tulis dengan input berbeda. (Dengan kata lain, bentuk kasar dari pengujian manual.) Saya kagum pada seberapa sering siswa tidak dapat mengambil langkah mental ini.

Sebagai contoh, saya telah melihat beberapa pertanyaan tentang Stack Overflow yang pada dasarnya berjumlah "metode mana yang perlu saya terapkan untuk membuat kode ini bekerja". Perhatikan bahwa ini bukan tentang kode metode (penanya tahu bagaimana menerapkan metode), itu murni tentang nama . Namun, tidak satu pun dari para penanya datang dengan ide hanya menjalankan kode dan melihat nama metode yang hilang dalam NoMethodError pengecualian yang akan selalu dinaikkan.

97
Jörg W Mittag

TDD adalah proses yang bagus dalam pemrograman "dunia nyata" karena masalah sering kali sampai pada meja kami yang kurang ditentukan. "Tambahkan fitur yang melakukan X", "perbaiki bug di mana ia menunjukkan hal yang salah jika Anda melakukannya Y", dll. TDD memaksa kami untuk membuat spec sebelum kami memulai pemrograman.

Di kelas CS/pemrograman, masalah biasanya datang kepada kami dengan sangat baik. + Msgstr "Tulis fungsi yang mengambil array bilangan bulat dan mengembalikan array dengan bilangan bulat yang sama yang diatur dalam urutan yang tidak menurun". Spek diserahkan kepada kami.

Saya ingin tahu mengapa Anda berpikir TDD membuat masalah algoritme rumit dengan spesifikasi yang terdefinisi lebih mudah. Secara khusus, saya ingin Anda menjelaskan ini:

Saya sebagian besar tidak tahu apa-apa jika saya diminta untuk menghitung semua permutasi elemen dalam daftar, masih tanpa menggunakan TDD. Dengan TDD, di sisi lain, saya memecahkan masalah permutasi dalam hitungan menit ketika menulis jawaban kepada siswa.

Saya menduga Anda akan mengatakan karena Anda menulis kasus uji yang menyatakan P([]) -> [[]], P([1]) -> [[1]], P([1, 2]) -> [[1, 2], [2, 1]], dll, dan itu menyebabkan Anda melihat bagaimana rekursi seharusnya bekerja . Tapi itu bukan TDD, itu hanya ... memikirkan masalahnya. Anda dapat memikirkan masalah tanpa proses penulisan unit test aktual yang gagal.

53
MattPutnam

Saya menduga itu sebagian besar karena menulis tes otomatis lebih sulit daripada menulis kode yang sedang diuji. Ketika Anda masih berjuang dengan mekanika dasar, sulit untuk menambahkan lapisan lain. Juga, seperti yang ditunjukkan oleh jawaban lain, TDD dianggap sebagai proses rekayasa perangkat lunak, meskipun para praktisi menganggapnya lebih sebagai perangkat didaktik. Juga, mengetahui tes apa yang harus ditulis pertama adalah keterampilan itu sendiri.

Jika saya mengajar mata kuliah pengantar, saya akan memberikan beberapa tes dalam urutan TDD, dan menginstruksikan siswa untuk mendapatkan tes lulus satu per satu dalam urutan itu. Itu pengalaman yang sangat mirip untuk memasangkan pemrograman dengan mentor yang berpengalaman. Secara pribadi, saya pikir itu akan membuat kelas seperti algoritma lebih mudah untuk diajarkan, yang akan mengimbangi waktu yang dihabiskan untuk teknik ini, karena perkembangan langkah demi langkah. Ini akan membuat siswa berpikir tentang pertanyaan seperti, "Saya memiliki beberapa kode kerja yang terbukti yang akan menemukan semua permutasi dari daftar dua elemen. Bagaimana saya menggunakan kembali sebanyak mungkin kode itu untuk membuatnya berfungsi untuk 3+ elemen?"

33
Karl Bielefeldt

Masalah dasar adalah bahwa menciptakan tes dalam proses TDD tidak ada hubungannya dengan ilmu komputer atau rekayasa perangkat lunak. Perlu pengetahuan tentang domain aplikasi.

Tentu saja itu adalah kekuatan TDD dalam aplikasi dunia nyata: Anda tidak bisa lepas dari memikirkan tentang apa sistem yang sedang Anda bangun sebenarnya akan digunakan untuk apa. Tetapi dalam kegiatan CS dan SE yang khas, tugas yang diberikan siswa memiliki konteks minimal, dan ada hanya untuk menguji atau menggambarkan beberapa tujuan pembelajaran.

Misalnya, jika tujuan pembelajaran adalah untuk menunjukkan pemahaman tentang konstruksi "case" dalam bahasa pemrograman, TDD tidak relevan: Anda dapat menulis perangkat lunak yang lulus semua tes TDD tanpa menggunakan "case" sama sekali. Jika contoh itu buatan, tidak menggunakan "kasus" sebenarnya bisa menjadi solusi yang lebih baik untuk masalah di dunia nyata, tetapi meskipun tidak dalam hal tujuan pembelajaran yang dimaksudkan.

Dengan segala cara mendorong siswa untuk menciptakan kasus pengujian mereka sendiri dan menjalankannya, tetapi mencoba untuk menggunakan proses TDD formal tidak penting.

Masalah kedua mungkin lebih berkaitan dengan cara CE dan SE diajarkan, tetapi masih praktis: bagaimana Anda menilai siswa koleksi tes saat menggunakan TDD? Tidak ada cara yang jelas untuk mengotomatiskan proses itu.

Bahkan jika Anda menghasilkan solusi model yang mengatakan "Anda harus menguji untuk 15 atau 20 situasi berikut" Anda masih harus mengidentifikasi secara manual mana dari tes siswa yang sesuai (seluruhnya atau sebagian) untuk setiap bagian dari jawaban model Anda. Dan kecuali dalam kasus-kasus sepele, siswa mungkin telah menghasilkan serangkaian tes yang baik yang secara logis terstruktur dengan cara yang berbeda dari jawaban model.

9
alephzero

Rata-rata siswa benar-benar memiliki gambaran yang buruk tentang apa yang diharapkan mereka ketahui dan lakukan. Untuk mengajar TDD, mereka perlu memahami:

  1. Bagaimana cara mengatasi masalah teknis. Pada awalnya mereka berpikir kode ditulis dalam sekali jalan. Hanya nanti ketika mereka menyadari strategi debugging dasar yang mereka pindah ke menulis lebih bertahap. Bahkan jika Anda memberi tahu mereka hal ini di muka, mereka masih akan melakukannya dengan cara ini karena mereka pikir itulah yang dilakukan (ini juga merupakan alasan mengapa orang tidak tahu cara menggambar, bermain piano, melakukan matematika, dll. )

  2. Cara mengintrospeksi tindakan Anda sendiri sehingga Anda dapat menemukan pola yang dapat diulang dalam perilaku Anda sendiri. Setelah Anda dapat melakukan ini, Anda dapat mengotomatiskan pekerjaan Anda sendiri. Tetapi ini sama sekali asing bagi kebanyakan orang sampai mereka mencapai tingkat tertentu.

  3. Cara menulis persyaratan.

  4. Memahami sudut kasus ruang masalah Anda.

  5. Memahami filosofi teknik tentang manajemen risiko. (Ha tetapi Anda bahkan tidak tahu Anda seorang insinyur yang benar)

  6. Memahami refactoring dan pemeliharaan kode.

  7. Memahami bagaimana pemrograman bekerja di perusahaan nyata.

Sebenarnya saya sudah memiliki kolega yang terlalu lama diperkenalkan dengan TDD, mereka tidak terlalu beruntung. Namun, masih mungkin untuk mengambil langkah kecil menuju efek ini. Hanya saja orang membutuhkan pengalaman di belakang mereka untuk mendapat manfaat.

Jadi Anda bisa mengajarkannya tetapi bukan sesuatu yang Anda mulai. Terutama karena ada kode yang tidak meminjamkan dirinya ke TDD dengan sangat mudah.

8
joojaa

TDD tidak lebih populer di universitas, karena (secara umum) universitas melakukan pekerjaan yang sangat buruk dalam memastikan bahwa pengetahuan yang diberikan kepada siswa dapat dialihkan ke konteks dunia nyata.

Bisa dibilang, itu bukan peran universitas di tempat pertama, dan, ini lebih tentang mengajar dasar-dasar dan konsep inti CS. Itu instruktif, penting, dan, penting, jika siswa akan tertarik untuk mengejar karir di dunia akademis, tetapi, gagal ketika siswa akan menyelesaikan gelar mereka dan mendaftar di industri, bekerja terintegrasi dalam tim, yang mengikuti pengembangan praktik terbaik, CI/CD, dll.

Jelas, ada persimpangan dan keduanya dapat saling menguntungkan, tetapi, pada akhirnya, universitas belum cukup cepat dengan apa yang perlu dilakukan untuk lulus insinyur perangkat lunak yang lebih mampu, relevan, dan terkini.

6
Bruno Oliveira

Untuk menjawab pertanyaan secara langsung:

Seperti yang disarankan seseorang, ada cukup banyak pembelajaran untuk satu semester penuh. Kursus terpisah? Mungkin. Saya bisa melihat TDD dikombinasikan dengan topik desain perangkat lunak. Nilai terbesar IMO TDD adalah mengunci perilaku yang ada sehingga kami dapat menambahkan perilaku baru nanti, dan mengubah desain agar sesuai untuk perilaku baru tersebut. Jadi kelas desain perangkat lunak?

Akan menyenangkan untuk melihat proses berpikir di belakang TDD (nama buruk, dan saya pernah bertanya pada Kent Beck apakah dia akan mempertimbangkan kembali; dia mengatakan "kereta telah meninggalkan stasiun") diperkenalkan sedini mungkin. Saya sudah mengumban kode sejak 1976, dan saya tahu bahwa TDD terasa sangat tidak wajar pada awalnya. Tapi sekarang rasanya cukup alami. Waktu saya tidak dapat dikembalikan dengan menulis kode tes, itu dikembalikan lagi nanti, ketika saya hanya perlu memperbaiki cacat serius sekali setahun (perangkat lunak OTIS2 Pusat Transplantasi UofM, yang ditulis sepenuhnya berdasarkan uji coba, memiliki "darurat perangkat lunak" terakhir pada tahun 2004 ).

Saya mendorong lulusan baru untuk mencobanya selama sebulan. Tetapi akan jauh lebih mudah bagi mereka jika mereka terkena TDD lebih awal. Saya merasa menggunakan kerangka kerja unit-test berguna ketika saya belajar bahasa baru (Kisah nyata: "Sekarang bagaimana saya bisa lulus tes ini di Ruby? MUNGKIN ini akan bekerja ... HEY IT WORKED!"), Atau menjelajahi perpustakaan baru ("Dokumen tidak jelas tentang urutan ini akan dikembalikan ... saya akan menulis tes ...").

Saya menemukan TDD berharga ketika menerapkan suatu algoritma (TIDAK menciptakan satu ... Saya akan sampai ke sana), atau membangun aturan bisnis yang agak rumit dari bawah ke atas, seolah-olah. Setiap ujian yang dilewati "dikunci" untuk selamanya. Jika tes ini cukup diskrit, itu tidak perlu berubah (tapi itu membutuhkan waktu lebih lama dari sebulan untuk menjadi ahli dalam hal ini.

Jadi akan menarik untuk memasukkan TDD ke dalam kelas pemrograman sebelumnya. Tiga poin peningkatan:

  1. Kami dapat lebih sedikit fokus pada debugging dan break-fix, yang menurut sebagian besar pengembang hanyalah sifat pekerjaan mereka. Bukan itu. Tidak harus menyakitkan atau menghabiskan waktu.
  2. Kerangka uji unit adalah pengganti sederhana untuk #ifdef DEBUG/printf ("...")/#endif - jadi kami telah melakukan sesuatu yang serupa (tapi lebih berisiko) sejak awal waktu.
  3. Ketika kami mendengar "Anda HARUS menulis tes pertama" kami sedang menyesatkan. Saya inginkan untuk menuliskan harapan saya untuk kode yang akan saya tulis. Saya ingin membiarkannya berjalan sementara saya fokus pada perilaku berikutnya, atau membersihkan desain.

Hal lain yang mungkin berguna adalah buku teks atau, paling tidak, kurikulum tanpa omong kosong dengan lab yang dirancang untuk menyampaikan berbagai aspek praktik TDD. Saya punya saran untuk itu (lihat pengalaman/disclaimer nanti).

Untuk menjawab kritik:

Saya baru di sini, tetapi saya perhatikan bahwa beberapa "jawaban" tidak menjawab pertanyaan, tetapi kritik yang adil terhadap TDD. Jadi saya kira tidak apa-apa untuk mengatasi beberapa masalah itu?

  1. Memang benar, penelitian yang telah dilakukan membandingkan TDD dengan unit-test-after (UTA?) Menunjukkan bahwa TDD pada awalnya lebih lambat. Namun, kelompok UTA memiliki cakupan tes yang jauh lebih rendah, dan lebih banyak cacat. Saya pikir ini adalah penelitian ini: Studi Longitudinal tentang Penggunaan Praktek Pengembangan yang Didorong oleh Uji Coba di Industri

Jika pengembang yang mengerjakan produk selama lebih dari beberapa bulan benar-benar menghabiskan sebagian besar waktu mereka untuk menulis fitur baru, maka ini akan menjadi negatif. Tetapi enam tim TDD yang saya kerjakan sebagai pengembang menghabiskan waktu mereka dengan cara itu, sedangkan dekade saya menghabiskan slinging code sebelum TDD dihabiskan sebagian besar di debugger, atau dengan hati-hati menyalin/menempel/memodifikasi sehingga saya tidak akan rusak lebih lama/kode orang lain. Manfaat TDD tidak semuanya instan, tetapi mereka sangat andal dan sangat berharga yang diukur dengan waktu lembur pengembang yang lebih rendah (dan stres) dan peningkatan pendapatan = . Intinya: Saya selalu berharap untuk bekerja dengan tim TDD itu. (Pernah saya minum teh.)

  1. Juga benar bahwa TDD tidak dapat menemukan algoritma baru. Saya pikir itu adalah Ron Jeffries yang mencoba membuat pemecah Sudoku menggunakan TDD, dan mencoba untuk tidak membiarkan keterampilan Sudoku sendiri mengganggu implementasi. Dia gagal. Saya tidak terkejut. TDD membantu memecah, menyederhanakan, dan menerapkan aturan bisnis; membantu mengonfirmasi bahwa kami mendapatkan algoritme yang benar (mis., algoritma enkripsi kompleks yang mungkin tidak dapat direduksi); membantu kami membentuk kembali kode nanti sehingga kami dapat menambahkan fitur baru dengan aman; dan lakukan ini dengan menjabarkan investasi yang telah kami lakukan dalam perilaku produk.

Ketika Anda menulis "tes" (spesifikasi alias, skenario alias) Anda harus tahu jawabannya! Selain itu, Anda ingin menulis tes yang cukup kecil dari solusi yang sudah Anda miliki beberapa gagasan (pengetahuan sebelumnya) tentang bagaimana Anda akan mengimplementasikannya.

Yang sering mengejutkan adalah betapa jernih dan sederhananya desain jika kita memperhatikan bau kode dan kita melakukan refactor sesuai kebutuhan setiap kali semua tes yang terkait dengan kode tersebut dilewati.

Tidak ada yang menyarankan kita membuang pengetahuan kita yang baik tentang pola desain, atau idiom bahasa, atau prinsip SOLID, atau cara bermain Sudoku, atau bagaimana menulis semacam tumpukan.

TDD adalah tentang menciptakan jaring pengaman yang memberi kita kepercayaan diri untuk secara cepat menambah fitur baru dan mengubah desain agar sesuai dengan fitur-fitur baru tersebut tanpa merusak yang lain.

UTA menambal jaring pengaman setelah seseorang jatuh melalui lubang sampai mati. (Catatan menarik: Proyek OTIS2 adalah sistem yang kritis terhadap kehidupan, sehingga risiko kematian pasien bukan lelucon bagi kami. Lebih dari 20.000 tes semua berjalan dalam 10 menit, sekarang yaitu adalah safetynet!)

Pengalaman/penafian:

Saya melakukan TDD secara penuh waktu dari tahun 1998 hingga 2004 dan dengan ~ 6 tim yang berbeda. Semuanya setidaknya 6 bulan pembangunan. Sebelum itu, saya menghabiskan 13 tahun menulis perangkat lunak dengan cara lain, dan mulai membenci para penentang dan pengujian manual dengan printf ().

Saya mulai mengajar praktik pengembangan perangkat lunak pada tahun 2001, sekarang termasuk kursus TDD, BDD, dan SA-CSD. Tentu, ini adalah kehidupan yang baik, tetapi saya juga tahu bahwa TDD adalah cara mudah untuk membuat pengembangan perangkat lunak yang berpusat pada tim waras dan menyenangkan lagi. Begitu...

Saya menulis apa yang saya harap akan menjadi buku teks perguruan tinggi atau sekolah menengah (dengan repo online, laboratorium, video, dll, tentu saja): Pengembangan Essential Didorong oleh Tes

4
user30938

Saya tidak pernah menganggap TDD bermanfaat sebagai cara untuk benar-benar menyelesaikan masalah dan setelah membaca pertanyaan Anda, saya masih belum.

TDD hanya memaksa Anda untuk melihat masalah dari satu ujung: ujung klien. Ini dapat membantu mencegah Anda menemukan solusi yang tidak cocok dengan pertanyaan klien. Ini umumnya adalah hal yang baik, meskipun itu juga bisa membatasi Anda, itu membuat Anda tidak melihat masalah dari sudut yang lebih luas, mungkin ada solusi yang lebih baik, lebih umum untuk masalah yang tidak dipertimbangkan klien Anda.

Cara lain untuk melihatnya adalah bahwa itu adalah pendekatan top-down terbaik. TDD bisa berarti Pengembangan Top Down. Anda memulai pengembangan di tingkat kursus yang paling dan secara bertahap memperbesar.

Apa pun itu, ini adalah konsep abstrak. Anda dapat memberi tahu siswa tentang hal itu, memberikan definisi, tetapi hanya itu. Anda tidak dapat mengajukan banyak pertanyaan tentang hal itu dalam ujian. Jadi di setiap kelas SE atau CS, meskipun berguna dalam konteks SE, itu tidak pernah lebih dari sekadar catatan.

4
Martin Maat

Saya diajari ilmu komputasi pada tahun 1970-an, jauh sebelum singkatan TDD ditemukan, dan tentu saja kami tidak pernah secara eksplisit diajarkan teknik itu. Tetapi untuk salah satu latihan pemrograman yang diberikan kepada kami, kami diberikan satu set kasus uji dan diberi tahu bahwa solusi kami harus lulus tes. Jadi saya belajar nilai dari pendekatan tersebut tanpa pernah diajarkan secara eksplisit, dan telah menggunakannya sejak saat itu.

4
Michael Kay

Sementara tes menulis adalah keterampilan penting untuk pengembangan perangkat lunak, bukti ilmiah tidak menunjukkan bahwa TDD pada akhirnya menghasilkan perangkat lunak yang lebih baik daripada pengembangan iteratif tes-terakhir (ITL) (OTOH, itu juga tidak lebih buruk ).

Sebagai bukti, Anda dapat melihat Davide Fucci et al. "Sebuah Replikasi Eksternal pada Efek Pengembangan yang Didorong oleh Tes Menggunakan Pendekatan Multi-site Blind Analysis" ( tautan ) dan meta-analisis Turhan et al dalam Pembuatan Perangkat Lunak ( tautan ).

Jadi, kecuali kita mulai melihat bukti yang bertentangan bahwa TDD memang, pada kenyataannya, memberikan keuntungan yang terukur, itu kurang penting bahwa TDD sebagai praktik khusus diajarkan sebagai lawan dari hanya menanamkan kebiasaan yang baik dari penulisan tes di beberapa titik dalam proses pengembangan.

3
Anzel

tapi saya masih akan menghabiskan waktu menulis algoritma daftar-pemesanan tanpa TDD, jika ditanya, dan saya akan sebagian besar tidak mengerti jika saya diminta untuk menghitung semua permutasi elemen-elemen dalam daftar, masih tanpa menggunakan TDD. Dengan TDD, di sisi lain, saya memecahkan masalah permutasi dalam hitungan menit

Ini membingungkan saya dengan serius.
Bagi saya pengembangan yang didorong oleh tes berarti memikirkan tentang tes lebih awal dan meluangkan waktu untuk mengimplementasikan tes dan tetap mengikuti perkembangan terbaru dengan kode.
Tentu saja berpikir tentang apa yang harus diuji adalah peluang bagus untuk menguraikan masalah untuk dipecahkan dan dalam beberapa kasus mendapatkan gambaran yang bagus tentang apa jebakan itu.
Tetapi tidak melakukan TDD, tidak berkonsentrasi pada tes pertama tidak melarang untuk memikirkan masalah yang mendasarinya. Anda harus selalu memikirkan apa yang Anda lakukan dan memperjelas situasinya, tidak peduli apakah Anda ingin melangkah lebih jauh dan melaksanakan tes sekarang atau tidak.

apakah akan bermasalah untuk menjelaskan pendekatan TDD sebelum meminta siswa untuk menulis algoritma pengurutan daftar dan hal-hal serupa?

Itu tergantung sejauh mana Anda akan menjelaskan TDD.
Sangat membantu untuk mendengar sesuatu. Tetapi siswa mendengar banyak hal yang mereka belum dapat interpret karena dasar-dasar lain masih hilang. Jadi Anda tidak boleh terlalu jauh masuk ke konsep yang tanpa pengetahuan dasar akan menjadi kekacauan yang tidak berguna dan mengasingkan istilah yang tidak diketahui bagi mereka.
Selain itu mungkin banyak programmer tahu bagaimana rasanya jika Anda mencari cara untuk mengatasi beberapa masalah dan menemukan contoh yang memang menunjukkan solusi, tetapi pertama-tama Anda harus memilah semua jenis hal yang tidak relevan lainnya. penulis menambahkan.

Jadi untuk menjawab pertanyaan ini, jika saya seorang siswa saya ingin memiliki hal-hal yang terpisah. Jika Anda mengumumkan untuk menjelaskan kepada kami bagaimana cara mengurutkan daftar maka tolong beri tahu kami bagaimana melakukannya tetapi jangan meninggalkan jalan untuk mengisi hal-hal pengujian. Jika Anda ingin mulai menjelaskan tes maka jangan mengumumkan untuk menerapkan penyortiran karena ini masih tidak terjadi untuk waktu yang lama.
Sekali lagi ada beberapa pemikiran yang diperlukan sebelum kita mulai menulis penyortiran atau tes. Apa yang terlihat dari daftar sebelum dan sesudah pengurutan? Buat contoh, pikirkan jebakan, apa yang harus diperhatikan agar tidak gagal ketika daftar kosong dan sebagainya. Semua ini harus dipertimbangkan tetapi belum ada garis tes yang ditulis.

Secara umum saya akan mengatakan Anda mencampur dua hal yang harus disimpan secara terpisah.

  • Berpikir tentang sifat masalah yang ingin Anda pecahkan.
  • Memikirkan input ke kode Anda dan output apa yang harus diberikan.

Memikirkan masalah sangat berbeda dari berfokus pada penulisan test case.

Bagaimana melakukannya dengan buruk

Suatu kali saya menemukan contoh TDD oleh seseorang yang agak terobsesi dengan TDD.
Sayangnya menurut saya penulis terlalu menyukai tutorialnya sehingga ia tidak menyadari apa itu sebenarnya.

Penulis hanya berkonsentrasi pada kasus uji, bukan pada masalah yang harus ditangani kode mereka. Karena Anda tidak pernah dapat menemukan semua permutasi input, Anda harus memiliki gambaran umum tentang apa yang sebenarnya Anda lakukan, Anda harus melihat keseluruhan masalahnya. Anda tidak selalu dapat memulai dengan input kosong, lalu menambahkan beberapa input lagi dan selalu menambahkan kode untuk menangani input baru dengan benar.
Anda harus memiliki gambaran tentang apa yang sebenarnya Anda hadapi secara umum. Tetapi penulis tidak.

Jika saya mencoba menerjemahkannya ke pengurutan daftar, kami akan mulai dengan daftar kosong, lalu satu elemen yang dapat dikembalikan apa adanya, daftar dengan dua elemen yang mungkin perlu ditukar dan mungkin berakhir dalam rekursi karena tiga elemen seperti dua (kami sudah memecahkannya) ditambah satu lagi dengan satu langkah ekstra ...
Szenario yang mengerikan untuk algoritme pengurutan- tetapi tidak seorang pun akan menyadarinya karena kami hanya berkonsentrasi pada uji kasus.

Kesimpulan

Komentar membuat saya menulis lebih banyak tentang pendapat saya.

Saya pikir istilah "pengembangan yang didorong oleh tes" salah. Itu harus "pengembangan yang didukung tes", yang berarti kita tidak hanya kode dan harapan tetapi kita berpikir tentang pengujian juga dan kita tahu itu selalu baik untuk diketahui sejak dini ketika ada masalah.

Jika pengembangan dinamai didorong oleh tes, ini bisa berarti semuanya hanya tergantung pada tes dan kami selesai segera setelah beberapa kasus uji terpenuhi. Persyaratan ini akan dipenuhi bahkan oleh kode yang sangat tidak mencukupi yang tidak pernah mencoba untuk melihat masalah secara keseluruhan tetapi diretas bolak-balik sampai semua kasus uji kebetulan berubah menjadi hijau - kemudian gagal dalam operasi nyata.

2
puck

Anda telah memperbarui pertanyaan Anda menjadi lebih "Mengapa TDD tidak diajarkan sebagai alat pembelajaran inti?". Jawaban lain sudah menjelaskan dengan cukup baik mengapa TDD bukan topik yang baik untuk pengkodean 101, tetapi jawaban utamanya adalah bahwa TDD, pada intinya, bukanlah alat pemecahan masalah. Ini dapat digunakan untuk tujuan itu, tetapi seperti alat apa pun yang Anda harus terlebih dahulu memahami kapan dan bagaimana menggunakannya.

TDD adalah proses pengujian, dan dengan demikian paling alami akan diajarkan baik sebagai bagian dari kursus Proses Pengembangan, atau sebagai bagian dari kursus Pengujian Perangkat Lunak. Dalam coding 101 program, tujuannya bukan untuk siswa untuk memecahkan masalah, itu untuk mengajarkan mereka bagaimana menggunakan berbagai konsep pemrograman. Secara umum, sebagian besar proyek pengkodean 101 dan 102 akan sangat eksplisit tentang bagaimana menyelesaikan masalah, para siswa hanya perlu memahami apa yang telah mereka pelajari untuk melakukan tugas dengan cara yang agak non-tempel.

Setiap siswa belajar dengan cara yang berbeda. Beberapa siswa perlu membaca tentang hal itu, yang lain membutuhkannya menjelaskan secara lisan kepada mereka, dan yang lain tidak akan pernah mendapatkannya kecuali mereka mendapatkan kode yang mendalam. Mengajar TDD untuk membantu dalam proses pembelajaran tidak akan benar-benar membantu sebagian besar siswa, dan yang tidak membantu? Guru harus memutuskan apakah waktu untuk mengajar TDD sepadan dengan kecepatan belajar tambahan. Secara keseluruhan, pengajaran metode pembelajaran apa pun tidak akan sepadan dengan waktu kelas yang dapat dihabiskan untuk topik khusus kursus aktual. (Secara umum, keterampilan belajar dan memecahkan masalah biasanya diserahkan kepada siswa untuk belajar sendiri, karena hanya siswa yang dapat mengidentifikasi apa yang terbaik bagi mereka)

TL: RD; Orang yang berbeda memiliki proses efektif yang berbeda pula. Universitas tidak menentukan bagaimana Anda harus melakukan apa pun; Berikan saja alatnya sehingga Anda bisa melakukan yang terbaik untuk Anda.

1
Tezra

TDD adalah alat implementasi yang fantastis, dan saya pikir Anda benar tentang hal itu menguntungkan bagi mereka yang ingin menulis perangkat lunak.

Apa alasan TDD tidak diajarkan sama sekali atau paling tidak sangat terlambat di universitas? Dengan kata lain, apakah akan bermasalah untuk menjelaskan pendekatan TDD sebelum meminta siswa untuk menulis algoritma pengurutan daftar dan hal-hal serupa?

Mungkin alasan terbesarnya adalah para profesor yang mengajar program-program ini jarang tahu bagaimana mengembangkan perangkat lunak, karena itu bukan bidang keahlian mereka. Seperti jawaban lain telah disebutkan, ilmu komputer dan rekayasa perangkat lunak adalah disiplin ilmu yang berbeda, dan saya akan membandingkan harapan bahwa siswa ilmu komputer belajar rekayasa perangkat lunak dengan siswa fisika belajar bagaimana merancang mobil. TDD adalah keterampilan yang membutuhkan sejumlah praktik yang layak untuk benar-benar dapat mengajar secara efektif, dan profesor ilmu komputer menghabiskan sebagian besar karir mereka bekerja di bidang ilmu komputer, sehingga mengharapkan fakultas ilmu komputer benar-benar dapat mengajar TDD dengan cara Menurut saya itu tidak akan membingungkan siswa mereka.

Kita perlu memperlakukan ilmu komputer dan pengembangan perangkat lunak profesional sebagai bidang yang jelas terpisah. Jika tujuan Anda adalah mempelajari ilmu komputer, Anda tidak perlu dibebani dengan membayar ribuan dolar untuk mempelajari cara membuat situs web di React salah dari seseorang yang telah menghabiskan 30 tahun terakhir dalam karirnya mengerjakan grafik teori di papan tulis.Juga, jika tujuan Anda adalah untuk menjadi insinyur perangkat lunak, saya tidak tahu mengapa Anda ingin menghabiskan 4 tahun dan puluhan ribu dolar untuk mempelajari apa yang pada dasarnya hanya bidang matematika tertentu. untuk memiliki pemahaman mendasar di lapangan, seperti halnya seseorang yang mendesain manifold knalpot perlu memahami sejumlah ilmu fisika, namun orang yang mendesain manifold knalpot tidak perlu terlalu mendalam tentang pemahaman dalam mekanika kuantum, relativitas khusus, dan elektromagnetisme untuk melakukan pekerjaan mereka.

Jika Anda ingin menjadi seorang akuntan, Anda bisa mendapatkan gelar dalam bidang akuntansi dan profesor Anda kemungkinan besar semuanya adalah CPA pada satu titik atau yang lain. Jika Anda ingin menjadi insinyur mesin, Anda bisa mendapatkan gelar di bidang teknik mesin dan profesor Anda kemungkinan besar semuanya telah menjadi insinyur berlisensi pada satu titik atau yang lain. Tetapi jika Anda ingin menjadi insinyur perangkat lunak, setiap gelar dalam rekayasa perangkat lunak sebenarnya hanya akan menjadi gelar ilmu komputer dengan beberapa pilihan Anda sudah dipilih untuk Anda, dan hampir tidak ada profesor Anda yang pernah menjadi pengembang perangkat lunak profesional. Tingkat akuntansi bukan bagian dari departemen matematika, dan gelar teknik mesin bukan bagian dari departemen fisika, tetapi gelar rekayasa perangkat lunak akan hampir selalu menjadi bagian dari departemen ilmu komputer. Sampai akademisi secara keseluruhan benar-benar memisahkan kedua bidang ini menjadi departemen yang berbeda yang dijalankan oleh staf yang berbeda, saya pikir akan selalu ada daftar panjang hal-hal seperti TDD yang tidak diajarkan kepada siswa yang bercita-cita untuk menjadi insinyur perangkat lunak.

1
Dogs