Apa cakupan kode yang masuk akal% untuk pengujian unit (dan mengapa)? [Tutup]

605

Jika Anda memandatkan cakupan kode persentase minimum untuk pengujian unit, bahkan mungkin sebagai persyaratan untuk melakukan repositori, apa jadinya?

Tolong jelaskan bagaimana Anda sampai pada jawaban Anda (karena jika yang Anda lakukan hanyalah memilih nomor, maka saya bisa melakukannya sendiri;)

kewarasan
sumber
Sekarang, suatu hari banyak IDE hadir dengan menyoroti cakupan, pastikan Anda mencakup bagian paling penting dari kode setidaknya dari pada berpikir untuk mendapatkan persentase tertentu.
Semua ini
4
% simbol adalah bau kode untuk metrik (juga% adalah bau omong kosong pada umumnya)
Hernán Eche
Tes unit menurut definisi dapat berupa metode individual, seluruh kelas, atau seluruh modul. Sekalipun Anda menguji semua metode, Anda mungkin tidak menguji semua jalur atau semua kombinasi yang akan dipukul pengguna. Situasi menjadi lebih kompleks dengan pernyataan, jangkauan cabang dan MCDC.
Ska
Mengapa pertanyaan ini tidak dihapus atau diedit dengan benar. Itu mengumpulkan begitu banyak minat tetapi itu benar-benar menyesatkan.
Ska

Jawaban:

1391

Prosa karya Alberto Savoia ini menjawab dengan tepat pertanyaan itu (dengan cara yang menghibur!):

http://www.artima.com/forums/flat.jsp?forum=106&thread=204677

Testivus Pada Cakupan Tes

Dini hari, seorang programmer bertanya kepada master besar:

“Saya siap menulis beberapa unit test. Cakupan kode apa yang harus saya tuju? "

Tuan besar itu menjawab:

"Jangan khawatir tentang liputan, cukup tulis beberapa tes bagus."

Si programmer tersenyum, membungkuk, dan pergi.

...

Kemudian pada hari itu, seorang programmer kedua mengajukan pertanyaan yang sama.

Tuan yang agung menunjuk sebuah panci berisi air mendidih dan berkata:

"Berapa butir beras yang harus aku taruh di panci itu?"

Si programmer, tampak bingung, menjawab:

“Bagaimana aku bisa memberitahumu? Itu tergantung pada berapa banyak orang yang Anda butuhkan untuk memberi makan, seberapa lapar mereka, apa makanan lain yang Anda sajikan, berapa banyak beras yang Anda miliki, dan sebagainya. ”

"Tepat sekali," kata tuan besar.

Programmer kedua tersenyum, membungkuk, dan pergi.

...

Menjelang akhir hari, programmer ketiga datang dan menanyakan pertanyaan yang sama tentang cakupan kode.

"Delapan puluh persen dan tidak kurang!" Jawab master dengan suara keras, meninju tinjunya di atas meja.

Programmer ketiga tersenyum, membungkuk, dan pergi.

...

Setelah jawaban terakhir ini, seorang magang muda mendekati tuan agung:

“Tuan yang hebat, hari ini saya mendengar Anda menjawab pertanyaan yang sama tentang cakupan kode dengan tiga jawaban berbeda. Mengapa?"

Tuan yang agung berdiri dari kursinya:

"Ayo bawa teh segar bersamaku dan mari kita bicarakan."

Setelah mereka mengisi cangkir mereka dengan merokok teh hijau panas, tuan besar itu mulai menjawab:

“Pemrogram pertama adalah baru dan baru memulai dengan pengujian. Saat ini ia memiliki banyak kode dan tidak ada tes. Masih banyak jalan yang harus dilaluinya; memfokuskan pada cakupan kode pada saat ini akan menyedihkan dan sangat tidak berguna. Lebih baik dia membiasakan diri menulis dan menjalankan beberapa tes. Dia bisa khawatir tentang liputan nanti. "

“Pemrogram kedua, di sisi lain, cukup berpengalaman baik dalam pemrograman dan pengujian. Ketika saya menjawab dengan bertanya kepadanya berapa banyak butir beras yang harus saya masukkan ke dalam panci, saya membantunya menyadari bahwa jumlah pengujian yang diperlukan tergantung pada sejumlah faktor, dan dia tahu faktor-faktor itu lebih baik daripada saya - itu kode dia setelah semua . Tidak ada jawaban tunggal, sederhana, dan dia cukup pintar untuk menangani kebenaran dan bekerja dengannya. ”

"Aku mengerti," kata pekerja magang muda, "tetapi jika tidak ada jawaban sederhana, lalu mengapa Anda menjawab programmer ketiga 'Delapan puluh persen dan tidak kurang'?"

Tuan yang agung tertawa begitu keras dan keras sehingga perutnya, bukti bahwa dia minum lebih dari sekedar teh hijau, jatuh naik turun.

"Programmer ketiga hanya menginginkan jawaban sederhana - bahkan ketika tidak ada jawaban sederhana ... dan kemudian tidak mengikutinya."

Magang muda dan guru besar beruban selesai minum teh mereka dalam keheningan kontemplatif.

Jon Limjap
sumber
62
Kedengarannya seperti argumen yang menentang konsep umum cakupan kode, sebagai metrik untuk mengevaluasi kegunaan uji unit. Saya yakin semua orang setuju itu bukan metrik yang sempurna, tapi pengalaman pribadi semoga menunjukkan korelasi antara CC% dan efektivitas unit test ...
sanity
16
kewarasan - pernyataan Anda dicerminkan secara tepat oleh respons terhadap "pengembang kedua". Pengalaman pribadi harus mendikte itu.
Jon Limjap
167
Jawaban sempurna. Metrik tidak membuat kode yang baik. Anda dapat menulis kode jelek dengan cakupan 100% dan itu tidak membuat kode itu bekerja dengan baik. +1 dari saya, sayang saya tidak bisa lebih :)
Rob Cooper
15
4 tahun kemudian, dan masih bermanfaat. Baru saja menarik ini pada dua rekan saya pagi ini.
SickHippie
9
Bagi saya, anekdot ini mewakili pandangan idealis. Dalam dunia nyata tim proyek dengan prioritas yang bersaing, cakupan kode meningkat hingga 0%. Kami membutuhkan nomor yang diperlukan untuk membangun kebiasaan pengujian unit dalam tim. Saya sampai pada pertanyaan ini mencari beberapa petunjuk untuk menentukan angka untuk suatu daerah yang saya tidak terlalu kenal, dan ini benar-benar tidak membantu sama sekali. Saya senang orang-orang di skenario lain merasa berguna.
samspot
85

Cakupan Kode adalah metrik yang menyesatkan jika cakupan 100% adalah tujuan Anda (alih-alih 100% menguji semua fitur).

  • Anda bisa mendapatkan 100% dengan menekan semua garis sekali. Namun Anda masih bisa melewatkan pengujian urutan tertentu (jalur logis) di mana garis-garis tersebut dipukul.
  • Anda tidak bisa mendapatkan 100% tetapi masih harus menguji semua 80% / freq Anda menggunakan jalur kode. Memiliki tes yang menguji setiap 'throw ExceptionTypeX' atau penjaga pemrograman defensif serupa yang Anda masukkan adalah 'menyenangkan untuk memiliki' bukan 'harus memiliki'

Jadi percayai diri Anda atau pengembang Anda untuk menyeluruh dan mencakup setiap jalur melalui kode mereka. Jadilah pragmatis dan jangan mengejar cakupan 100% magis. Jika Anda TDD kode Anda, Anda harus mendapatkan cakupan + 90% sebagai bonus. Gunakan kode-cakupan untuk menyorot potongan kode yang Anda lewatkan (seharusnya tidak terjadi jika Anda TDD .. karena Anda menulis kode hanya untuk membuat lulus ujian. Tidak ada kode yang bisa ada tanpa tes mitra.)

Gishu
sumber
4
- Pengecualian - jika Anda tidak menguji pengecualian Anda, bagaimana Anda tahu kode Anda tidak meledak ketika itu terjadi? - Setter / Getters - sensitif konteks, saya kira, tetapi tentu saja tes Anda harus menjalankannya sebagai bagian dari rangkaian uji, dan jika tidak, apakah benar-benar digunakan?
tddmonkey
1
Pengecualian harus luar biasa - tidak seharusnya terjadi. Jika ya, Anda mencatat titik kegagalan dan jaminan. Anda tidak dapat menguji setiap pengecualian yang dapat terjadi. Jika aplikasi seharusnya menangani jalur / acara yang tidak bahagia, Anda harus melakukan tes untuk itu. Accessor dapat ditambahkan untuk klien masa depan .. tergantung
Gishu
5
Saya tidak yakin apa yang Anda maksud dengan poin kedua Anda "tetapi masih menguji semua jalur kode Anda". Jika Anda sebenarnya berarti cakupan jalur penuh, maka tidak ada Anda tidak dapat memiliki cakupan jalur penuh tanpa cakupan garis / cabang / keputusan 100%. Bahkan, cakupan jalur penuh biasanya tidak dapat diperoleh dalam program non-sepele karena sifat kombinatorik cabang dalam menghasilkan jalur. en.wikipedia.org/wiki/Code_coverage#Other_coverage_criteria
Zach Burlingame
3
Anda tidak menguji setiap pengecualian yang mungkin; tentu saja kamu tidak bisa melakukan itu. Anda HARUS bertujuan menguji setiap blok kode yang menangani pengecualian. Misalnya, jika Anda memiliki persyaratan bahwa ketika blok X melempar pengecualian, pengecualian dicatat dalam database, garis hijau di bagian bawah layar berubah merah, dan email dikirim ke Paus; maka itulah yang harus Anda uji. Tetapi Anda tidak perlu menguji setiap pengecualian yang mungkin yang dapat memicu peristiwa ini.
Dawood ibn Kareem
2
+1 untuk "Gunakan cakupan kode untuk menyorot potongan kode yang Anda lewatkan". Itulah gunanya metrik itu bagus.
beluchin
61

Cakupan kode bagus, tetapi cakupan fungsionalitasnya lebih baik. Saya tidak percaya pada setiap baris yang saya tulis. Tetapi saya benar-benar percaya dalam menulis cakupan pengujian 100% dari semua fungsi yang ingin saya berikan (bahkan untuk fitur-fitur keren lainnya saya datang sendiri dan yang tidak dibahas selama pertemuan).

Saya tidak peduli apakah saya akan memiliki kode yang tidak tercakup dalam tes, tetapi saya akan peduli jika saya akan memperbaiki kode saya dan akhirnya memiliki perilaku yang berbeda. Oleh karena itu, cakupan fungsionalitas 100% adalah satu-satunya target saya.

tofi9
sumber
4
Ini jawaban yang fantastis. Kode yang memenuhi persyaratannya adalah tujuan yang jauh lebih berharga daripada kode yang memenuhi beberapa metrik cakupan LoC sewenang-wenang.
Dawood ibn Kareem
46
Jika Anda dapat memberikan semua fungsionalitas tanpa mengenai semua baris kode, lalu apa yang dilakukan baris-baris kode tambahan di sana?
Jens Timmerman
4
@JensTimmerman secara teori Anda benar. Namun, cakupan kode 100% terlalu mahal untuk waktu, dan memaksa tim saya untuk melakukan itu tidak hanya mendemotivasi mereka, tetapi juga membuat proyek saya berjalan melebihi tenggat waktu. Saya suka berada di suatu tempat di tengah, dan fungsi pengujian (sebut saja: pengujian integrasi) adalah apa yang saya rasa nyaman. Kode apa yang tidak saya uji? Penanganan pengecualian teknis, (rentang / parameter) memeriksa yang mungkin diperlukan. Singkatnya, semua pipa ledeng teknis yang saya pelajari terapkan dari pengalaman sendiri atau praktik terbaik yang saya baca.
tofi9
2
Saya mengambil langkah ini lebih jauh dengan membuat daftar situasi umum yang harus dimasukkan atau dikecualikan dari pengujian. Dengan begitu, kami tidak pernah mengemudi menuju persen, melainkan cakupan fungsional semua bagian basis kode yang berfungsi.
Skeeterdrums
58

Jawaban yang diterima membuat poin yang bagus - tidak ada angka tunggal yang masuk akal sebagai standar untuk setiap proyek. Ada proyek yang tidak membutuhkan standar seperti itu. Di mana jawaban yang diterima tidak sesuai, menurut pendapat saya, adalah dalam menggambarkan bagaimana seseorang dapat membuat keputusan untuk proyek tertentu.

Saya akan mencoba melakukannya. Saya bukan ahli dalam rekayasa tes dan akan senang melihat jawaban yang lebih banyak informasi.

Kapan harus menetapkan persyaratan cakupan kode

Pertama, mengapa Anda ingin menerapkan standar seperti itu? Secara umum, ketika Anda ingin memperkenalkan kepercayaan empiris dalam proses Anda. Apa yang saya maksud dengan "kepercayaan empiris"? Ya, tujuan sebenarnya yang benar . Untuk sebagian besar perangkat lunak, kami tidak mungkin mengetahui hal ini di semua input, jadi kami setuju untuk mengatakan bahwa kode tersebut telah teruji dengan baik . Ini lebih dapat diketahui, tetapi masih merupakan standar subyektif: Akan selalu terbuka untuk diperdebatkan apakah Anda telah memenuhi atau tidak. Perdebatan itu bermanfaat dan harus terjadi, tetapi mereka juga mengekspos ketidakpastian.

Cakupan kode adalah pengukuran objektif: Setelah Anda melihat laporan cakupan Anda, tidak ada ambiguitas tentang apakah standar telah dipenuhi bermanfaat. Apakah itu membuktikan kebenaran? Tidak sama sekali, tetapi memiliki hubungan yang jelas dengan seberapa baik kode diuji, yang pada gilirannya adalah cara terbaik kami untuk meningkatkan kepercayaan pada kebenarannya. Cakupan kode adalah perkiraan terukur kualitas tak terukur yang kami pedulikan.

Beberapa kasus tertentu di mana memiliki standar empiris dapat menambah nilai:

  • Untuk memuaskan pemangku kepentingan. Untuk banyak proyek, ada berbagai aktor yang memiliki minat pada kualitas perangkat lunak yang mungkin tidak terlibat dalam pengembangan perangkat lunak sehari-hari (manajer, pemimpin teknis, dll.) Mengatakan "kita akan menulis semua tes yang benar-benar kita butuhkan "tidak meyakinkan: Mereka perlu mempercayai sepenuhnya, atau memverifikasi dengan pengawasan ketat yang berkelanjutan (dengan asumsi mereka bahkan memiliki pemahaman teknis untuk melakukannya.) Memberikan standar yang terukur dan menjelaskan bagaimana mereka memperkirakan secara wajar tujuan aktual lebih baik.
  • Untuk menormalkan perilaku tim. Di samping para pemangku kepentingan, jika Anda bekerja pada sebuah tim di mana banyak orang menulis kode dan tes, ada ruang untuk ambiguitas tentang apa yang memenuhi syarat sebagai "teruji dengan baik." Apakah semua kolega Anda memiliki gagasan yang sama tentang tingkat pengujian yang cukup baik? Mungkin tidak. Bagaimana Anda mendamaikan ini? Temukan metrik yang Anda semua bisa setujui dan terima sebagai perkiraan yang masuk akal. Ini terutama (tapi tidak eksklusif) berguna dalam tim besar, di mana lead mungkin tidak memiliki pengawasan langsung terhadap pengembang junior, misalnya. Jaringan kepercayaan juga penting, tetapi tanpa pengukuran objektif, mudah bagi perilaku kelompok untuk menjadi tidak konsisten, bahkan jika semua orang bertindak dengan itikad baik.
  • Untuk menjaga diri Anda jujur. Bahkan jika Anda satu-satunya pengembang dan satu-satunya pemangku kepentingan untuk proyek Anda, Anda mungkin memiliki kualitas tertentu untuk perangkat lunak tersebut. Alih-alih membuat penilaian subyektif yang sedang berlangsung tentang seberapa baik perangkat lunak diuji (yang mengambil pekerjaan), Anda dapat menggunakan cakupan kode sebagai perkiraan yang masuk akal, dan biarkan mesin mengukurnya untuk Anda.

Metrik mana yang digunakan

Cakupan kode bukan metrik tunggal; ada beberapa cara untuk mengukur cakupan. Yang mana Anda mungkin menetapkan standar tergantung pada apa yang Anda gunakan untuk memenuhi standar itu.

Saya akan menggunakan dua metrik umum sebagai contoh kapan Anda dapat menggunakannya untuk menetapkan standar:

  • Pernyataan cakupan : Berapa persentase pernyataan yang telah dieksekusi selama pengujian? Berguna untuk mengetahui cakupan fisik kode Anda: Berapa banyak kode yang telah saya tulis yang telah saya uji?
    • Cakupan semacam ini mendukung argumen kebenaran yang lebih lemah, tetapi juga lebih mudah untuk dicapai. Jika Anda hanya menggunakan cakupan kode untuk memastikan bahwa segala sesuatu diuji (dan bukan sebagai indikator kualitas pengujian di luar itu) maka cakupan pernyataan mungkin cukup.
  • Cakupan cabang : Ketika ada logika percabangan (mis. An if), sudahkah kedua cabang dievaluasi? Ini memberikan pengertian yang lebih baik tentang cakupan logis kode Anda: Berapa banyak jalur yang mungkin diambil oleh kode saya yang telah saya uji?
    • Cakupan semacam ini adalah indikator yang jauh lebih baik bahwa suatu program telah diuji melalui serangkaian input yang komprehensif. Jika Anda menggunakan cakupan kode sebagai pendekatan empiris terbaik untuk kepercayaan pada kebenaran, Anda harus menetapkan standar berdasarkan cakupan cabang atau serupa.

Ada banyak metrik lain (cakupan garis mirip dengan cakupan pernyataan, tetapi menghasilkan hasil numerik yang berbeda untuk pernyataan multi-baris, misalnya; cakupan bersyarat dan cakupan jalur mirip dengan cakupan cabang, tetapi mencerminkan pandangan yang lebih rinci tentang kemungkinan permutasi eksekusi program yang mungkin Anda temui.)

Berapa persentase yang dibutuhkan

Akhirnya, kembali ke pertanyaan awal: Jika Anda menetapkan standar cakupan kode, seperti apa angka itu?

Mudah-mudahan jelas pada titik ini bahwa kita sedang berbicara tentang perkiraan awal, jadi angka apa pun yang kita pilih akan secara inheren merupakan perkiraan.

Beberapa nomor yang mungkin dipilih:

  • 100% . Anda dapat memilih ini karena Anda ingin memastikan semuanya diuji. Ini tidak memberi Anda wawasan tentang kualitas pengujian, tetapi memberi tahu Anda bahwa beberapa pengujian kualitas telah menyentuh setiap pernyataan (atau cabang, dll.) Sekali lagi, ini kembali ke tingkat kepercayaan: Jika cakupan Anda di bawah 100% , Anda tahu beberapa bagian dari kode Anda tidak diuji.
    • Beberapa mungkin berpendapat bahwa ini konyol, dan Anda hanya boleh menguji bagian-bagian kode Anda yang benar-benar penting. Saya berpendapat bahwa Anda juga harus menjaga bagian-bagian kode Anda yang benar-benar penting. Cakupan kode dapat ditingkatkan dengan menghapus kode yang belum diuji, juga.
  • 99% (atau 95%, angka lain di tahun sembilan puluhan tinggi). Sesuai dalam kasus-kasus di mana Anda ingin menyampaikan tingkat kepercayaan yang sama dengan 100%, tetapi sisakan sedikit pada diri Anda sendiri untuk tidak khawatir tentang sudut sesekali yang sulit untuk diuji dari kode.
  • 80% . Saya telah melihat nomor ini digunakan beberapa kali, dan tidak sepenuhnya tahu dari mana asalnya. Saya pikir itu mungkin merupakan penyalahgunaan aneh aturan 80-20; umumnya, maksud di sini adalah untuk menunjukkan bahwa sebagian besar kode Anda diuji. (Ya, 51% juga akan menjadi "sebagian besar", tetapi 80% lebih mencerminkan apa yang kebanyakan orang maksudkan .) Ini sesuai untuk kasus-kasus jalan tengah di mana "teruji dengan baik" bukan prioritas tinggi (Anda tidak perlu Saya tidak ingin menyia-nyiakan upaya pada tes bernilai rendah), tetapi cukup merupakan prioritas yang Anda masih ingin memiliki beberapa standar.

Saya belum melihat angka di bawah 80% dalam praktik, dan sulit membayangkan kasus di mana orang akan mengaturnya. Peran standar-standar ini adalah untuk meningkatkan kepercayaan terhadap kebenaran, dan angka di bawah 80% tidak terlalu menginspirasi kepercayaan. (Ya, ini subjektif, tapi sekali lagi, idenya adalah membuat pilihan subjektif sekali ketika Anda menetapkan standar, dan kemudian menggunakan pengukuran objektif untuk maju.)

Catatan lain

Di atas mengasumsikan bahwa kebenaran adalah tujuannya. Cakupan kode hanyalah informasi; mungkin relevan dengan tujuan lain. Misalnya, jika Anda khawatir tentang rawatan, Anda mungkin peduli tentang kopling longgar, yang dapat ditunjukkan dengan uji coba, yang pada gilirannya dapat diukur (dalam mode tertentu) dengan cakupan kode. Jadi standar cakupan kode Anda memberikan dasar empiris untuk mendekati kualitas "kemampuan pemeliharaan" juga.

membunuh layar
sumber
Jawaban yang bagus. Bisakah Anda membantu saya menemukan cakupan fungsionalitas melalui pengujian unit? Adakah alat yang dapat membantu saya mencapai ini?
curlyreggie
2
Jawaban yang bagus Ini satu-satunya yang berfokus pada pengujian sebagai masalah tim dalam pengaturan industri. Saya tidak bisa meninjau semuanya dan tim saya sangat cerah, tetapi hijau. Saya menetapkan persentase lantai 90% pada proyek baru sebagai cek kewarasan untuk junior devs, bukan karena saya percaya itu "cukup". "90%" dan "positif, negatif, dan nol" adalah mantra mudah untuk pengembang muda yang cerdas yang saya tahu akan melakukan pekerjaan dengan baik, tetapi tidak memiliki pengalaman untuk terus maju dan menulis bahwa test case tambahan yang mengganggu di pikiran Anda kembali.
0x1mason
2
Saya pikir ini adalah jawaban terbaik yang tersedia.
bugkiller
27

Cakupan kode favorit saya adalah 100% dengan tanda bintang. Tanda bintang datang karena saya lebih suka menggunakan alat yang memungkinkan saya untuk menandai garis tertentu sebagai garis yang "tidak masuk hitungan". Jika saya telah membahas 100% dari baris yang "menghitung", saya sudah selesai.

Proses yang mendasarinya adalah:

  1. Saya menulis tes untuk menjalankan semua fungsi dan kasus tepi yang dapat saya pikirkan (biasanya bekerja dari dokumentasi).
  2. Saya menjalankan alat cakupan kode
  3. Saya memeriksa setiap jalur atau jalur yang tidak tercakup dan yang saya anggap tidak penting atau tidak dapat dijangkau (karena pemrograman defensif) Saya tandai tidak menghitung
  4. Saya menulis tes baru untuk menutupi garis yang hilang dan meningkatkan dokumentasi jika kasus tepi tersebut tidak disebutkan.

Dengan cara ini jika saya dan kolaborator saya menambahkan kode baru atau mengubah tes di masa depan, ada garis terang untuk memberi tahu kami jika kami melewatkan sesuatu yang penting - cakupan turun di bawah 100%. Namun, ini juga memberikan fleksibilitas untuk menangani berbagai prioritas pengujian.

Eponim
sumber
3
@ErikE Asterix, tentu saja, pendekar yang gagah berani dari Gaul yang menciptakan pengecualian untuk pendudukan Romawi yang monoton dan dengan demikian simbol kecil yang menandai pengecualian ditandai dengan namanya. (Lebih serius, terima kasih, saya sudah salah mengeja.)
Eponim
3
Apakah Anda ingin memasukkan "alat yang memungkinkan [Anda] untuk menandai garis tertentu sebagai garis yang tidak masuk hitungan"?
domdambrogia
2
@domdambrogia Sebagai contoh dalam PHP, jika menggunakan pustaka cakupan kode Bergmann, beri anotasi dengan // @codeCoverageIgnoredan akan dikecualikan dari cakupan.
Uskup
19

Saya akan memiliki anectode lain pada cakupan tes yang ingin saya bagikan.

Kami memiliki proyek besar di mana, melalui twitter, saya mencatat bahwa, dengan 700 unit test, kami hanya memiliki cakupan kode 20% .

Scott Hanselman menjawab dengan kata - kata bijak :

Apakah ini BENAR 20%? Apakah itu 20% yang mewakili kode yang paling sering dipukul pengguna Anda? Anda mungkin menambahkan 50 tes lagi dan hanya menambahkan 2%.

Sekali lagi, ini kembali ke Testivus saya pada Kode Cakupan Jawaban. Berapa banyak nasi yang harus Anda masukkan ke dalam panci? Tergantung.

Jon Limjap
sumber
Jelas harus ada akal sehat di sana. Ini tidak banyak digunakan jika 50% dari kode yang Anda uji adalah komentar.
kewarasan
2
Ini lebih di garis ... apakah cakupan Anda dihabiskan untuk fungsionalitas inti aplikasi Anda, atau itu sia-sia menguji fitur sepele / bagus-untuk-dimiliki?
Jon Limjap
sepertinya sebagian besar dari kode Anda adalah boilerplate, atau penanganan perkecualian, atau hal
Erik Aronesty
8

Untuk sistem yang dirancang dengan baik, di mana unit test telah mendorong pengembangan dari awal saya akan mengatakan 85% adalah angka yang cukup rendah. Kelas kecil yang dirancang agar dapat diuji tidak harus sulit untuk ditutup dengan lebih baik dari itu.

Mudah untuk mengabaikan pertanyaan ini dengan sesuatu seperti:

  • Baris yang tercakup tidak sama dengan logika yang diuji dan seseorang tidak boleh membaca terlalu banyak dalam persentase.

Benar, tetapi ada beberapa poin penting yang harus dibuat tentang cakupan kode. Dalam pengalaman saya, metrik ini sebenarnya cukup berguna, jika digunakan dengan benar. Karena itu, saya belum melihat semua sistem dan saya yakin ada banyak dari mereka di mana sulit untuk melihat analisis cakupan kode yang menambahkan nilai nyata. Kode dapat terlihat sangat berbeda dan cakupan kerangka uji yang tersedia dapat bervariasi.

Juga, alasan saya terutama menyangkut loop umpan balik tes yang cukup singkat. Untuk produk yang saya kembangkan loop umpan balik terpendek cukup fleksibel, mencakup semuanya, mulai dari tes kelas hingga pensinyalan antar proses. Menguji sub-produk yang dapat dikirim biasanya membutuhkan waktu 5 menit dan untuk loop umpan balik sesingkat itu memang mungkin untuk menggunakan hasil pengujian (dan khususnya metrik cakupan kode yang kita cari di sini) untuk menolak atau menerima komitmen dalam repositori.

Saat menggunakan metrik cakupan kode, Anda tidak boleh hanya memiliki persentase tetap (sewenang-wenang) yang harus dipenuhi. Melakukan ini tidak memberi Anda manfaat nyata dari analisis cakupan kode menurut pendapat saya. Alih-alih, tentukan metrik berikut:

  • Tanda Air Rendah (LWM), jumlah garis terbukanya yang terendah yang pernah terlihat dalam sistem yang diuji
  • High Water Mark (HWM), persentase cakupan kode tertinggi yang pernah dilihat untuk sistem yang sedang diuji

Kode baru hanya dapat ditambahkan jika kita tidak pergi di atas LWM dan kita tidak pergi di bawah HWM. Dengan kata lain, cakupan kode tidak boleh berkurang , dan kode baru harus dicakup. Perhatikan bagaimana saya katakan harus dan tidak harus (dijelaskan di bawah).

Tapi bukankah ini berarti tidak mungkin untuk membersihkan sampah lama yang sudah teruji dan tidak bisa digunakan lagi? Ya, dan itulah mengapa Anda harus pragmatis tentang hal-hal ini. Ada situasi ketika aturan harus dilanggar, tetapi untuk integrasi sehari-hari Anda, pengalaman saya bahwa metrik ini cukup berguna. Mereka memberikan dua implikasi berikut.

  • Kode yang dapat diuji dipromosikan. Saat menambahkan kode baru, Anda benar-benar harus berusaha membuat kode dapat diuji, karena Anda harus mencoba dan menutup semuanya dengan kotak uji Anda. Kode yang dapat diuji biasanya merupakan hal yang baik.

  • Cakupan tes untuk kode lawas meningkat dari waktu ke waktu. Saat menambahkan kode baru dan tidak dapat menutupinya dengan test case, seseorang dapat mencoba untuk menutupi beberapa kode lawas sebagai ganti aturan LWM. Kecurangan yang kadang-kadang perlu setidaknya memberikan efek samping positif bahwa cakupan kode warisan akan meningkat seiring waktu, membuat penegakan aturan yang tampaknya sangat pragmatis dalam praktiknya.

Dan lagi, jika loop umpan balik terlalu panjang mungkin sama sekali tidak taktis untuk mengatur sesuatu seperti ini dalam proses integrasi.

Saya juga ingin menyebutkan dua manfaat lebih umum dari metrik cakupan kode.

  • Analisis cakupan kode adalah bagian dari analisis kode dinamis (tidak seperti yang statis, yaitu Lint). Masalah yang ditemukan selama analisis kode dinamis (oleh alat seperti keluarga purify, http://www-03.ibm.com/software/products/en/rational-purify-family ) adalah hal-hal seperti pembacaan memori tidak diinisialisasi (UMR), kebocoran memori, dll . Masalah-masalah ini hanya dapat ditemukan jika kode dilindungi oleh test case yang dieksekusi . Kode yang paling sulit untuk dicakup dalam kasus uji biasanya adalah kasus abnormal dalam sistem, tetapi jika Anda ingin sistem gagal dengan anggun (mis. Jejak kesalahan alih-alih crash), Anda mungkin perlu berupaya menutupi kasus-kasus abnormal dalam analisis kode dinamis juga. Dengan sedikit kesialan, UMR dapat menyebabkan segfault atau lebih buruk.

  • Orang-orang bangga menjaga 100% untuk kode baru, dan orang-orang mendiskusikan masalah pengujian dengan hasrat yang sama seperti masalah implementasi lainnya. Bagaimana fungsi ini dapat ditulis dengan cara yang lebih dapat diuji? Bagaimana Anda mencoba menutupi kasus abnormal ini, dll.

Dan negatif, untuk kelengkapan.

  • Dalam sebuah proyek besar dengan banyak pengembang yang terlibat, semua orang pasti tidak akan menjadi seorang jenius pengujian. Beberapa orang cenderung menggunakan metrik cakupan kode sebagai bukti bahwa kode tersebut diuji dan ini sangat jauh dari kebenaran , sebagaimana disebutkan dalam banyak jawaban lain untuk pertanyaan ini. Ini adalah SATU metrik yang dapat memberi Anda beberapa manfaat yang bagus jika digunakan dengan benar, tetapi jika disalahgunakan ternyata dapat menyebabkan pengujian yang buruk. Selain dari efek samping yang sangat berharga yang disebutkan di atas, garis yang tertutup hanya menunjukkan bahwa sistem yang diuji dapat mencapai garis itu untuk beberapa data input dan dapat dijalankan tanpa menggantung atau menabrak.
Martin G
sumber
7

Jika ini adalah dunia yang sempurna, 100% kode akan ditanggung oleh unit test. Namun, karena ini BUKAN dunia yang sempurna, ini soal apa yang Anda punya waktu. Sebagai hasilnya, saya merekomendasikan untuk lebih sedikit fokus pada persentase tertentu, dan lebih fokus pada area kritis. Jika kode Anda ditulis dengan baik (atau setidaknya faksimili yang masuk akal) harus ada beberapa poin kunci di mana API terkena kode lain.

Fokuskan upaya pengujian Anda pada API ini. Pastikan bahwa API 1) didokumentasikan dengan baik dan 2) memiliki kasus uji tertulis yang sesuai dengan dokumentasi. Jika hasil yang diharapkan tidak sesuai dengan dokumen, maka Anda memiliki bug baik dalam kode, dokumentasi, atau kasus uji. Semuanya bagus untuk diperiksa.

Semoga berhasil!

64BitBob
sumber
6

Banyak toko tidak menilai tes, jadi jika Anda di atas nol setidaknya ada beberapa penghargaan - jadi bisa dibilang bukan nol tidak buruk karena banyak yang masih nol.

Di dunia .Net orang sering mengutip 80% sebagai alasan. Tetapi mereka mengatakan ini pada tingkat solusi. Saya lebih suka mengukur di tingkat proyek: 30% mungkin baik untuk proyek UI jika Anda punya Selenium, dll atau tes manual, 20% untuk proyek lapisan data mungkin baik-baik saja, tetapi 95% + mungkin cukup dapat dicapai untuk bisnis lapisan aturan, jika tidak sepenuhnya diperlukan. Jadi cakupan keseluruhan mungkin, katakanlah, 60%, tetapi logika bisnis kritis mungkin jauh lebih tinggi.

Saya juga pernah mendengar ini: bercita-cita untuk 100% dan Anda akan mencapai 80%; tetapi bercita-cita untuk 80% dan Anda akan mencapai 40%.

Intinya: Terapkan aturan 80:20, dan biarkan jumlah bug aplikasi Anda memandu Anda.

Greg Trevellick
sumber
5

Cakupan kode hanyalah metrik lain. Dalam dan dari dirinya sendiri, itu bisa sangat menyesatkan (lihat www.thoughtworks.com/insights/blog/are-test-coverage-metrics-overrated ). Karena itu tujuan Anda seharusnya bukan untuk mencapai cakupan kode 100% melainkan untuk memastikan bahwa Anda menguji semua skenario yang relevan dari aplikasi Anda.

klementtt
sumber
4

85% akan menjadi tempat awal yang baik untuk kriteria checkin.

Saya mungkin akan memilih berbagai bilah yang lebih tinggi untuk kriteria pengiriman - tergantung pada kekritisan dari subsistem / komponen yang diuji.

stephbu
sumber
54
Bagaimana Anda mencapai persentase itu?
sanity
Sebagai catatan kaki - ini bisa berantakan untuk proyek-proyek di mana otomatisasi sulit - seperti selalu pragmatis tentang apa yang dapat dicapai vs yang diinginkan.
stephbu
4
Terutama melalui eksperimen. Sangat mudah untuk mendapatkan cakupan kode hingga 80-90% untuk pengujian unit terkait-Dev - yang semakin tinggi biasanya memerlukan intervensi uji ilahi - atau jalur kode yang sangat sederhana.
stephbu
1
Saya mulai biasanya dengan 1) jalur kode runtime utama 2) kasus pengecualian jelas yang saya lempar secara eksplisit 3) kasus bersyarat yang berakhir dengan "kegagalan" Ini membuat Anda biasanya ke kisaran 70-80 Kemudian wackamole, bug, dan regresi untuk kasus sudut, parameter fuzzing dll. Refactoring untuk memungkinkan injeksi metode dll. Saya biasanya memberikan waktu setidaknya untuk menulis / refactoring yang berhubungan dengan tes dev sebagai kode utama itu sendiri.
stephbu
4

Saya menggunakan cobertura, dan berapa pun persentasenya, saya akan merekomendasikan agar nilai-nilai di tugas cobertura-up-to-date. Paling tidak, teruslah meningkatkan totallinerate dan totalbranchrate tepat di bawah cakupan Anda saat ini, tetapi jangan pernah menurunkan nilai-nilai itu. Juga mengikat properti kegagalan membangun Ant untuk tugas ini. Jika versi gagal karena kurangnya jangkauan, Anda tahu kode tambahan seseorang tetapi belum mengujinya. Contoh:

<cobertura-check linerate="0"
                 branchrate="0"
                 totallinerate="70"
                 totalbranchrate="90"
                 failureproperty="build.failed" />
Gary Kephart
sumber
4

Ketika saya pikir kode saya tidak cukup diuji unit, dan saya tidak yakin apa yang harus diuji selanjutnya, saya menggunakan cakupan untuk membantu saya memutuskan apa yang akan diuji selanjutnya.

Jika saya meningkatkan cakupan dalam tes unit - saya tahu tes unit ini berharga.

Ini berlaku untuk kode yang tidak tercakup, 50% tertutup atau 97% tertutup.

tukang batu
sumber
3
Saya sangat tidak setuju. Unit test hanya bernilai sesuatu jika ada kemungkinan ia akan menemukan bug, (baik bug yang ada sekarang atau bug regresi di masa depan); atau jika itu membantu mendokumentasikan perilaku kelas Anda. Jika suatu metode sangat sederhana sehingga tidak dapat benar-benar gagal, seperti pengambil satu-baris, maka ada nilai nol dalam menyediakan unit test untuknya.
Dawood ibn Kareem
6
Saya memiliki bug dalam satu baris getter. Dari pengalaman saya, tidak ada kode bebas bug. Tidak ada metode yang tidak bisa gagal.
brickner
1
Dengan asumsi pengambil satu baris Anda digunakan oleh kode lain yang Anda liput, dan tes kode itu lolos, maka Anda juga secara tidak langsung telah mencakup pengambil satu baris. Jika Anda tidak menggunakan pengambil, apa yang dilakukannya di kode Anda? Saya setuju dengan David Wallace ... tidak perlu langsung menguji fungsi pembantu sederhana yang digunakan di tempat lain jika kode dan tes yang bergantung pada pembantu tidak menunjukkan mungkin ada masalah dengan itu.
Lowell Montgomery
@ LowowMontgomery dan bagaimana jika tes untuk kode Anda yang lain gagal karena pengambil satu-baris (yang tidak diuji)? Jika ada tes untuk one-liner, akan jauh lebih mudah untuk sampai pada penyebab kegagalan. Ini menjadi sangat buruk ketika Anda memiliki ratusan satu baris yang tidak diuji digunakan di beberapa tempat yang berbeda.
Daniel
Asumsinya adalah tes menggunakan pengambil satu-garis lulus. Jika gagal (mis. Di mana Anda mencoba menggunakan nilai balik dari pengambil satu baris Anda), maka Anda dapat mengatasinya. Tetapi kecuali ada alasan yang sangat mendesak untuk menjadi begitu paranoid, Anda harus menarik garis di suatu tempat. Pengalaman saya adalah bahwa saya perlu memprioritaskan apa yang menyedot waktu dan perhatian saya dan "pengambil" yang sangat sederhana (pekerjaan itu) tidak perlu tes terpisah. Waktu itu dapat dihabiskan untuk membuat tes lain lebih baik atau lebih banyak cakupan kode yang lebih mungkin gagal. (Yaitu saya berdiri dengan posisi asli saya, dengan David Wallace).
Lowell Montgomery
4

Saya lebih suka melakukan BDD, yang menggunakan kombinasi tes penerimaan otomatis, mungkin tes integrasi lainnya, dan tes unit. Pertanyaan bagi saya adalah apa cakupan target dari test suite otomatis secara keseluruhan seharusnya.

Selain itu, jawabannya tergantung pada metodologi Anda, bahasa dan alat pengujian dan cakupan. Ketika melakukan TDD dalam Ruby atau Python tidak sulit untuk mempertahankan cakupan 100%, dan itu layak dilakukan. Jauh lebih mudah untuk mengelola cakupan 100% daripada cakupan 90-sesuatu persen.Artinya, jauh lebih mudah untuk mengisi kesenjangan cakupan seperti yang terlihat (dan ketika melakukan TDD dengan baik kesenjangan cakupan jarang terjadi dan biasanya sepadan dengan waktu Anda) daripada mengelola daftar kesenjangan cakupan yang belum sempat Anda lakukan dan ketinggalan cakupan regresi karena latar belakang konstan Anda dari kode yang terbuka.

Jawabannya juga tergantung pada sejarah proyek Anda. Saya hanya menemukan hal di atas praktis dalam proyek yang dikelola sejak awal. Saya telah sangat meningkatkan cakupan proyek warisan besar, dan itu layak dilakukan, tetapi saya tidak pernah merasa praktis untuk kembali dan mengisi setiap celah cakupan, karena kode lama yang belum diuji tidak cukup dipahami dengan baik untuk melakukannya dengan benar dan segera.

Dave Schweisguth
sumber
3

Jika Anda telah melakukan pengujian unit untuk jumlah waktu yang layak, saya tidak melihat alasan untuk tidak mendekati 95% +. Namun, minimal, saya selalu bekerja dengan 80%, bahkan ketika baru dalam pengujian.

Jumlah ini hanya boleh menyertakan kode yang ditulis dalam proyek (tidak termasuk kerangka kerja, plugin, dll.) Dan bahkan mungkin mengecualikan kelas-kelas tertentu yang seluruhnya terdiri dari kode tertulis panggilan ke kode luar. Panggilan semacam ini harus diejek / di-stub.

Tony Pitale
sumber
3

Secara umum, dari beberapa makalah praktik terbaik keunggulan teknik yang telah saya baca, 80% untuk kode baru dalam unit test adalah poin yang menghasilkan pengembalian terbaik. Pergi di atas bahwa CC% menghasilkan jumlah cacat yang lebih rendah untuk jumlah upaya yang dilakukan. Ini adalah praktik terbaik yang digunakan oleh banyak perusahaan besar.

Sayangnya, sebagian besar hasil ini bersifat internal bagi perusahaan, jadi tidak ada literatur publik yang bisa saya tunjukkan.

pengguna17222
sumber
3

Cakupan kode sangat bagus tetapi hanya selama manfaat yang Anda peroleh dari itu lebih besar daripada biaya / upaya untuk mencapainya.

Kami telah bekerja dengan standar 80% untuk beberapa waktu, namun kami baru saja memutuskan untuk meninggalkan ini dan lebih fokus pada pengujian kami. Berkonsentrasi pada logika bisnis yang kompleks dll,

Keputusan ini diambil karena semakin banyak waktu yang kami habiskan untuk mengejar cakupan kode dan mempertahankan unit test yang ada. Kami merasa kami telah sampai pada titik di mana manfaat yang kami peroleh dari cakupan kode kami dianggap kurang dari upaya yang harus kami lakukan untuk mencapainya.

Simon Keep
sumber
2

Jawaban singkat: 60-80%

Jawaban panjang: Saya pikir itu sepenuhnya tergantung pada sifat proyek Anda. Saya biasanya memulai proyek dengan unit menguji setiap bagian praktis. Dengan "rilis" pertama dari proyek Anda harus memiliki persentase basis yang cukup bagus berdasarkan jenis pemrograman yang Anda lakukan. Pada titik itu Anda dapat mulai "menegakkan" cakupan kode minimum.

pengguna11087
sumber
2

Lihat Crap4j . Ini pendekatan yang sedikit lebih canggih dari pada cakupan kode langsung. Ini menggabungkan pengukuran cakupan kode dengan pengukuran kompleksitas, dan kemudian menunjukkan kepada Anda kode kompleks apa yang saat ini tidak diuji.

Don Kirkby
sumber
2

Jawaban saya atas teka-teki ini adalah memiliki cakupan garis 100% dari kode yang dapat Anda uji dan cakupan garis 0% dari kode yang tidak dapat Anda uji.

Praktik saya saat ini di Python adalah untuk membagi modul .py saya menjadi dua folder: app1 / dan app2 / dan ketika menjalankan tes unit menghitung cakupan dari dua folder dan secara visual memeriksa (saya harus mengotomatisasi ini suatu hari nanti) bahwa app1 memiliki cakupan 100% dan app2 memiliki cakupan 0%.

Ketika / jika saya menemukan bahwa angka-angka ini berbeda dari standar saya menyelidiki dan mengubah desain kode sehingga cakupan sesuai dengan standar.

Ini berarti bahwa saya dapat merekomendasikan mencapai 100% cakupan kode perpustakaan.

Saya juga sesekali meninjau app2 / untuk melihat apakah saya bisa menguji kode apa pun di sana, dan Jika saya bisa saya memindahkannya ke app1 /

Sekarang saya tidak terlalu khawatir tentang cakupan agregat karena itu bisa sangat bervariasi tergantung pada ukuran proyek, tetapi secara umum saya telah melihat 70% hingga lebih dari 90%.

Dengan python, saya harus bisa membuat tes asap yang secara otomatis dapat menjalankan aplikasi saya sambil mengukur cakupan dan mudah-mudahan mendapatkan sekitar 100% ketika menggabungkan tes asap dengan angka-angka yang belum diputuskan.

quamrana
sumber
2

Melihat cakupan dari perspektif lain: Kode yang ditulis dengan baik dengan aliran kontrol yang jelas adalah yang paling mudah untuk dibahas, yang paling mudah dibaca, dan biasanya kode yang paling tidak bermasalah. Dengan menulis kode dengan jelas dan mudah diingat, dan dengan menulis unit test secara paralel dengan kode, Anda mendapatkan hasil terbaik IMHO.


sumber
2

Menurut pendapat saya, jawabannya adalah "Itu tergantung pada berapa banyak waktu yang Anda miliki". Saya mencoba untuk mencapai 100% tetapi saya tidak membuat keributan jika saya tidak mendapatkannya dengan waktu yang saya miliki.

Ketika saya menulis tes unit, saya memakai topi yang berbeda dibandingkan dengan topi yang saya kenakan saat mengembangkan kode produksi. Saya berpikir tentang apa yang diklaim oleh kode yang diuji untuk dilakukan dan situasi apa yang mungkin dapat memecahkannya.

Saya biasanya mengikuti kriteria atau aturan berikut:

  1. Bahwa Tes Unit harus berupa dokumentasi tentang apa perilaku yang diharapkan dari kode saya, yaitu. output yang diharapkan memberikan input tertentu dan pengecualian yang mungkin dilontarkan klien yang ingin ditangkap (Apa yang harus diketahui pengguna kode saya?)

  2. Bahwa Tes Unit harus membantu saya menemukan bagaimana jika kondisi yang mungkin belum saya pikirkan. (Bagaimana cara membuat kode saya stabil dan kuat?)

Jika kedua aturan ini tidak menghasilkan cakupan 100%, maka jadilah itu. Tapi begitu, saya punya waktu, saya menganalisis blok dan garis yang belum ditemukan dan menentukan apakah masih ada kasus uji tanpa unit test atau jika kode perlu direaktor ulang untuk menghilangkan kode yang tidak perlu.

Mark Menchavez
sumber
1

Itu sangat tergantung pada aplikasi Anda. Sebagai contoh, beberapa aplikasi sebagian besar terdiri dari kode GUI yang tidak dapat diuji unit.

Thomas
sumber
5
Anda mungkin harus menggunakan Model View Presenter untuk UI Anda jika Anda berada di lingkungan TDD.
Charles Graham
1

Saya tidak berpikir akan ada aturan B / W.
Kode harus ditinjau, dengan perhatian khusus pada detail kritis.
Namun, jika belum diuji, ia memiliki bug!

Nescio
sumber
Tidak ingin aturan, hanya umpan balik tentang pengalaman pribadi tentang korelasi antara persentase cakupan kode dan efektivitas unit test.
kewarasan
1

Tergantung pada kekritisan kode, di mana saja dari 75% -85% adalah aturan praktis yang baik. Kode pengiriman pasti harus diuji lebih teliti daripada di utilitas rumah, dll.

William Keller
sumber
1

Ini harus bergantung pada fase siklus hidup pengembangan aplikasi Anda.

Jika Anda sudah dalam pengembangan untuk sementara waktu dan sudah memiliki banyak kode yang diterapkan dan sekarang baru menyadari bahwa Anda perlu memikirkan tentang cakupan kode maka Anda harus memeriksa cakupan Anda saat ini (jika ada) dan kemudian menggunakan baseline tersebut untuk menetapkan tonggak setiap sprint (atau kenaikan rata-rata selama periode sprint), yang berarti mengambil utang kode sambil terus memberikan nilai pengguna akhir (setidaknya dalam pengalaman saya pengguna akhir tidak peduli sedikit pun jika Anda telah meningkatkan tes cakupan jika mereka tidak melihat fitur baru).

Bergantung pada domain Anda, menembak dengan 95% tidak masuk akal, tetapi saya harus mengatakan secara rata-rata bahwa Anda akan melihat kasus rata-rata 85% hingga 90%.

codeLes
sumber
1

Saya pikir gejala terbaik dari cakupan kode yang benar adalah bahwa jumlah masalah nyata yang dapat diperbaiki dengan unit test sesuai dengan ukuran kode unit test yang Anda buat.

dimarzionis
sumber
1

Saya pikir yang paling penting adalah mengetahui tren liputan dari waktu ke waktu dan memahami alasan perubahan tren. Apakah Anda melihat perubahan tren baik atau buruk akan tergantung pada analisis Anda tentang alasannya.

Rob Scott
sumber
0

Kami menargetkan> 80% hingga beberapa hari yang lalu, Tapi setelah kami menggunakan banyak kode Generated, Kami tidak peduli untuk% usia, melainkan meminta penelepon untuk melakukan panggilan pada cakupan yang diperlukan.

reva
sumber
0

Dari posting Testivus saya pikir konteks jawaban harus menjadi programmer kedua. Setelah mengatakan ini dari sudut pandang praktis, kami membutuhkan parameter / tujuan untuk diperjuangkan. Saya menganggap bahwa ini dapat "diuji" dalam proses Agile dengan menganalisis kode yang kita miliki arsitektur, fungsionalitas (cerita pengguna), dan kemudian muncul dengan angka. Berdasarkan pengalaman saya di bidang Telekomunikasi saya akan mengatakan bahwa 60% adalah nilai yang baik untuk diperiksa.

D Lovece
sumber