Pengujian TDD vs. Unit [ditutup]

117

Perusahaan saya cukup baru dalam pengujian unit kode kami. Saya telah membaca tentang TDD dan pengujian unit selama beberapa waktu dan yakin akan nilainya. Saya telah berusaha untuk meyakinkan tim kami bahwa TDD sepadan dengan upaya untuk mempelajari dan mengubah pola pikir kami tentang bagaimana kami memprogram tetapi itu adalah perjuangan. Yang membawa saya ke pertanyaan saya.

Ada banyak komunitas TDD yang sangat religius tentang menulis tes dan kemudian kode (dan saya bersama mereka), tetapi untuk tim yang berjuang dengan TDD apakah kompromi masih membawa manfaat tambahan?

Saya mungkin bisa berhasil mendapatkan tim untuk menulis pengujian unit setelah kode ditulis (mungkin sebagai persyaratan untuk memeriksa kode) dan asumsi saya adalah bahwa masih ada nilai dalam menulis pengujian unit tersebut.

Apa cara terbaik untuk membawa tim yang sedang berjuang ke TDD? Dan jika gagal, apakah masih layak untuk menulis unit test meskipun setelah kode ditulis?

EDIT

Apa yang saya ambil dari ini adalah penting bagi kita untuk memulai pengujian unit, di suatu tempat dalam proses pengkodean. Bagi mereka yang berada dalam tim yang mengambil konsep, mulailah bergerak lebih ke arah TDD dan menguji terlebih dahulu. Terima kasih atas masukan semua orang.

MENGIKUTI

Kami baru saja memulai proyek kecil baru dan sebagian kecil tim menggunakan TDD, sisanya menulis unit test setelah kode. Setelah kami menyelesaikan bagian pengkodean proyek, pengujian unit penulisan setelah kode terkejut melihat pengkode TDD sudah selesai dan dengan kode yang lebih solid. Itu adalah cara yang baik untuk memenangkan hati orang-orang yang skeptis. Kami masih memiliki banyak kesulitan di depan, tetapi pertempuran keinginan tampaknya telah berakhir. Terima kasih untuk semua orang yang menawarkan saran!

Walter
sumber
1
Anda mungkin menemukan utas ini bermanfaat: stackoverflow.com/questions/917334/should-i-use-tdd
Randolpho
29
1 untuk TINDAK LANJUT. Itu cerita yang bagus.
Carl Manaster

Jawaban:

76

Jika tim gagal menerapkan TDD, tetapi mereka tidak membuat Pengujian Unit apa pun sebelumnya ... maka mulailah dengan membuat Pengujian Unit setelah kode mereka ditulis. Bahkan Tes Unit yang ditulis setelah kode lebih baik daripada tidak ada Tes Unit sama sekali!

Setelah mereka mahir dalam Pengujian Unit (dan semua yang menyertainya), maka Anda dapat bekerja membuat mereka membuat pengujian terlebih dahulu ... dan membuat kode kedua.

Justin Niessner
sumber
3
Benar bahwa tim tidak membuat pengujian unit apa pun sebelumnya. Ini terasa seperti batu loncatan yang bagus untuk TDD penuh.
Walter
Sangat setuju dengan ini. Sebenarnya, saya rasa saya menulis sesuatu yang mirip untuk pertanyaan serupa beberapa bulan lalu. Dimana itu ... Aah! stackoverflow.com/questions/917334/should-i-use-tdd/…
Randolpho
27

Masih layak untuk menulis tes unit setelah kode ditulis. Hanya saja terkadang sering kali lebih sulit karena kode Anda tidak dirancang untuk dapat diuji, dan Anda mungkin membuatnya terlalu rumit.

Menurut saya cara pragmatis yang baik untuk membawa tim ke TDD adalah dengan memberikan metode alternatif "uji-selama pengembangan" dalam periode transisi, atau mungkin dalam jangka panjang. Mereka harus didorong ke bagian TDD dari kode yang tampak alami bagi mereka. Namun, di bagian kode yang tampaknya sulit untuk didekati dengan uji pertama atau saat menggunakan objek yang telah ditentukan sebelumnya oleh proses A&D yang tidak gesit, pengembang dapat diberikan opsi untuk menulis sebagian kecil kode, kemudian menulis pengujian untuk menutupinya. kode, dan mengulangi proses ini. Menulis pengujian unit untuk beberapa kode segera setelah menulis kode itu lebih baik daripada tidak menulis pengujian unit sama sekali.

Kaleb Brasee
sumber
16

Menurut pendapat saya, lebih baik memiliki cakupan pengujian 50% dengan "kode pertama, uji setelah" dan perpustakaan yang 100% selesai, dari 100% cakupan uji dan perpustakaan lengkap 50% dengan TDD. Setelah beberapa saat, rekan pengembang Anda diharapkan akan merasa terhibur dan mendidik untuk menulis tes untuk semua publickode yang mereka tulis, sehingga TDD akan menyelinap ke dalam rutinitas pengembangan mereka.

Asbjørn Ulsberg
sumber
3
Saya mengerti maksud Anda, tetapi saya khawatir tentang "perpustakaan yang 100% selesai" dengan cakupan pengujian 50% ... hanya dari pengalaman saya bahwa setiap bagian kode yang tidak tercakup oleh beberapa pengujian mengandung setidaknya satu bug. Atau dengan kata lain: Orang cenderung menghindari menulis tes untuk kode yang benar-benar akan mendapat manfaat dari beberapa pengujian lagi :)
Aaron Digulla
2
Nah, cara lain untuk menaruhnya adalah kode buggy yang telah dirilis lebih baik daripada kode sempurna yang mendekam selamanya. Jelas ada pengecualian batuk NASA batuk , tetapi untuk sebagian besar, dapatkan kode Anda di luar sana. Anda masih dapat menambahkan pengujian setelah dirilis.
jcdyer
3
Apa yang Anda maksud dengan "perpustakaan lengkap 100%". Apakah Anda menganggapnya lengkap jika buggy? Bukankah Anda termasuk diuji dalam definisi selesai?
Pascal Thivent
10
sedang diuji bukanlah kondisi yang cukup untuk bebas bug
fa.
2
Cakupan tes yang diukur dengan alat cakupan tes adalah pedang bermata dua. Jika ini dicapai dengan menjalankan semua metode di IUT, tetapi pengujian tersebut tidak benar-benar menguji perilaku yang mungkin rusak, pengembang dan pemangku kepentingan lainnya akan memiliki rasa aman yang salah. Seluruh gerakan menuju TDD dalam organisasi Anda dapat meledak di hadapan Anda ketika perilaku kritis tidak teruji, namun Anda memiliki cakupan pengujian 100%. Yang terpenting bukan kuantitas, tapi kualitas.
Doug Knesek
12

Saya baru saja membaca ini di kalender: "Setiap aturan, dijalankan secara maksimal, menjadi konyol atau bahkan berbahaya." Jadi saran saya jangan menjadi religius tentang itu. Setiap anggota tim Anda harus menemukan keseimbangan antara apa yang mereka rasa "benar" dalam hal pengujian. Dengan cara ini, setiap anggota tim Anda akan menjadi paling produktif (alih-alih, katakanlah, berpikir "mengapa saya harus menulis tes sti **** ini ??").

Jadi beberapa tes lebih baik daripada tidak sama sekali, tes setelah kode lebih baik daripada beberapa tes dan tes sebelum kode lebih baik daripada setelahnya. Tetapi setiap langkah memiliki kelebihannya sendiri dan Anda tidak boleh tidak menyukai langkah-langkah kecil sekalipun.

Aaron Digulla
sumber
"apa yang mereka rasakan" Sebagai pengembang, saya tidak ingat pernah memiliki keinginan (yang benar) untuk melakukan pengujian unit otomatis melalui perasaan saya sendiri, hanya yang manual. Saya tidak berpikir bahwa saya sendirian yang kurang bersemangat dari pengujian
Gennady Vanin Геннадий Ванин
@ vgv8: Itu berarti pengujian Anda tidak membantu Anda. Ada banyak alasan mengapa demikian; Saya menyarankan untuk menggali lebih dalam. Proyek apa pun mendapat manfaat dari tes bagus dan menderita tes buruk. Anda akan melihat ketika Anda mulai menulis tes yang bagus dan sejak saat itu, tidak ada yang bisa menghentikan Anda menulis lebih banyak.
Aaron Digulla
yang terasa benar bagi saya, adalah tingkat pengujian yang mencakup apa yang harus dilakukan unit pemrograman, dan dari tingkat fungsional: apa yang dilakukan pengguna secara normal, yang mencakup hasil buruk yang oleh beberapa orang disebut "bug yang dilaporkan". Jika bug dikonfirmasi, setidaknya satu tes akan ditulis! semakin besar proyek dan semakin besar tim, semakin penting.
DaFi4
12

TDD adalah tentang desain! Jadi jika Anda menggunakannya, Anda pasti memiliki desain kode yang dapat diuji, sehingga lebih mudah untuk menulis pengujian Anda. Jika Anda menulis tes setelah kode ditulis, tes tersebut masih berharga tetapi IMHO Anda akan membuang-buang waktu karena Anda mungkin tidak memiliki desain yang dapat diuji.

Satu saran yang dapat saya berikan kepada Anda untuk mencoba meyakinkan tim Anda untuk mengadopsi TDD adalah dengan menggunakan beberapa teknik yang dijelaskan dalam Fearless Change: Patterns for Introducing New Ideas, oleh Mary Lynn Manns dan Linda Rising .

Diego Dias
sumber
3
+1: Test Driven Development berarti desain digerakkan oleh pertimbangan pengujian.
S. Lott
+1. Tes unit nantinya tentu saja akan membantu Anda, tetapi Anda akan kehilangan manfaat dari memiliki "desain yang dapat diuji" jika Anda tidak menulis pengujian unit di awal.
Noufal Ibrahim
9

Jika mereka baru dalam pengujian daripada IMO memulai kode pengujian yang sudah ditulis dan perlahan-lahan lulus untuk menulis tes terlebih dahulu. Sebagai seseorang yang mencoba mempelajari TDD dan baru dalam pengujian unit, saya merasa agak sulit untuk melakukan 180 lengkap dan mengubah pola pikir saya untuk menulis tes sebelum kode, jadi pendekatan yang saya ambil adalah semacam campuran 50-50 ; ketika saya tahu persis seperti apa tampilan kode itu, saya akan menulis kode dan kemudian menulis tes untuk memverifikasinya. Untuk situasi di mana saya tidak sepenuhnya yakin maka saya akan mulai dengan tes dan bekerja mundur.

Ingat juga bahwa tidak ada yang salah dengan menulis tes untuk memverifikasi kode, daripada menulis kode untuk memenuhi tes. Jika tim Anda tidak ingin mengikuti rute TDD maka jangan memaksakannya.

Wayne Molina
sumber
6

Saya mungkin bisa berhasil mendapatkan tim untuk menulis pengujian unit setelah kode ditulis (mungkin sebagai persyaratan untuk memeriksa kode) dan asumsi saya adalah bahwa masih ada nilai dalam menulis pengujian unit tersebut.

Sama sekali tidak ada keraguan tentang fakta bahwa ada nilai dalam kode unit yang diuji (terlepas dari kapan tes ditulis) dan saya menyertakan "kode adalah unit yang diuji" di "Definisi Selesai". Orang dapat menggunakan TDD atau tidak, selama mereka menguji.

Mengenai kontrol versi, saya suka menggunakan " cabang pengembangan " dengan kebijakan unit yang diuji (yaitu kode mengkompilasi dan membangun, semua pengujian unit lulus). Ketika fitur selesai, fitur tersebut diterbitkan dari cabang pengembangan ke trunk. Dengan kata lain, cabang batang adalah " cabang Selesai " (Tidak ada sampah di bagasi!) Dan memiliki shippable kebijakan (dapat melepaskan setiap saat) yang lebih ketat dan mencakup lebih banyak hal daripada "unit diuji".

Pascal Thivent
sumber
4

Ini adalah sesuatu yang tim Anda harus memiliki kesuksesannya sendiri sebelum mereka mulai mempercayainya. Saya akan mengoceh tentang pencerahan nUnit saya kepada siapa pun yang peduli:

Sekitar 5 tahun yang lalu saya menemukan nUnit saat mengerjakan sebuah proyek. Kami hampir menyelesaikan V1.0 dan saya membuat beberapa tes hanya untuk mencoba alat baru ini. Kami memiliki banyak bug (jelas!) Karena kami adalah tim baru, dengan tenggat waktu yang ketat, ekspektasi tinggi (terdengar familiar?) Dll. Pokoknya kami masuk 1.0 dan mulai 1.1. Kami mengatur ulang tim sedikit dan saya mendapat 2 pengembang yang ditugaskan kepada saya. Saya melakukan demo 1 jam untuk mereka dan memberi tahu mereka bahwa semua yang kami tulis harus memiliki uji kasus. Kami terus-menerus berlari "di belakang" anggota tim lainnya selama siklus pengembang 1.1 karena kami menulis lebih banyak kode, pengujian unit. Kami akhirnya bekerja lebih banyak tetapi inilah hasilnya - ketika kami akhirnya melakukan pengujian, kami memiliki tepat 0 bug dalam kode kami. Kami membantu orang lain men-debug dan memperbaiki bug mereka. Di postmortem, ketika jumlah bug muncul,

Saya tidak cukup bodoh untuk berpikir Anda dapat menguji jalan Anda menuju sukses tetapi saya benar-benar percaya dalam hal tes unit. Proyek mengadopsi nUnit dan segera menyebar ke perusahaan untuk semua proyek .Net sebagai hasil dari 1 keberhasilan. Total periode waktu untuk rilis V1.1 kami adalah 9 minggu pengembang jadi itu pasti BUKAN sukses dalam semalam. Tetapi dalam jangka panjang, itu terbukti berhasil untuk proyek kami dan perusahaan tempat kami membangun solusi.

Tidak Ada Pengembalian Dana Tidak Ada Pengembalian
sumber
"Proyek mengadopsi nUnit dan segera menyebar ke perusahaan untuk semua proyek .Net" Dan apa yang harus dilakukan jika satu produk / proyek memiliki kode C #, Java, C ++, SQL Server?
Gennady Vanin Геннадий Ванин
Entahlah ... Menemukan cara untuk menguji semua komponen sebelum Anda menyebarkan ke produksi? Pengujian unit hanyalah salah satu aspek dari rencana pengujian komprehensif sebelum diluncurkan. Anda dapat membuat lubang dalam skenario apa pun.
Tidak Ada Pengembalian Dana Tidak Ada Pengembalian
4

Tidak ada keraguan bahwa pengujian (Pertama, Saat atau bahkan Setelah) akan menghemat daging Anda, dan meningkatkan produktivitas dan kepercayaan diri Anda. Saya merekomendasikan untuk mengadopsinya!

Saya berada dalam situasi yang sama, karena saya adalah seorang pengembang "pemula", saya sering merasa frustrasi ketika mengerjakan proyek tim oleh fakta bahwa sebuah kontribusi telah merusak pembangunan. Saya tidak tahu apakah saya yang harus disalahkan atau bahkan dalam beberapa kasus, siapa yang harus disalahkan. Tetapi saya lebih khawatir bahwa saya melakukan hal yang sama kepada sesama pengembang. Kesadaran ini kemudian memotivasi untuk mengadopsi beberapa strategi TDD. Tim kami mulai memiliki permainan konyol, dan aturan, seperti Anda tidak bisa pulang sampai semua tes Anda lulus, atau jika Anda mengirimkan sesuatu tanpa tes, maka Anda harus membeli semua orang "bir / makan siang / dll" dan itu membuat TDD lebih menyenangkan.

Dai Bok
sumber
3

Salah satu aspek yang paling berguna dari pengujian unit adalah memastikan kebenaran berkelanjutan dari kode yang sudah berfungsi. Ketika Anda dapat melakukan refactor sesuka hati, biarkan IDE mengingatkan Anda tentang kesalahan waktu kompilasi, lalu klik tombol untuk membiarkan pengujian Anda menemukan potensi kesalahan waktu proses - terkadang tiba di blok kode yang sebelumnya sepele, maka saya pikir Anda akan menemukan tim Anda mulai menghargai TDD. Jadi, memulai dengan menguji kode yang ada pasti berguna.

Juga, terus terang, saya telah belajar lebih banyak tentang bagaimana menulis kode yang dapat diuji dengan mencoba menguji kode tertulis daripada memulai dengan TDD. Ini bisa terlalu abstrak pada awalnya jika Anda mencoba memikirkan kontrak yang akan mencapai tujuan akhir dan memungkinkan pengujian. Tetapi ketika Anda melihat kode dan dapat mengatakan "Singleton ini benar-benar merusak injeksi ketergantungan dan membuat pengujian ini tidak mungkin," Anda mulai mengembangkan apresiasi untuk pola apa yang membuat kehidupan pengujian Anda lebih mudah.

David Berger
sumber
3

Nah, jika Anda tidak menulis tes terlebih dahulu, itu bukan "Test Driven", itu hanya pengujian. Ini memiliki manfaat tersendiri dan jika Anda semua sudah memiliki basis kode menambahkan tes untuk itu tentu berguna bahkan jika itu bukan TDD tetapi hanya pengujian.

Menulis tes terlebih dahulu adalah tentang berfokus pada apa yang harus dilakukan kode sebelum menulisnya. Ya, Anda juga mendapatkan tes melakukan itu dan itu bagus, tetapi beberapa orang mungkin berpendapat itu bahkan bukan poin yang paling penting.

Yang akan saya lakukan adalah melatih tim pada proyek mainan seperti ini (lihat Coding Dojo, Katas) menggunakan TDD (jika Anda bisa mengajak programmer TDD berpengalaman untuk berpartisipasi dalam lokakarya semacam itu, akan lebih baik lagi). Ketika mereka akan melihat manfaatnya, mereka akan menggunakan TDD untuk proyek sebenarnya. Tetapi sementara itu jangan memaksa mereka, jika mereka tidak melihat manfaatnya mereka tidak akan melakukannya dengan benar.

kriss
sumber
3

Jika Anda memiliki sesi desain sebelum menulis kode atau harus menghasilkan dokumen desain, Anda dapat menambahkan Pengujian Unit sebagai hasil nyata dari sebuah sesi.

Ini kemudian dapat berfungsi sebagai spesifikasi tentang cara kerja kode Anda. Dorong pasangan pada sesi desain, untuk membuat orang berbicara tentang bagaimana sesuatu harus bekerja dan apa yang harus dilakukan dalam skenario tertentu. Apa kasus edge, dengan kasus uji eksplisit untuk mereka sehingga semua orang tahu apa yang akan dilakukan jika diberi argumen nol misalnya.

Disamping tetapi BDD juga mungkin menarik

danswain
sumber
Saya tidak menyadari BDD. Saya harus membaca lebih lanjut tentang itu.
Walter
3

Anda mungkin menemukan beberapa daya tarik dengan menunjukkan satu atau dua contoh di mana TDD menghasilkan lebih sedikit kode yang ditulis - karena Anda hanya menulis kode yang diperlukan untuk lulus ujian, godaan untuk lempengan emas atau terlibat dalam YAGNI lebih mudah ditolak. Kode yang tidak Anda tulis tidak perlu dipertahankan, difaktorkan ulang, dll, jadi ini adalah "penghematan nyata" yang dapat membantu menjual konsep TDD.

Jika Anda dapat dengan jelas mendemonstrasikan nilai dalam hal waktu, biaya, kode dan bug yang disimpan, Anda mungkin merasa ini lebih mudah menjual.

Michael Nash
sumber
2

Memulai membangun kelas pengujian JUnit adalah cara untuk memulai, untuk kode yang ada, itulah satu-satunya cara untuk memulai. Dalam pengalaman saya, sangat berguna untuk membuat kelas uji untuk kode yang ada. Jika menurut manajemen hal ini akan menghabiskan terlalu banyak waktu, Anda dapat mengusulkan untuk hanya menulis kelas pengujian ketika kelas yang sesuai ditemukan mengandung bug, atau perlu dibersihkan.

Untuk proses pemeliharaan, pendekatan untuk membuat tim melewati batas adalah menulis pengujian JUnit untuk mereproduksi bug sebelum Anda memperbaikinya, yaitu

  • bug dilaporkan
  • buat kelas pengujian JUnit jika diperlukan
  • tambahkan tes yang mereproduksi bug
  • perbaiki kode Anda
  • jalankan tes untuk menunjukkan kode saat ini tidak mereproduksi bug

Anda dapat menjelaskan bahwa dengan "mendokumentasikan" bug dengan cara ini akan mencegah bug tersebut menyusup kembali nanti. Itu adalah manfaat yang dapat dialami tim dengan segera.

rsp
sumber
2

Saya telah melakukan ini di banyak organisasi dan saya telah menemukan satu-satunya cara terbaik untuk memulai dan mengikuti TDD adalah dengan mengatur pemrograman berpasangan. Jika Anda memiliki orang lain yang dapat Anda andalkan yang mengetahui TDD, maka Anda berdua dapat berpisah dan berpasangan dengan pengembang lain untuk benar-benar melakukan pemrograman berpasangan menggunakan TDD. Jika tidak, saya akan melatih seseorang yang akan membantu Anda melakukan ini sebelum mempresentasikannya kepada anggota tim lainnya.

Salah satu rintangan utama dengan pengujian unit dan terutama TDD adalah bahwa pengembang tidak tahu bagaimana melakukannya, sehingga mereka tidak dapat melihat bagaimana hal itu bisa sepadan dengan waktu mereka. Juga ketika Anda pertama kali memulai, itu jauh lebih lambat dan sepertinya tidak memberikan manfaat. Ini hanya benar-benar memberi Anda manfaat ketika Anda ahli dalam hal itu. Dengan menyiapkan sesi pemrograman berpasangan, Anda dapat dengan cepat membuat pengembang dapat mempelajarinya dengan cepat dan menjadi ahli lebih cepat. Selain itu, mereka akan dapat melihat manfaat langsung darinya saat Anda mengerjakannya bersama.

Pendekatan ini telah berhasil berkali-kali bagi saya di masa lalu.

John Sonmez
sumber
2

Salah satu cara ampuh untuk menemukan manfaat TDD adalah dengan melakukan penulisan ulang yang signifikan dari beberapa fungsionalitas yang ada, mungkin karena alasan kinerja. Dengan membuat rangkaian pengujian yang berfungsi dengan baik yang mencakup semua fungsionalitas kode yang ada, ini kemudian memberi Anda kepercayaan diri untuk melakukan refactor ke isi hati Anda dengan keyakinan penuh bahwa perubahan Anda aman.

Perhatikan bahwa dalam kasus ini saya berbicara tentang pengujian desain atau kontrak - pengujian unit bahwa rincian implementasi pengujian tidak akan cocok di sini. Tapi sekali lagi, TDD tidak dapat menguji implementasi secara definisi, karena mereka seharusnya ditulis sebelum implementasi.

Chris Welsh
sumber
1

TDD adalah alat yang dapat digunakan pengembang untuk menghasilkan kode yang lebih baik. Saya kebetulan merasa bahwa latihan menulis kode yang dapat diuji sama berharganya dengan tes itu sendiri. Mengisolasi IUT (Implementasi Dalam Pengujian) untuk tujuan pengujian memiliki efek samping dalam memisahkan kode Anda.

TDD bukan untuk semua orang, dan tidak ada keajaiban yang akan membuat tim memilih untuk melakukannya. Risikonya adalah bahwa penulis unit test yang tidak tahu apa yang layak untuk diuji akan menulis banyak tes bernilai rendah, yang akan menjadi umpan meriam bagi para skeptis TDD di organisasi Anda.

Saya biasanya membuat Tes Penerimaan otomatis tidak dapat dinegosiasikan, tetapi mengizinkan pengembang untuk mengadopsi TDD karena cocok untuk mereka. Saya telah melatih / membimbing TDDers saya yang berpengalaman dan "membuktikan" kegunaannya dengan contoh selama beberapa bulan.

Ini adalah perubahan sosial / budaya dan juga teknis.

Doug Knesek
sumber