Apakah TDD benar-benar berfungsi untuk proyek yang kompleks?

53

Saya mengajukan pertanyaan ini mengenai masalah yang saya alami selama proyek TDD. Saya perhatikan tantangan berikut saat membuat unit test.

  • Menghasilkan dan memelihara data tiruan

Sulit dan tidak realistis untuk mempertahankan data tiruan besar. Ini bahkan lebih sulit ketika struktur basis data mengalami perubahan.

  • Menguji GUI

Bahkan dengan MVVM dan kemampuan untuk menguji GUI, dibutuhkan banyak kode untuk mereproduksi skenario GUI.

  • Menguji bisnis

Saya memiliki pengalaman bahwa TDD berfungsi dengan baik jika Anda membatasinya pada logika bisnis sederhana. Namun logika bisnis yang kompleks sulit untuk diuji karena jumlah kombinasi tes (ruang uji) sangat besar.

  • Kontradiksi dalam persyaratan

Pada kenyataannya sulit untuk menangkap semua persyaratan dalam analisis dan desain. Berkali-kali satu persyaratan catatan menimbulkan kontradiksi karena proyek ini kompleks. Kontradiksi ditemukan terlambat di bawah tahap implementasi. TDD mensyaratkan bahwa persyaratannya 100% benar. Dalam kasus seperti itu, orang dapat berharap bahwa persyaratan yang bertentangan akan ditangkap selama pembuatan tes. Tetapi masalahnya adalah bahwa ini tidak terjadi dalam skenario yang kompleks.

Saya telah membaca pertanyaan ini: Mengapa TDD berfungsi?

Apakah TDD benar-benar berfungsi untuk proyek-proyek perusahaan yang kompleks, atau apakah itu praktis terbatas pada jenis proyek?

Amir Rezaei
sumber
+1 Saya memiliki pertanyaan yang sama setelah membaca pertanyaan itu - saya menggunakannya dalam arti terbatas dengan masalah yang sama dengan data tiruan.
Michael K
20
"TDD mensyaratkan bahwa persyaratan 100% benar" di mana "persyaratan" berarti "Saya harus tahu bagaimana metode tunggal ini harus bekerja". Dan jika Anda tidak tahu bagaimana metode ini seharusnya bekerja, bagaimana Anda seharusnya mengimplementasikannya?
Frank Shearar
@ FrankShearar: Anda tahu bagaimana metode harus bekerja pada input yang diharapkan. Katakanlah strcmp harus mengambil 2 petunjuk yang tidak satupun darinya nullptr dan keduanya valid. Anda tidak tahu apa yang akan terjadi ketika Anda memberi umpan buruk. Mungkin pada beberapa arsitektur Anda dapat menangkap AV dan melakukan sesuatu yang waras, tetapi Anda tidak dapat membayangkan skenario seperti itu mungkin, jadi pengujian Anda tidak mencakupnya.
Coder
7
Saya akan mengatakan TDD adalah satu-satunya yang berfungsi untuk proyek-proyek besar! Semakin besar proyek semakin kompleks interaksi dan semakin banyak persyaratan berubah secara acak - hanya TDD yang dapat bersaing
Martin Beckett
2
Sebenarnya, hal hebat tentang TDD dalam hal perubahan persyaratan adalah ketika persyaratan berubah, Anda bisa menulis tes baru untuk persyaratan itu dan memastikan tidak akan merusak sisa proyek. Jika Anda belum memiliki tes tertulis, Anda juga harus menulis tes untuk memastikan perubahan Anda tidak merusak apa pun. Juga, saya suka perbaikan bug. Bahkan jika Anda tidak mengembangkan semuanya menggunakan TDD, gunakan itu untuk perbaikan bug: Tulis tes yang mereproduksi bug, kemudian perbaiki bug dan jalankan tes lagi.
Jordan Reiter

Jawaban:

53

Sulit dan tidak realistis untuk mempertahankan data tiruan besar. Ini bahkan lebih sulit ketika struktur basis data mengalami perubahan.

Salah.

Pengujian unit tidak memerlukan data tiruan "besar". Ini membutuhkan data tiruan yang cukup untuk menguji skenario dan tidak lebih.

Juga, programmer yang benar-benar malas meminta ahli materi pelajaran untuk membuat lembar kerja sederhana dari berbagai kasus uji. Hanya spreadsheet sederhana.

Kemudian programmer malas menulis skrip sederhana untuk mengubah baris spreadsheet menjadi unit uji kasus. Ini sangat sederhana, sungguh.

Ketika produk berevolusi, spreadsheet dari kasus uji diperbarui dan tes unit baru dihasilkan. Lakukan sepanjang waktu. Ini benar-benar berfungsi.

Bahkan dengan MVVM dan kemampuan untuk menguji GUI, dibutuhkan banyak kode untuk mereproduksi skenario GUI.

Apa? "Reproduksi"?

Maksud dari TDD adalah untuk Merancang hal-hal untuk Testability (Pengembangan Drive Test). Jika GUI sangat kompleks, maka harus didesain ulang agar lebih sederhana dan lebih dapat diuji. Simpler juga berarti lebih cepat, lebih mudah dirawat dan lebih fleksibel. Tetapi sebagian besar lebih sederhana akan berarti lebih dapat diuji.

Saya memiliki pengalaman bahwa TDD berfungsi dengan baik jika Anda membatasinya pada logika bisnis sederhana. Namun logika bisnis yang kompleks sulit untuk diuji karena jumlah kombinasi tes (ruang uji) sangat besar.

Itu bisa benar.

Namun, meminta ahli materi pelajaran untuk memberikan kasus uji inti dalam bentuk sederhana (seperti spreadsheet) sangat membantu.

Spreadsheet bisa menjadi agak besar. Tapi tidak apa-apa, karena saya menggunakan skrip Python sederhana untuk mengubah spreadsheet menjadi kasus uji.

Dan. Saya memang harus menulis beberapa test case secara manual karena spreadsheet tidak lengkap.

Namun. Ketika pengguna melaporkan "bug", saya hanya bertanya kasus uji mana dalam spreadsheet yang salah.

Pada saat itu, para ahli materi akan mengoreksi spreadsheet atau mereka akan menambahkan contoh untuk menjelaskan apa yang seharusnya terjadi. Laporan bug dapat - dalam banyak kasus - secara jelas didefinisikan sebagai masalah kasus uji. Memang, dari pengalaman saya, mendefinisikan bug sebagai test case yang rusak membuat diskusi jauh lebih mudah.

Daripada mendengarkan para ahli mencoba menjelaskan proses bisnis yang sangat kompleks, para ahli harus menghasilkan contoh nyata dari proses tersebut.

TDD mensyaratkan bahwa persyaratannya 100% benar. Dalam kasus seperti itu, orang dapat berharap bahwa persyaratan yang bertentangan akan ditangkap selama pembuatan tes. Tetapi masalahnya adalah bahwa ini tidak terjadi dalam skenario yang kompleks.

Tidak menggunakan TDD benar-benar mengamanatkan bahwa persyaratannya 100% benar. Beberapa mengklaim bahwa TDD dapat mentolerir persyaratan yang tidak lengkap dan berubah, di mana pendekatan non-TDD tidak dapat bekerja dengan persyaratan yang tidak lengkap.

Jika Anda tidak menggunakan TDD, kontradiksi ditemukan terlambat dalam tahap implementasi.

Jika Anda menggunakan TDD kontradiksi ditemukan sebelumnya ketika kode melewati beberapa tes dan gagal tes lainnya. Memang, TDD memberi Anda bukti kontradiksi sebelumnya dalam proses, jauh sebelum implementasi (dan argumen selama pengujian penerimaan pengguna).

Anda memiliki kode yang lulus beberapa tes dan gagal lainnya. Anda hanya melihat tes-tes itu dan Anda menemukan kontradiksinya. Ini bekerja sangat, sangat baik dalam praktiknya karena sekarang pengguna harus berdebat tentang kontradiksi dan menghasilkan contoh-contoh konkret dari perilaku yang diinginkan.

S.Lott
sumber
4
@ S.Lott Karena OP kemungkinan besar berbicara tentang WPF / SL sehubungan dengan MVVM, komentar pengujian GUI Anda agak tidak berdasar. Bahkan dengan decoupling dan pendekatan MVVM yang ketat, tampilan dengan definisi masih rumit untuk diuji. Ini dengan UI apa pun. Menguji Tampilan sangat memakan waktu, rumit dan ROI rendah. Di sinilah argumen yang berkaitan dengan permukaan MVVM yang menguji M / VM dan mengabaikan V mungkin merupakan pendekatan terbaik, namun pengujian komponen pada View seperti penempatan kontrol, pewarnaan, dll ... masih sangat memakan waktu dan kompleks.
Aaron McIver
3
@ S.Lott Tergantung pada ruang lingkup. TDD tidak memberikan nilai substansial terkait pengujian Tampilan. Namun TDD memang memberikan nilai substansial berkaitan dengan pengujian Model dan ViewModel. Jika ruang lingkup Anda adalah ViewModel dan Lihat maka nilai TDD akan jauh berbeda berdasarkan ruang lingkup Anda maka jika ruang lingkup Anda adalah Model dan layanan yang diperlukan. Jangan salah paham, saya percaya TDD memiliki nilai substansial di seluruh proyek kompleks ... nilainya hanya berbeda berdasarkan ruang lingkup.
Aaron McIver
5
@ Robert Harvey: Ini bukan penemuan saya. Saya terlalu malas untuk menciptakan apa pun.
S.Lott
4
@Amir Rezaei: Saya minta maaf karena data unit test minimal Anda kompleks. Itu tidak ada hubungannya dengan TDD. Aplikasi Anda kompleks. Anda masih perlu mengujinya, bukan? Anda masih harus menghasilkan data uji? Jika Anda tidak akan mengikuti TDD, bagaimana Anda akan membuat aplikasi yang dapat diuji? Keberuntungan? Berharap? Iya. Ini rumit. Tidak ada yang menghilangkan kompleksitas. TDD memastikan bahwa Anda benar-benar akan menguji kompleksitas itu.
S.Lott
4
@Amir Rezaei: "kami merancang untuk kenyataan". Apakah Anda akan menulis ujian? Jika demikian, maka rancang untuk testabilitas. Jika Anda tidak akan menulis tes, lalu bagaimana Anda tahu sesuatu bekerja?
S.Lott
28

Iya

Paparan pertama saya ke TDD sedang mengerjakan komponen middleware untuk ponsel berbasis Linux. Yang akhirnya menjadi jutaan baris kode sumber, yang pada gilirannya disebut menjadi sekitar 9 gigabyte kode sumber untuk berbagai komponen sumber terbuka.

Semua penulis komponen diharapkan untuk mengusulkan API dan satu set unit test, dan meminta mereka ditinjau oleh panitia. Tidak ada yang mengharapkan kesempurnaan dalam pengujian, tetapi semua fungsi yang terpapar secara publik harus memiliki setidaknya satu tes, dan sekali komponen diserahkan kepada kontrol sumber, semua tes unit harus selalu lulus (bahkan jika mereka melakukannya karena komponen tersebut secara salah melaporkan itu bekerja dengan baik).

Tidak diragukan lagi karena setidaknya sebagian untuk TDD dan desakan bahwa semua tes unit selalu berlalu, rilis 1.0 datang lebih awal, di bawah anggaran, dan dengan stabilitas yang mencengangkan.

Setelah rilis 1.0, karena perusahaan ingin dapat dengan cepat mengubah ruang lingkup karena permintaan pelanggan, mereka mengatakan kepada kami untuk berhenti melakukan TDD, dan menghapus persyaratan yang harus dilewati unit test. Sungguh mengherankan betapa cepatnya kualitas turun ke toilet, dan kemudian jadwal mengikutinya.

Bob Murphy
sumber
8
removed the requirement that unit tests pass. It was astonishing how quickly quality went down the toilet, and then the schedule followed it.- Ini seperti memberi tahu pembalap F1 Anda bahwa ia tidak diizinkan Berhenti Pit karena butuh terlalu banyak waktu ... Idiotik.
Jess Telford
1
Ini mencontohkan apa yang saya selalu katakan: Satu-satunya cara untuk cepat adalah dengan baik !
TheCatWhisperer
18

Saya berpendapat bahwa semakin kompleks proyek, semakin banyak manfaat yang Anda dapatkan dari TDD. Manfaat utama adalah efek samping dari bagaimana TDD akan memaksa Anda untuk menulis kode dalam potongan yang jauh lebih kecil, jauh lebih mandiri. Manfaat utama adalah:

a) Anda mendapatkan validasi desain jauh lebih awal karena loop umpan balik Anda jauh lebih ketat karena tes dari awal.

b) Anda dapat mengubah sedikit demi sedikit dan melihat bagaimana sistem bereaksi karena Anda telah membangun selimut cakupan pengujian sepanjang waktu.

c) Kode jadi akan jauh lebih baik sebagai hasilnya.

Wyatt Barnett
sumber
1
Saya melihat dan mengetahui manfaat TDD. Namun saya berpendapat tentang seberapa realistis dan berapa banyak sumber daya dan biaya yang diperlukan untuk melakukan TDD dalam proyek-proyek tersebut.
Amir Rezaei
Saya harus setuju dengan Anda. Dalam proyek-proyek yang kompleks tidak ada (menurut saya) untuk memastikan bahwa semuanya berfungsi selain dari tes ... Jika banyak programmer bekerja pada basis kode Anda, Anda tidak dapat memastikan bahwa tidak ada yang mengubah pekerjaan Anda. Jika tes terus berlalu - tidak ada masalah. Jika tidak, Anda tahu ke mana harus mencari.
mhr
10

Apakah TDD benar-benar berfungsi untuk proyek yang kompleks?
Iya. Tidak setiap proyek jadi saya diberitahu bekerja dengan baik dengan TDD, tetapi sebagian besar aplikasi bisnis baik-baik saja, dan saya yakin yang tidak berfungsi dengan baik ketika mereka ditulis dengan cara TDD murni dapat ditulis dengan cara ATDD tanpa masalah besar.

Menghasilkan dan memelihara data tiruan
Jaga agar tetap kecil dan hanya memiliki apa yang Anda butuhkan dan ini tampaknya bukan masalah yang menakutkan. Jangan salah paham, itu menyakitkan. Tapi itu bermanfaat.

Menguji GUI.
Tes MVVM dan pastikan itu dapat diuji tanpa melihat. Saya menemukan ini tidak lebih sulit daripada menguji sedikit logika bisnis lainnya. Menguji tampilan dalam kode saya tidak lakukan, semua yang Anda uji namun pada saat ini adalah mengikat logika, yang satu harapan akan ditangkap dengan cepat ketika Anda melakukan tes manual cepat.

Menguji bisnis
Tidak ditemukan masalah. Banyak tes kecil. Seperti yang saya katakan di atas, beberapa kasus (pemecah teka-teki Sudoku tampaknya menjadi populer) tampaknya sulit untuk dilakukan TDD.

TDD mensyaratkan bahwa persyaratannya 100% benar.
Tidak, tidak. Dari mana Anda mendapatkan ide ini? Semua praktik Agile menerima bahwa persyaratan berubah. Anda perlu tahu apa yang Anda lakukan sebelum melakukannya, tetapi itu tidak sama dengan mengharuskan persyaratan menjadi 100%. TDD adalah praktik umum di Scrum, di mana persyaratan (Cerita Pengguna), menurut definisi, tidak 100% lengkap.

mlk
sumber
Jika Anda tidak memiliki persyaratan yang akurat, bagaimana Anda memulai dengan tes unit? Apakah Anda melompat mundur antara implementasi dan desain di tengah sprint?
Amir Rezaei
"Unit" lebih kecil dari persyaratan, dan ya umumnya dapat dilakukan tanpa semua UAC diikat.
mlk
Kami Unit Uji setiap Unit dan juga Unit Tes kombinasi Unit, itulah persyaratannya.
Amir Rezaei
9

Pertama, saya percaya masalah Anda lebih tentang pengujian unit secara umum daripada TDD, karena saya tidak melihat apa pun yang benar-benar spesifik TDD (tes-pertama + siklus refactor merah-hijau) dalam apa yang Anda katakan.

Sulit dan tidak realistis untuk mempertahankan data tiruan besar.

Apa yang Anda maksud dengan data tiruan? Sebuah tiruan seharusnya hanya berisi hampir tidak ada data, yaitu tidak ada bidang selain satu atau dua yang dibutuhkan dalam pengujian, dan tidak ada dependensi selain sistem yang diuji. Menyiapkan nilai tiruan harapan atau nilai pengembalian dapat dilakukan dalam satu baris, jadi tidak ada yang mengerikan.

Ini bahkan lebih sulit ketika struktur basis data mengalami perubahan.

Jika maksud Anda database mengalami perubahan tanpa modifikasi yang tepat telah dibuat untuk model objek, pengujian unit baik tepat di sini untuk memperingatkan Anda tentang itu. Jika tidak, perubahan pada model harus tercermin dalam unit test dengan jelas, tetapi dengan indikasi kompilasi, hal itu mudah dilakukan.

Bahkan dengan MVVM dan kemampuan untuk menguji GUI, dibutuhkan banyak kode untuk mereproduksi skenario GUI.

Anda benar, unit menguji GUI (Tampilan) tidak mudah, dan banyak orang melakukannya dengan baik tanpa itu (selain itu, menguji GUI bukan bagian dari TDD). Sebaliknya, unit yang menguji Pengontrol / Presenter / ViewModel / lapisan menengah apa pun Anda sangat disarankan, sebenarnya itu adalah salah satu alasan utama pola seperti MVC atau MVVM.

Saya memiliki pengalaman bahwa TDD berfungsi dengan baik jika Anda membatasinya pada logika bisnis sederhana. Namun logika bisnis yang kompleks sulit untuk diuji karena jumlah kombinasi tes (ruang uji) sangat besar.

Jika logika bisnis Anda rumit, biasanya unit test Anda sulit dirancang. Terserah kepada Anda untuk membuat mereka menjadi atomik mungkin, masing-masing menguji hanya satu tanggung jawab dari objek yang diuji. Tes unit semakin dibutuhkan dalam lingkungan yang kompleks karena mereka memberikan jaring keamanan yang menjamin bahwa Anda tidak melanggar aturan atau persyaratan bisnis saat Anda membuat perubahan pada kode.

TDD mensyaratkan bahwa persyaratannya 100% benar.

Benar-benar tidak. Perangkat lunak yang berhasil mensyaratkan bahwa persyaratannya 100% benar;) Tes unit hanya mencerminkan visi Anda tentang persyaratan saat ini; jika visi tersebut cacat, kode Anda dan perangkat lunak Anda akan terlalu, unit test atau tidak ... Dan di situlah unit test bersinar: dengan judul tes yang cukup eksplisit, keputusan desain dan interpretasi persyaratan Anda menjadi transparan, yang membuatnya lebih mudah untuk menunjuk jari Anda pada apa yang perlu diubah saat pelanggan Anda berkata, "aturan bisnis ini tidak seperti yang saya inginkan".

guillaume31
sumber
6

Saya harus tertawa ketika mendengar seseorang mengeluh bahwa alasan mereka tidak dapat menggunakan TDD untuk menguji aplikasi mereka adalah karena aplikasi mereka sangat rumit. Apa alternatifnya? Apakah monyet uji menggedor pada hektar keyboard? Biarkan pengguna menjadi penguji? Apa lagi? Tentu saja sulit dan rumit. Apakah Anda pikir Intel tidak menguji chip mereka sampai mereka mengirim? Bagaimana "kepala di pasir" itu?

SnoopDougieDoug
sumber
5
Memiliki pekerja profesional yang sangat terampil yang menulis kode sederhana dan efektif. Dan gunakan penguji. Pendekatan ini telah berhasil untuk banyak perusahaan yang sukses.
Coder
Salah satu alternatif adalah pengujian regresi. Pikirkan, katakanlah, menguji peramban web. Katakanlah Anda Google dan Anda ingin menguji Chrome versi baru. Anda dapat menguji setiap elemen CSS individu, dan setiap atribut dari setiap tag HTML, dan setiap jenis hal dasar yang dapat dilakukan JavaScript. Tetapi berapa banyak kemungkinan kombinasi fitur-fitur ini? Saya tidak berpikir ada orang yang bisa mengetahuinya. Jadi mereka melakukan semua jenis pengujian fitur individu di berbagai memanfaatkan, tetapi pada akhirnya, mereka menjalankan regresi terhadap bank situs web yang dikenal. Itu sejuta monyet di sana.
Dan Korn
Alternatif realistis adalah memberikan perangkat lunak yang tidak berfungsi; dalam keadaan yang tepat, ini masih bisa menguntungkan. Pilih contoh favorit Anda.
soru
4

Saya telah menemukan TDD (dan pengujian unit secara umum) hampir tidak mungkin untuk alasan terkait: Kompleks, novel, dan / atau algoritma fuzzy. Masalah yang paling saya temui dalam prototipe penelitian yang saya tulis adalah bahwa saya tidak tahu apa jawaban yang benar selain dengan menjalankan kode saya. Terlalu rumit untuk mencari tahu dengan tangan untuk apa pun kecuali kasus-kasus sepele yang konyol. Ini terutama benar jika algoritma melibatkan heuristik, perkiraan, atau non-determinisme. Saya masih mencoba untuk menguji fungsionalitas tingkat bawah yang tergantung pada kode ini dan menggunakan sangat menegaskan sebagai pemeriksaan kewarasan. Metode pengujian terakhir saya adalah menulis dua implementasi yang berbeda, idealnya dalam dua bahasa yang berbeda menggunakan dua set pustaka yang berbeda dan membandingkan hasilnya.

dsimcha
sumber
Saya punya masalah ini. Anda perlu kasus sederhana yang berhasil "dengan tangan", dan kasus yang cukup rumit berhasil & divalidasi oleh pakar domain. Jika tidak ada yang bisa melakukan itu, Anda memiliki masalah spesifikasi. Saat Anda dapat menyandikan fungsi penerimaan algoritmik, bahkan jika itu tidak keluar dari ruang keadaan bentuk yang tepat, Anda dapat menggunakannya dengan pengujian statistik (jalankan pengujian 10.000 kali & lihat tren penerimaan jawaban)
Tim Williscroft
"dan kasus yang cukup rumit dikerjakan & divalidasi oleh pakar domain" - Apakah ini merupakan uji unit, atau uji regresi?
quant_dev
2
@ Tim: Saya adalah pakar domain (dalam pekerjaan saya, satu orang biasanya adalah ahli domain dan programmer) dan saya tidak dapat dengan bijaksana mengerjakan hal ini dengan tangan. Di sisi lain, saya hampir selalu tahu kira - kira jawaban apa yang seharusnya (misalnya, algoritma pembelajaran mesin harus membuat prediksi yang cukup akurat, suatu algoritma yang mengumpankan data acak tidak menghasilkan hasil yang "menarik") tetapi ini sulit untuk diotomatisasi. Juga, untuk prototipe penelitian, hampir tidak pernah ada spesifikasi formal.
dsimcha
@quant_dev ini adalah unit test. Ini menguji perilaku unit pada set data uji yang lebih kompleks. Anda dapat menggunakan tes unit untuk pengujian regresi. Anda juga harus menulis tes regresi untuk bug ketika mereka terjadi untuk mencegah terulangnya mereka. (ada bukti kuat bahwa bug cluster)
Tim Williscroft
@dsimcha: sehingga pendekatan statistik untuk pengujian unit dapat bekerja untuk Anda, karena Anda dapat membuat perkiraan peramal. Saya menggunakan pendekatan ini dalam sistem senjata untuk memilih & men-debug target bergerak, memindahkan kode keterlibatan penembak. Sangat sulit untuk menemukan jawaban untuk itu dengan tangan, tetapi relatif mudah untuk mengetahui bahwa sang prediktor bekerja (Anda benar-benar menembakkan proyektil, dan melihat di mana itu hampir mengenai, busa, bilas ulangi 100.000 kali dan Anda mendapatkan hasil yang bagus seperti "Algoritma A bekerja 91% dari waktu, AlgorithmB bekerja 85% dari waktu.)
Tim Williscroft
4
> Does TDD really work for complex projects?

Dari pengalaman saya: Ya untuk Unittests (uji modul / fitur secara terpisah) karena ini sebagian besar tidak memiliki masalah yang Anda sebutkan: (Gui, Mvvm, Business-Modell). Saya tidak pernah memiliki lebih dari 3 ejekan / bertopik untuk memenuhi satu unittest (tapi mungkin domain Anda membutuhkan lebih).

Namun saya tidak yakin apakah TDD dapat menyelesaikan masalah yang Anda sebutkan pada integrasi atau pengujian end-to-end dengan tes gaya BDD.

Namun setidaknya beberapa masalah bisa dikurangi .

> However complex business logic is hard to test since the number 
> of combinations of tests (test space) is very large.

Ini benar jika Anda ingin melakukan cakupan lengkap pada tingkat tes integrasi atau tes ujung ke ujung. Mungkin lebih mudah melakukan peliputan lengkap pada tingkat yang paling sederhana.

Contoh: Memeriksa izin pengguna yang kompleks

Menguji Fungsi IsAllowedToEditCusterData()pada tingkat uji integrasi akan perlu menanyakan objek yang berbeda untuk informasi tentang pengguna, domain, pelanggan, lingkungan .....

Mengejek bagian-bagian ini cukup sulit. Ini terutama benar jika IsAllowedToEditCusterData()harus mengetahui objek yang berbeda ini.

Pada Unittest-Level Anda akan memiliki Function IsAllowedToEditCusterData()yang mengambil contoh 20 parameter yang berisi semua fungsi yang perlu diketahui. Karena IsAllowedToEditCusterData()tidak perlu tahu bidang apa a user, a domain, a customer, .... memiliki ini mudah untuk diuji.

Ketika saya harus mengimplementasikan IsAllowedToEditCusterData()saya memiliki dua kelebihan:

Satu kelebihan yang tidak lebih dari mendapatkan 20 parameter tersebut dan kemudian memanggil kelebihan dengan 20 parameter yang melakukan pengambilan keputusan.

(Saya IsAllowedToEditCusterData()hanya memiliki 5 parameter dan saya membutuhkan 32 kombinasi berbeda untuk mengujinya sepenuhnya)

Contoh

// method used by businesslogic
// difficuilt to test because you have to construct
// many dependant objects for the test
public boolean IsAllowedToEditCusterData() {
    Employee employee = getCurrentEmployee();
    Department employeeDepartment = employee.getDepartment();
    Customer customer = getCustomer();
    Shop shop = customer.getShop();

    // many more objects where the permittions depend on

    return IsAllowedToEditCusterData(
            employee.getAge(),
            employeeDepartment.getName(),
            shop.getName(),
            ...
        );
}

// method used by junittests
// much more easy to test because only primitives
// and no internal state is needed
public static boolean IsAllowedToEditCusterData(
        int employeeAge,
        String employeeDepartmentName,
        String shopName,
        ... ) 
{
    boolean isAllowed; 
    // logic goes here

    return isAllowed;
}
k3b
sumber
1
+1 Contoh yang sangat bagus “Memeriksa izin pengguna yang rumit” yang persis merupakan salah satu skenario kami.
Amir Rezaei
3

Jawaban yang menyedihkan adalah tidak ada yang benar-benar berfungsi untuk proyek kompleks besar!

TDD sebagus apa pun dan lebih baik daripada kebanyakan, tetapi TDD sendiri tidak akan menjamin kesuksesan dalam proyek besar. Namun itu akan meningkatkan peluang kesuksesan Anda. Terutama ketika digunakan dalam kombinasi dengan disiplin manajemen proyek lainnya (verifikasi persyaratan, kasus penggunaan, matriks keterlacakan persyaratan, penelusuran kode, dll.).

James Anderson
sumber
1

Ingat bahwa pengujian unit adalah spesifikasi yang dipaksakan . Ini sangat berharga dalam proyek yang kompleks. Jika basis kode lama Anda tidak memiliki tes untuk mendukungnya, tidak ada yang akan berani mengubah apa pun karena mereka akan takut merusak apa pun.

"Wtf. Mengapa cabang kode ini ada di sana? Tidak tahu, mungkin seseorang membutuhkannya, lebih baik meninggalkannya di sana daripada membuat marah orang lain ..." Seiring waktu proyek-proyek kompleks menjadi lahan sampah.

Dengan tes, siapa pun dapat dengan yakin mengatakan, "Saya telah membuat perubahan drastis, tetapi semua tes masih berlalu." Menurut definisi, dia tidak merusak apa pun. Ini mengarah pada proyek yang lebih gesit yang dapat berkembang. Mungkin salah satu alasan kita masih membutuhkan orang untuk mempertahankan COBOL adalah karena pengujian tidak populer sejak saat itu: P

kizzx2
sumber
1

Saya telah melihat sebuah proyek besar yang kompleks benar-benar gagal ketika TDD digunakan secara eksklusif, yaitu tanpa setidaknya mengatur dalam debugger / IDE. Data tiruan dan / atau tes terbukti tidak memadai. Data nyata klien Beta sensitif dan tidak dapat disalin atau dicatat. Jadi, tim pengembang tidak pernah bisa memperbaiki bug fatal yang bermanifestasi ketika menunjuk data nyata, dan seluruh proyek dihilangkan, semua orang dipecat, semuanya.

Cara untuk memperbaiki masalah ini adalah dengan menjalankannya di debugger di situs klien, hidup terhadap data nyata, melangkah melalui kode, dengan titik istirahat, variabel arloji, menonton memori, dll. Namun, tim ini, yang menganggap kode mereka cocok untuk menghiasi menara gading terbaik, dalam kurun waktu hampir satu tahun tidak pernah sekalipun meluncurkan aplikasi mereka. Itu mengejutkan saya.

Jadi, seperti semuanya, keseimbangan adalah kuncinya. TDD mungkin bagus tetapi tidak bergantung padanya secara eksklusif.

SPA
sumber
1
TDD tidak mencegah kebodohan. TDD adalah salah satu bagian dari kelincahan, tetapi bagian penting lainnya adalah tentang memberikan kode yang dapat dieksekusi dan dapat dijalankan di setiap sprint ...
oligofren
0

Saya kira begitu, lihat Test Driven Development benar-benar berfungsi

Pada tahun 2008, Nachiappan Nagappan, E. Michael Maximilien, Thirumalesh Bhat, dan Laurie Williams menulis makalah yang disebut "Menyadari peningkatan kualitas melalui pengembangan yang digerakkan oleh tes: hasil dan pengalaman dari empat tim industri" (tautan PDF). Abstrak:

Test-driven development (TDD) adalah praktik pengembangan perangkat lunak yang telah digunakan secara sporadis selama beberapa dekade. Dengan praktik ini, seorang insinyur perangkat lunak melakukan siklus menit demi menit antara penulisan unit gagal tes dan penulisan kode implementasi untuk lulus tes tersebut. Pengembangan yang digerakkan oleh tes baru-baru ini muncul kembali sebagai praktik penting yang memungkinkan dari metodologi pengembangan perangkat lunak tangkas. Namun, sedikit bukti empiris yang mendukung atau membantah kegunaan praktik ini dalam konteks industri. Studi kasus dilakukan dengan tiga tim pengembangan di Microsoft dan satu di IBM yang telah mengadopsi TDD. Hasil studi kasus menunjukkan bahwa kepadatan cacat pra-rilis dari empat produk menurun antara 40% dan 90% dibandingkan dengan proyek serupa yang tidak menggunakan praktik TDD. Secara subyektif,

Pada 2012, praktik pengembangan Ruby on Rails mengasumsikan TDD. Saya pribadi bergantung pada alat-alat seperti rspec untuk menulis tes dan ejekan, factory_girl untuk membuat objek, capybara untuk otomatisasi browser, simplecov untuk cakupan kode dan penjaga untuk mengotomatisasi tes ini.

Sebagai hasil dari menggunakan metodologi ini dan alat-alat ini, saya cenderung setuju secara subyektif dengan Nagappan dkk ...

Hiltmon
sumber
0

Jika kombinasi anggaran, persyaratan, dan keterampilan tim ada di kuadran ruang proyek, 'tinggalkan harapan semua yang masuk ke sini', maka menurut definisi, sangat mungkin proyek itu akan gagal.

Mungkin persyaratannya rumit dan tidak stabil, infrastrukturnya tidak stabil, tim junior dan dengan pergantian tinggi, atau arsiteknya bodoh.

Pada proyek TDD, gejala kegagalan yang akan datang ini adalah bahwa tes tidak dapat ditulis sesuai jadwal; Anda mencoba, hanya untuk menemukan 'itu akan mengambil ini panjang, dan kami hanya memiliki itu '.

Pendekatan lain akan menunjukkan gejala yang berbeda ketika gagal; paling umum pengiriman sistem yang tidak berfungsi. Politik dan kontrak akan menentukan apakah itu lebih disukai.

soru
sumber
-1

TDDmungkin terdengar sebagai rasa sakit di muka tetapi dalam jangka panjang itu akan menjadi teman terbaik Anda, percayalah TDDakan benar-benar membuat aplikasi dapat dipertahankan dan aman dalam jangka panjang.

Rachel
sumber