Kapan tepat untuk tidak menguji unit?

139

Saya bekerja di perusahaan kecil sebagai pengembang solo. Sebenarnya saya satu-satunya pengembang di perusahaan itu. Saya memiliki beberapa (relatif) proyek besar yang telah saya tulis dan kelola secara teratur, dan tidak satu pun dari mereka memiliki tes untuk mendukungnya. Ketika saya memulai proyek baru, saya sering bertanya-tanya apakah saya harus mencoba pendekatan TDD. Kedengarannya seperti ide yang bagus, tapi jujur ​​saya tidak pernah bisa membenarkan kerja ekstra yang terlibat.

Saya bekerja keras untuk berpikiran maju dalam desain saya. Saya menyadari bahwa suatu hari nanti pengembang lain harus menjaga kode saya, atau paling tidak memecahkannya. Saya menjaga hal-hal sesederhana mungkin dan saya berkomentar dan mendokumentasikan hal-hal yang sulit untuk dipahami. Dan faktanya adalah proyek-proyek ini tidak begitu besar atau rumit sehingga pengembang yang layak akan berjuang untuk memahaminya.

Banyak contoh yang saya lihat dari tes sampai ke hal-hal kecil, yang mencakup semua aspek kode. Karena saya adalah satu-satunya pengembang dan saya sangat dekat dengan kode di seluruh proyek, jauh lebih efisien untuk mengikuti pola tulis-kemudian-secara manual-tes. Saya juga menemukan persyaratan dan fitur berubah cukup sering sehingga mempertahankan tes akan menambah jumlah hambatan pada suatu proyek. Waktu itu kalau tidak bisa dihabiskan untuk menyelesaikan kebutuhan bisnis.

Jadi saya berakhir dengan kesimpulan yang sama setiap kali. Pengembalian investasi terlalu rendah.

Saya kadang-kadang menyiapkan beberapa tes untuk memastikan saya telah menulis algoritma dengan benar, seperti menghitung berapa tahun seseorang telah berada di perusahaan berdasarkan tanggal perekrutan mereka. Tetapi dari sudut pandang cakupan kode saya telah membahas sekitar 1% dari kode saya.

Dalam situasi saya, apakah Anda masih menemukan cara untuk membuat unit menguji praktik biasa, atau apakah saya dibenarkan untuk menghindari overhead itu?

UPDATE: Beberapa hal tentang situasi saya yang saya tinggalkan: Proyek saya adalah semua aplikasi web. Untuk mencakup semua kode saya, saya harus menggunakan tes UI otomatis, dan itu adalah area di mana saya masih tidak melihat manfaat besar dibandingkan pengujian manual.

Ken Pespisa
sumber
1
Terimakasih semuanya. Saya belajar banyak di sini. Beberapa hal tentang situasi saya yang saya tinggalkan: Proyek saya adalah semua aplikasi web. Untuk mencakup semua kode saya, saya harus menggunakan tes UI otomatis, dan itu adalah area di mana saya masih tidak melihat manfaat besar dibandingkan pengujian manual.
Ken Pespisa
1
Kami mengalami kesuksesan besar di Transactis menggunakan alat pengujian otomasi web Telerik. Kami sudah memiliki puluhan tes browser manual yang sebelumnya dikonversi menjadi otomatisasi. Tes otomatis WAY lebih cepat, dan juga HEBAT untuk menyoroti masalah kinerja yang mungkin dimiliki situs web Anda.
John Kaster
2
Saya telah melihat sebuah proyek yang mencoba untuk menguji browser secara otomatis dari halaman web lengkap. Sejauh yang saya tahu, itu belum menemukan ratusan bug parah yang kami temukan melalui pengujian manual, dan menghabiskan banyak waktu untuk mengembangkan dan memelihara. (Menggunakan Selenium didorong oleh NUnit). Lebih buruk lagi, beberapa tes sering putus karena tidak ada masalah, karena browser dan kerangka pengujian tidak kompatibel.
O'Rooney
1
Ini bukan jawaban, hanya pengamatan ... argumen Anda terhadap pengujian unit karena "persyaratan terlalu sering berubah" mengingatkan saya pada argumen terbalik yang saya dengar di tempat saya bekerja: "program kami sangat statis, apa gunanya pengujian itu? Hampir tidak pernah berubah! " ;)
Bane
2
Tes UI otomatis aplikasi web bukan tes unit, semuanya adalah binatang yang berbeda dan saya tidak akan menyalahkan Anda jika Anda tidak ingin melakukannya. Tetapi semua kode bisnis Anda harus di backend, dan itulah yang harus Anda uji.
Nyamiou The Galeanthrope

Jawaban:

85

Banyak contoh yang saya lihat dari tes sampai ke hal-hal kecil, yang mencakup semua aspek kode.

Begitu? Anda tidak perlu menguji semuanya . Hanya hal-hal yang relevan.

Karena saya adalah satu-satunya pengembang dan saya sangat dekat dengan kode di seluruh proyek, jauh lebih efisien untuk mengikuti pola tulis-kemudian-secara manual-tes.

Itu sebenarnya salah. Itu tidak lebih efisien. Ini benar-benar hanya kebiasaan.

Apa yang dilakukan pengembang solo lain adalah menulis sketsa atau garis besar, menulis kasus uji, lalu mengisi garis besar dengan kode akhir.

Itu sangat, sangat efisien.

Saya juga menemukan persyaratan dan fitur berubah cukup sering sehingga mempertahankan tes akan menambah jumlah hambatan pada suatu proyek.

Itu juga salah. Tes bukan hambatan. Perubahan persyaratan adalah hambatan.

Anda harus memperbaiki tes untuk mencerminkan persyaratan. Apakah hal-hal kecil mereka, atau tingkat tinggi; ditulis pertama atau terakhir ditulis.

Kode tidak selesai sampai tes berlalu. Itulah satu kebenaran universal perangkat lunak.

Anda dapat memiliki tes penerimaan terbatas "ini dia".

Atau Anda dapat melakukan beberapa tes unit.

Atau Anda dapat memiliki keduanya.

Tapi apa pun yang Anda lakukan, selalu ada tes untuk menunjukkan bahwa perangkat lunak itu berfungsi.

Saya akan menyarankan bahwa sedikit formalitas dan rangkaian alat uji unit yang bagus membuat tes itu jauh lebih berguna.

S.Lott
sumber
8
Saya suka pernyataan pertama Anda, untuk menguji hal-hal yang relevan saja. Mengenai efisiensi pengujian manual vs unit, saya tidak percaya pernyataan saya sepenuhnya salah, atau Anda sepenuhnya benar. Tampaknya ada keseimbangan yang dapat ditemukan antara pengujian otomatis dan manual untuk mencapai efisiensi maksimum.
Ken Pespisa
9
@Ken Pespisa: Maaf. Saya minum TDD Kool-Aid sekitar dua tahun yang lalu (setelah 30 tahun terakhir). Sekarang saya mandek dulu. Itu membuat saya jauh, jauh lebih produktif karena saya kurang berpikir untuk melakukannya ketika membangun.
S.Lott
3
@Ken Pespisa: Tidak. Ada keseimbangan dalam jawaban. Jika Anda bertanya apakah itu benar untuk membaginya dengan nol, Anda akan mendapatkan respons yang luar biasa cenderung satu arah karena suatu alasan. Jika Anda bertanya apakah sqrt(-1)harus bilangan bulat, Anda akan mendapatkan respons luar biasa dengan satu arah. Keseimbangan adalah sekitar "bagaimana" dan "urutan apa". Fakta sebenarnya adalah bahwa Anda harus menguji. Jadi, tulis dulu tesnya dan pastikan semuanya bekerja.
S.Lott
21
Pertimbangkan unit menguji antarmuka bukan detail implementasi. Uji batas dan batas kasus. Uji kode berisiko. Banyak kode yang cukup sederhana untuk diverifikasi dengan inspeksi, meskipun memeriksa kode Anda lebih rentan kesalahan daripada memeriksa kode orang lain. Tes manual pertama kali mungkin lebih efisien, pada tes kesepuluh kali otomatis jauh di depan.
BillThor
10
"Kode tidak selesai sampai tes lulus" - Tidak juga, IMO. Kode dimulai ketika melewati tes. Kode tidak dilakukan sampai kode ini hidup selama satu atau dua tahun dan menjadi subjek stress test dan tes integrasi dengan basis pengguna yang besar, aktif dan tidak sabar. Itulah satu-satunya pengujian yang benar-benar diperhitungkan.
Vektor
108

Bayangkan Anda memiliki serangkaian tes yang dapat berjalan di eyeblink dan akan menyala lampu hijau atau merah. Bayangkan bahwa rangkaian tes ini menguji semuanya ! Bayangkan yang harus Anda lakukan untuk menjalankan serangkaian tes adalah mengetikkan ^ T. Kekuatan apa yang akan memberimu ini?

Bisakah Anda membuat perubahan pada kode tanpa takut merusak sesuatu? Bisakah Anda menambahkan fitur baru tanpa takut merusak fitur lama? Bisakah Anda membersihkan kode berantakan dengan cepat tanpa takut melakukan kerusakan?

Ya, Anda bisa melakukan semua itu! Dan apa yang akan terjadi pada kode Anda dari waktu ke waktu? Itu akan menjadi lebih bersih dan bersih karena tidak akan ada risiko untuk membersihkannya.

Mari kita bayangkan bahwa Anda memiliki peri kecil di bahu Anda. Setiap kali Anda menulis satu baris kode, peri akan menambahkan sesuatu ke suite tes yang menguji bahwa baris kode itu melakukan apa yang seharusnya dilakukan. Jadi setiap beberapa detik Anda dapat menekan ^ T dan melihat bahwa baris kode terakhir yang Anda tulis berhasil.

Berapa banyak debug yang menurut Anda akan Anda lakukan?

Jika ini kedengarannya seperti fantasi, Anda benar. Namun kenyataannya tidak jauh berbeda. Ganti eyeblink dengan beberapa detik, dan peri dengan disiplin TDD, dan Anda sudah cukup banyak mendapatkannya.

Katakanlah Anda kembali ke sistem yang Anda buat setahun lalu, dan Anda lupa cara membuat salah satu objek utama. Ada tes yang membuat objek itu setiap cara dapat dibuat. Anda dapat membaca tes-tes itu dan menyiarkan memori Anda. Perlu menelepon API? Ada tes yang memanggil API itu setiap cara dapat dipanggil. Tes-tes ini adalah dokumen - dokumen kecil , ditulis dalam bahasa yang Anda mengerti. Mereka sama sekali tidak ambigu. Mereka begitu formal sehingga mereka mengeksekusi. Dan mereka tidak dapat keluar dari sinkronisasi dengan aplikasi!

Tidak layak investasi? Anda pasti bercanda! Bagaimana mungkin ada orang yang TIDAK menginginkan rangkaian tes itu? Bantulah diri Anda sendiri dan berhentilah berdebat dengan kekonyolan. Belajarlah untuk melakukan TDD dengan baik, dan perhatikan seberapa cepat Anda melangkah, dan seberapa bersih kode Anda.

Paman Bob.
sumber
29
Wow, Paman Bob? Sangat menyenangkan untuk mendapatkan pemikiran Anda di sini. Saya setuju dengan Anda tentang manfaat TDD, benar-benar tidak ada argumen yang bisa didapat di sana. Pertanyaannya adalah tentang investasi waktu dan ROI. Tidak konyol bagi saya untuk mempertimbangkan hal-hal ini. Bayangkan sebuah proyek akan membuat saya 50% lebih banyak waktu untuk menyelesaikan dengan TDD daripada tanpa, dan peri mengatakan kepada saya itu hanya akan menyelamatkan saya 10% waktu dari pengujian manual selama masa proyek. Itu mungkin tampak seperti fantasi, tetapi saya melihatnya sepenuhnya masuk akal dengan proyek-proyek tertentu.
Ken Pespisa
11
@ Ken "Bayangkan sebuah proyek akan membuat saya 50% lebih banyak waktu untuk menyelesaikan dengan TDD daripada tanpa". Kedengarannya persis seperti fantasi bagiku. Bahkan, sepertinya Anda baru saja membuat angka itu di tempat tanpa sedikit pun bukti untuk mendukungnya.
Rein Henrichs
18
@Rein Henrichs - Tentu saja saya membuat nomor, itu adalah pernyataan hipotetis. Saya menegaskan bahwa TDD menambahkan sejumlah besar waktu untuk sebuah proyek, dan saya harus mempertimbangkan apakah saya akan mendapatkan sesuatu yang sama atau lebih baik sebagai imbalannya. Anda tidak harus meyakinkan saya tentang nilai-nilai TDD, saya yakin. Tapi itu bukan obat mujarab.
Ken Pespisa
11
@Rein, apa sebenarnya "bukti yang tersedia?" Tolong jelaskan.
Ken Pespisa
22
@Uncle Bob "Ganti eyeblink dengan beberapa detik": Anda bercanda, tentu saja. TDD adalah alat yang baik, tetapi Anda harus menguji hanya bagian-bagian yang relevan jika tidak, Anda menghabiskan lebih banyak waktu mempertahankan tes daripada melakukan pengembangan serius. Ini terutama benar ketika persyaratan berubah dengan sangat cepat: Anda terus-menerus menulis dan membuang ujian untuk kelas yang berubah setiap saat. Saya tidak mengatakan TDD itu buruk, itu hanya harus digunakan secara masuk akal dan tidak diterapkan secara mekanis seperti yang Anda sarankan.
Giorgio
34

Kesalahan yang Anda buat adalah bahwa Anda melihat pengujian sebagai investasi waktu tanpa pengembalian segera. Tidak harus seperti itu.

Tes menulis pertama benar-benar memfokuskan Anda pada apa yang perlu dilakukan bagian kode ini.

Menjalankan keduanya mengungkapkan bug yang seharusnya muncul dalam pengujian.

Menjalankan ketiga terkadang menunjukkan bug yang tidak akan muncul dalam pengujian dan kemudian akan benar-benar menggigit Anda dalam produksi.

Keempat jika Anda menekan bug dengan sistem yang sedang berjalan dan membuat unit test untuknya, Anda tidak akan bisa memperkenalkan kembali bug itu nanti. Itu bisa sangat membantu. Bug yang diperkenalkan kembali adalah hal yang umum dan sangat mengganggu.

Kelima, jika Anda perlu menyerahkan kode kepada orang lain, test suite akan membuat hidup mereka jauh lebih mudah. Juga jika Anda telah mengabaikan proyek dan kembali ke sana setelah beberapa tahun, Anda tidak akan begitu dekat dengan itu lagi dan itu akan membantu Anda juga.

Pengalaman saya secara konsisten adalah bahwa dalam pengembangan proyek, memiliki unit test yang layak selalu membuat proses lebih cepat dan lebih dapat diandalkan.

glenatron
sumber
2
@ Ken, test suites adalah spesifikasi dalam bentuk yang dapat dieksekusi.
32

Orang-orang di JUnit (kerangka uji Java Unit) memiliki filosofi bahwa jika terlalu mudah untuk diuji, jangan mengujinya . Saya sangat merekomendasikan membaca FAQ Praktik Terbaik mereka , karena cukup pragmatis.

TDD adalah proses penulisan perangkat lunak Anda yang berbeda. Premis dasar di balik pengujian unit adalah bahwa Anda akan menghabiskan lebih sedikit waktu dalam debugger melangkah melalui kode, dan lebih cepat mencari tahu apakah perubahan kode Anda secara tidak sengaja merusak sesuatu yang lain dalam sistem. Itu cocok dengan TDD. Siklus TDD seperti ini:

  1. Tulis ujian
  2. Tontonlah gagal (buktikan Anda memiliki sesuatu untuk dilakukan)
  3. Tulis saja apa yang diperlukan untuk lulus ujian - tidak lagi.
  4. Tonton lewat (yay!)
  5. Refactor (membuatnya lebih baik)
  6. Cuci, bilas, dan ulangi

Apa yang kurang jelas tentang penerapan TDD adalah bahwa ia mengubah cara penulisan kode Anda . Dengan memaksa diri Anda berpikir tentang cara menguji / memvalidasi bahwa kode berfungsi, Anda menulis kode yang dapat diuji. Dan karena kita berbicara pengujian unit, itu biasanya berarti bahwa kode Anda menjadi lebih modular. Bagi saya, kode modular dan dapat diuji adalah kemenangan besar di depan.

Sekarang, apakah Anda perlu menguji hal-hal seperti properti C #? Bayangkan sebuah properti didefinisikan seperti ini:

bool IsWorthTesting {get; set;}

Jawabannya adalah "tidak", ini tidak layak untuk diuji, karena pada titik ini Anda menguji fitur bahasa. Hanya percaya bahwa platform C # orang benar. Selain itu, jika gagal, apa yang bisa Anda lakukan untuk memperbaikinya?

Juga, Anda akan menemukan bahwa ada bagian-bagian tertentu dari kode Anda yang sangat baik akan terlalu banyak upaya untuk menguji dengan benar. Itu berarti jangan lakukan itu, tetapi pastikan Anda menguji kode yang menggunakan / digunakan oleh masalah rumit:

  • Pengecualian yang diperiksa hanya dapat terjadi jika pemasangan menjadi buruk. Jawa memiliki banyak hal. Anda diharuskan untuk menulis blok pemblokiran atau mendeklarasikan pengecualian yang dicentang bahkan jika tidak ada cara untuk gagal tanpa meretas file yang diinstal.
  • Antarmuka pengguna. Menemukan kontrol sedang diuji, dan menerapkan peristiwa yang tepat untuk mensimulasikan tindakan pengguna sangat merepotkan, dan dalam beberapa kasus tidak mungkin. Namun, jika Anda menggunakan pola Model / View / Controller, Anda dapat memastikan model dan pengendali Anda diuji dan membiarkan bagian tampilan untuk pengujian manual.
  • Interaksi klien / server. Ini bukan lagi tes unit, dan sekarang merupakan tes integrasi . Tulis semua bagian yang naik untuk mengirim dan menerima pesan melalui kabel, tetapi jangan benar-benar melewati kabel. Pendekatan yang baik adalah mengurangi tanggung jawab kode yang benar-benar berbicara melalui kawat ke komunikasi mentah. Dalam kode uji unit Anda, tiru objek komunikasi untuk memastikan layanan berperilaku seperti yang Anda harapkan.

Percaya atau tidak, TDD akan membantu Anda jatuh ke dalam laju pembangunan berkelanjutan. Ini bukan karena sihir, melainkan karena Anda memiliki umpan balik yang ketat dan Anda dapat menangkap kesalahan yang sangat bodoh dengan cepat. Biaya untuk memperbaiki kesalahan tersebut pada dasarnya adalah konstan (setidaknya cukup untuk tujuan perencanaan) karena kesalahan kecil tidak pernah tumbuh menjadi kesalahan besar. Bandingkan dengan sifat sprint kode pesta / debug purge sprint.

Berin Loritsch
sumber
24

Anda harus menyeimbangkan biaya pengujian dengan biaya bug.

Menulis tes unit 10 baris untuk fungsi yang membuka file, di mana kegagalannya adalah "file tidak ditemukan" tidak ada gunanya.

Fungsi yang melakukan sesuatu yang kompleks pada struktur data yang kompleks - maka jelas ya.

Agak sulit ada di antara keduanya. Tapi ingat nilai sebenarnya dari unit test tidak menguji fungsi tertentu, itu menguji interaksi rumit di antara mereka. Jadi tes unit yang melihat bahwa perubahan dalam satu bit kode, memecah beberapa fungsi dalam modul yang berbeda 1000 baris jauhnya, bernilai berat dalam kopi.

Martin Beckett
sumber
23

Pengujian adalah judi.

Membuat tes adalah bertaruh bahwa biaya bug dalam unit terjadi dan tidak menangkap mereka dengan tes itu (sekarang, dan selama semua revisi kode masa depan) lebih besar daripada biaya pengembangan tes. Biaya pengembangan pengujian tersebut mencakup hal-hal seperti penggajian untuk rekayasa pengujian tambahan, penambahan waktu ke pasar, biaya peluang yang hilang karena tidak mengkode hal-hal lain, dan sebagainya.

Seperti taruhan apa pun, terkadang Anda menang, terkadang Anda kalah.

Kadang-kadang perangkat lunak terlambat dengan bug jauh lebih sedikit menang atas hal-hal cepat tapi buggy yang sampai ke pasar terlebih dahulu. Terkadang sebaliknya. Anda harus melihat statistik di bidang khusus Anda, dan seberapa banyak manajemen ingin bertaruh.

Beberapa jenis bug mungkin sangat tidak mungkin dibuat, atau berhasil keluar dari pengujian kewarasan awal, sehingga secara statistik tidak sepadan dengan waktu untuk membuat tes khusus tambahan. Tetapi kadang-kadang biaya bug sangat besar (medis, nuklir, dll) sehingga perusahaan harus mengambil taruhan yang kalah (mirip dengan membeli asuransi). Banyak aplikasi tidak memiliki biaya kegagalan yang tinggi, dan karenanya tidak memerlukan perlindungan asuransi yang tidak ekonomis. Yang lainnya melakukannya.

hotpaw2
sumber
3
Jawaban yang bagus. Salah satu dari sedikit yang benar-benar menjawab pertanyaan awal saya. Saya telah menenggelamkan diri ke dunia pengujian sejak menulis posting ini (saya suka itu btw.) Saya perlu lebih memahaminya sebelum saya benar-benar tahu kapan menggunakannya (atau tidak). Karena banyak alasan yang dinyatakan di sini, saya lebih suka menggunakannya setiap saat. Tetapi pada akhirnya itu akan tergantung pada seberapa cepat saya mendapatkannya, karena pada akhirnya itu adalah pertaruhan waktu saya, yang berada di bawah kendali perusahaan / klien saya, dan sering kali mereka fokus pada sudut bawah segitiga proyek: id. wikipedia.org/wiki/Project_triangle
Ken Pespisa
10

Saran saya adalah hanya menguji kode yang Anda ingin berfungsi dengan benar.

Jangan menguji kode yang Anda ingin menjadi buggy dan menyebabkan masalah bagi Anda di jalan.

Nick Hodges
sumber
9
Mengingatkan saya pada pepatah yang dikatakan dokter gigi saya: Anda tidak perlu mengganti gigi Anda, hanya gigi yang ingin Anda pertahankan.
Ken Pespisa
Saya akui itulah yang membuat saya memikirkannya. ;-)
Nick Hodges
8

Saya sering bertanya-tanya apakah saya harus mencoba pendekatan TDD. Kedengarannya seperti ide yang bagus, tapi jujur ​​saya tidak pernah bisa membenarkan kerja ekstra yang terlibat.

TDD dan Unit Testing bukan hal yang sama.

Anda dapat menulis kode, lalu menambahkan unit test nanti. Itu bukan TDD, dan banyak pekerjaan tambahan.

TDD adalah praktik pengkodean dalam satu lingkaran Lampu Merah. Lampu hijau. Iterasi refactor.

Ini berarti menulis tes untuk kode yang belum ada, menonton tes gagal, memperbaiki kode untuk membuat tes bekerja, kemudian membuat kode "benar". Ini sering menghemat pekerjaan Anda

Salah satu kelebihan TDD adalah mengurangi kebutuhan untuk memikirkan hal-hal sepele. Hal-hal seperti kesalahan satu demi satu menghilang. Anda tidak harus mencari melalui dokumentasi API untuk mengetahui apakah daftar yang dikembalikan dimulai dari 0 atau 1, lakukan saja.

Paul Butcher
sumber
Bisakah Anda menguraikan bagaimana kesalahan satu-per-satu hilang? Apakah Anda mengatakan bahwa Anda dapat lebih cepat mendapatkan jawaban tentang apakah indeks array berbasis nol atau berbasis satu melalui pengujian daripada mencari melalui dokumentasi? Sepertinya tidak bagi saya - Saya cukup cepat di Google :)
Ken Pespisa
1
Sebenarnya, menulis TDD adalah cara terbaik untuk menjelajahi API (termasuk basis kode warisan, untuk keperluan mendokumentasikan fungsionalitas).
Frank Shearar
Ini juga sangat berguna jika API itu pernah berubah ... Anda tiba-tiba mengalami beberapa tes yang gagal :-)
bitsoflogic
@ Ken Pespisa, ini pasti lebih cepat - tulis kode berdasarkan apakah Anda pikir itu 0 atau 1, jalankan, perbaiki jika diperlukan. Sebagian besar waktu, Anda akan benar dan Anda akan melewatkan harus mencarinya, jika Anda salah, Anda tahu dalam 10 detik.
Paul Butcher
Manfaatnya sangat menarik. Saya agak suka itu.
Ken Pespisa
3

Saya bekerja pada sistem di mana kami menguji hampir semuanya. Eksekusi penting untuk pengujian adalah kode output PDF dan XLS.

Mengapa? Kami dapat menguji bagian-bagian yang mengumpulkan data dan membangun model yang digunakan untuk membuat output. Kami juga dapat menguji bagian-bagian yang menemukan bagian model mana yang akan digunakan untuk file PDF. Kami tidak dapat menguji apakah PDF tampak baik karena itu benar-benar subjektif. Kami tidak dapat menguji apakah semua bagian dalam PDF dapat dibaca oleh pengguna biasa karena itu juga subjektif. Atau jika pilihan antara diagram batang dan pai benar untuk dataset.

Jika output akan menjadi subyektif, ada sedikit pengujian unit yang dapat Anda lakukan sepadan dengan usaha.

sal
sumber
Sebenarnya, pengujian semacam ini mungkin "pengujian integrasi". Dan ya, pengujian integrasi jauh lebih sulit daripada pengujian unit, dan salah satu alasannya adalah bahwa kadang-kadang aturan untuk apa yang "benar" sangat rumit, atau bahkan subjektif.
sleske
2

Untuk banyak hal, 'tes-kemudian-manual-tes' tidak membutuhkan waktu lebih lama daripada menulis beberapa tes. Penghematan waktu berasal dari kemampuan untuk menjalankan kembali tes tersebut kapan saja.

Anggap saja: Jika Anda memiliki beberapa cakupan fitur yang layak dengan tes Anda (tidak harus bingung dengan cakupan kode), dan katakanlah Anda memiliki 10 fitur - mengklik sebuah tombol berarti Anda memiliki kira-kira, 10 kasih kembali melakukan tes Anda ... sementara Anda duduk dan menyesap kopi Anda.

Anda juga tidak perlu menguji minutae. Anda dapat menulis tes integrasi yang mencakup fitur-fitur Anda jika Anda tidak ingin turun ke detail yang rumit ... IMO, beberapa unit test terlalu halus menguji bahasa dan platform, dan bukan kode.

TL; DR Ini benar-benar tidak pernah tepat karena manfaatnya terlalu bagus.

Steven Evers
sumber
2

Dua jawaban yang sangat baik yang saya temui ada di sini:

  1. Kapan melakukan uji unit vs uji manual
  2. Apa yang tidak diuji ketika datang ke Unit Testing?

Pembenaran untuk menghindari persepsi overhead:

  • Penghematan waktu / biaya untuk perusahaan Anda
  • Potensi Penghematan waktu / biaya dalam pemecahan masalah / pemeliharaan / ekstensi dalam jangka panjang bahkan setelah Anda pergi.

Apakah Anda tidak ingin meninggalkan produk hebat dari sisi Anda sebagai bukti kualitas pekerjaan Anda? Berbicara dengan sikap egois, bukankah lebih baik bagimu daripada kamu?

Aditya P
sumber
1
Pertanyaan bagus di akhir. Saya bangga dengan pekerjaan saya, tentu saja, dan aplikasi saya bekerja dengan sangat baik (jika saya berani). Tapi Anda benar - mereka bisa lebih baik dengan dukungan beberapa tes. Saya pikir saya mengambil di sini adalah untuk mencoba masuk sebanyak mungkin tes berguna dalam waktu saya harus bekerja pada proyek, dan tanpa terlalu terobsesi dengan cakupan kode.
Ken Pespisa
1

Pengembang profesional menulis unit test karena, dalam jangka panjang, mereka menghemat waktu. Anda akan menguji kode Anda cepat atau lambat, dan jika Anda tidak melakukannya, maka jika Anda harus memperbaiki bug, mereka akan lebih sulit untuk memperbaikinya dan lebih banyak mengetuk efek.

Jika Anda menulis kode tanpa tes dan tanpa bug maka baik-baik saja. Saya tidak percaya Anda dapat menulis sistem non-sepele dengan nol bug, jadi saya berasumsi Anda sedang menguji satu atau lain cara.

Tes unit juga penting untuk mencegah regresi ketika Anda memodifikasi atau memperbaiki kode lama. Mereka tidak membuktikan perubahan Anda tidak merusak kode lama tetapi mereka memberi Anda banyak kepercayaan (selama mereka lulus tentu saja :))

Saya tidak akan kembali dan menulis seluruh tes untuk kode yang sudah Anda kirim, tetapi lain kali Anda perlu memodifikasi fitur yang saya sarankan untuk mencoba menulis tes untuk modul atau kelas itu, dapatkan cakupan Anda hingga 70% + sebelum Anda menerapkan perubahan apa pun. Lihat apakah itu membantu Anda.

Jika Anda mencobanya dan dapat dengan jujur ​​mengatakan itu tidak membantu maka cukup adil, tetapi saya pikir ada cukup bukti industri yang mereka bantu untuk membuatnya setidaknya layak untuk Anda saat menguji coba pendekatan.

Steve
sumber
Saya suka pemikiran tentang mencegah regresi dan menambah kepercayaan diri. Itulah alasan saya ingin menambahkan tes.
Ken Pespisa
1

Sepertinya sebagian besar jawaban adalah pro-TDD, meskipun pertanyaannya bukan tentang TDD tetapi tentang tes unit secara umum.

Tidak ada aturan yang sepenuhnya objektif di balik apa yang harus diuji unit atau tidak untuk tes unit. Tetapi ada beberapa kali di mana tampaknya banyak programmer tidak menguji unit:

  1. Metode pribadi

Bergantung pada filosofi OOP Anda, Anda dapat membuat metode pribadi untuk memisahkan rutinitas kompleks dari metode publik Anda. Metode publik biasanya dimaksudkan untuk dipanggil di banyak tempat yang berbeda dan sering digunakan, dan metode pribadi hanya benar-benar dipanggil oleh satu atau dua metode publik di kelas atau modul untuk sesuatu yang sangat spesifik. Biasanya cukup untuk menulis unit test untuk metode publik tetapi bukan metode pribadi yang mendasari yang membuat beberapa keajaiban terjadi. Jika ada yang salah dengan metode pribadi, tes unit metode publik Anda harus cukup baik untuk mendeteksi masalah ini.

  1. Hal-hal yang sudah Anda ketahui seharusnya berfungsi (atau hal-hal yang diuji oleh orang lain)

Banyak programmer baru menentang ini ketika mereka pertama kali belajar untuk menguji, dan berpikir bahwa mereka perlu menguji setiap baris yang dieksekusi. Jika Anda menggunakan perpustakaan eksternal dan fungsinya diuji dan didokumentasikan dengan baik oleh penulisnya, biasanya tidak ada gunanya menguji fungsionalitas khusus dalam pengujian unit. Misalnya, seseorang mungkin menulis tes untuk memastikan bahwa model ActiveRecord mereka tetap memiliki nilai yang benar untuk atribut dengan callback "before_save" ke database, meskipun perilaku itu sendiri sudah diuji secara menyeluruh di Rails. Metode yang dipanggil oleh panggilan balik, mungkin, tetapi bukan perilaku panggilan balik itu sendiri. Setiap masalah mendasar dengan perpustakaan yang diimpor akan lebih baik terungkap melalui tes penerimaan, daripada tes unit.

Keduanya bisa berlaku apakah Anda sedang melakukan TDD atau tidak.

Ravenstine
sumber
0

Ken, saya dan banyak pengembang lain di luar sana telah sampai pada kesimpulan yang sama seperti Anda beberapa kali sepanjang karier kami.

Kebenaran yang saya yakin akan Anda temukan (seperti yang lainnya) adalah bahwa investasi awal tes menulis untuk aplikasi Anda mungkin tampak menakutkan, tetapi jika ditulis dengan baik dan ditargetkan pada bagian kode yang benar, mereka benar-benar dapat menghemat satu ton waktu.

Masalah besar saya adalah dengan kerangka pengujian yang tersedia. Saya tidak pernah benar-benar merasa seperti itu yang saya cari, jadi saya hanya menggulung solusi saya yang sangat sederhana. Ini benar-benar membantu membawa saya ke "sisi gelap" pengujian regresi. Saya akan membagikan cuplikan pseudo dasar dari apa yang saya lakukan di sini, dan mudah-mudahan Anda dapat menemukan solusi yang cocok untuk Anda.

public interface ITest {
    public string Name {
        get;
    }
    public string Description {
        get;
    }
    public List<ITest> SubTests {
        get;
    }
    public TestResult Execute();
}

public class TestResult {
    public bool Succesful {
        get;
        set;
    }

    public string ResultMessage {
        get;
        set;
    }

    private Dictionary<ITest, TestResult> subTestResults = new Dictionary<ITest, TestResult>();
    public Dictionary<ITest, TestResult> SubTestResults {
        get {
            return subTestResults;
        }
        set {
            subTestResults = value;
        }
    }
}

Satu-satunya bagian yang sulit setelah itu adalah mencari tahu tingkat granularitas apa yang Anda pikirkan adalah yang terbaik untuk proyek apa pun yang Anda lakukan.

Membangun buku alamat akan sangat membutuhkan pengujian jauh lebih sedikit daripada mesin pencari perusahaan, tetapi dasarnya tidak benar-benar berubah.

Semoga berhasil!

Adam Carstensen
sumber
Saya pikir seiring waktu saya akan mencari tahu tingkat granularitas apa yang terbaik. Adalah baik untuk mendengar dari orang lain yang secara teratur membuat tes yang mereka dekati secara masuk akal dan tidak secara robotis menulis tes untuk setiap hasil yang mungkin. Pengantar pertama saya untuk tes adalah pada tingkat di mana semuanya harus diuji. Bahkan, seluruh konsep TDD tampaknya mengikuti mantra itu.
Ken Pespisa
Saya pikir Anda mungkin mendapat manfaat dari menggunakan Kerangka Kerja seperti SubSpec (ini terinspirasi oleh BDD), sehingga akan memungkinkan Anda untuk mendapatkan Isertasi ("SubTest") sambil berbagi pengaturan konteks.
Johannes Rudolph