Apakah cakupan tes merupakan ukuran kualitas kode yang memadai?

20

Jika saya memiliki beberapa kode yang memiliki cakupan tes 80% (semua tes lulus), apakah adil untuk mengatakan bahwa kualitasnya lebih tinggi daripada kode tanpa cakupan tes?

Atau apakah adil untuk mengatakan itu lebih bisa dipertahankan?

David_001
sumber
2
Cakupan 100% tidak berarti telah diuji dengan baik. Tapi 0% berarti belum diuji sama sekali.
mouviciel
1
Secara teknis tidak. Secara praktis, ya. Pengalaman telah mengajarkan banyak insinyur perangkat lunak dan penguji bahwa ketika cakupan kode mencapai sekitar 80%, jenis cacat yang pengujian unitnya memadai mulai turun. Itu prinsip pareto. Pada dasarnya begitu Anda sampai pada titik di mana Anda mencakup 80% dari kode, terlepas dari kualitas tes Anda, Anda mungkin menguji 20% dari kode yang menyebabkan sebagian besar masalah potensial cukup menyeluruh. Ini bukan mutlak, tetapi lebih merupakan kebijaksanaan konvensional. Anda harus lebih teliti jika nyawa bergantung pada pengujian Anda.
Calphool
@ JoRounceville Saya tidak yakin ... Saya bisa mencapai cakupan pengujian tinggi sambil menguji tidak ada yang benar-benar berguna. Cakupan hanya memberi tahu Anda berapa banyak kode yang disentuh oleh test suite, bukan apakah tes tersebut bermakna.
Andres F.
1
@AndresF. Itu sebabnya saya berkata "secara teknis tidak, praktis ya". Orang bukan idiot (umumnya). Mereka (umumnya) tidak menguji hanya kasus yang tidak masuk akal. Jadi, berdasarkan pengalaman , banyak toko berhenti di sekitar cakupan 80%, membuat asumsi (cukup aman) bahwa orang-orang mereka bukan orang bodoh.
Calphool

Jawaban:

24

Dalam arti yang ketat, tidak adil untuk mengajukan klaim apa pun sampai kualitas suite uji ditetapkan. Melewati 100% dari tes tidak berarti jika sebagian besar tes itu sepele atau berulang satu sama lain.

Pertanyaannya adalah: Dalam sejarah proyek, apakah ada dari tes itu yang menemukan bug? Tujuan dari tes ini adalah untuk menemukan bug. Dan jika tidak, mereka gagal sebagai tes. Alih-alih meningkatkan kualitas kode, mereka mungkin hanya memberi Anda rasa aman palsu.

Untuk meningkatkan desain pengujian Anda, Anda dapat menggunakan (1) teknik papan tulis, (2) teknik kotak hitam, dan (3) pengujian mutasi.

(1) Berikut adalah beberapa teknik papan tulis yang bagus untuk diterapkan pada desain pengujian Anda. Tes papan tulis dibangun dengan kode sumber tertentu dalam pikiran. Salah satu aspek penting dari pengujian papan tulis adalah cakupan kode:

  • Apakah setiap fungsi dipanggil? [Cakupan fungsional]
  • Apakah setiap pernyataan dieksekusi? [Cakupan pernyataan - Cakupan fungsional dan cakupan pernyataan sangat mendasar, tetapi lebih baik daripada tidak sama sekali]
  • Untuk setiap keputusan (suka ifatau tidak while), apakah Anda memiliki ujian yang memaksanya untuk menjadi benar, dan yang lain memaksa itu menjadi salah? [Cakupan keputusan]
  • Untuk setiap kondisi yang merupakan konjungsi (kegunaan &&) atau disjungsi (kegunaan ||), apakah setiap subekspresi memiliki tes di mana itu benar / salah? [Cakupan kondisi]
  • Cakupan loop: Apakah Anda memiliki tes yang memaksa 0 iterasi, 1 iterasi, 2 iterasi?
  • Apakah masing-masing breakdari loop tertutup?

(2) Teknik Blackbox digunakan ketika persyaratan tersedia, tetapi kode itu sendiri tidak. Ini dapat menyebabkan tes berkualitas tinggi:

  • Apakah tes kotak hitam Anda mencakup beberapa tujuan pengujian? Anda ingin tes Anda menjadi "gemuk": Mereka tidak hanya menguji fitur X, tetapi mereka juga menguji Y dan Z. Interaksi berbagai fitur adalah cara terbaik untuk menemukan bug.
  • Satu-satunya kasus Anda tidak ingin tes "gemuk" adalah ketika Anda menguji kondisi kesalahan. Misalnya, menguji input pengguna yang tidak valid. Jika Anda mencoba mencapai beberapa tujuan pengujian input yang tidak valid (misalnya, kode pos yang tidak valid dan alamat jalan yang tidak valid), kemungkinan satu kasus menutupi yang lainnya.
  • Pertimbangkan jenis input dan bentuk "kelas ekivalensi" untuk jenis input. Misalnya, jika kode Anda menguji apakah segitiga sama sisi, tes yang menggunakan segitiga dengan sisi (1, 1, 1) mungkin akan menemukan jenis kesalahan yang sama dengan data pengujian (2, 2, 2) dan (3, 3, 3) akan ditemukan. Lebih baik menghabiskan waktu Anda memikirkan kelas input lain. Misalnya, jika program Anda menangani pajak, Anda ingin tes untuk setiap braket pajak. [Ini disebut partisi ekivalensi.]
  • Kasus khusus sering dikaitkan dengan cacat. Data pengujian Anda juga harus memiliki nilai batas, seperti yang ada di, di atas, atau di bawah tepi tugas kesetaraan. Misalnya, dalam menguji algoritme pengurutan, Anda akan ingin menguji dengan array kosong, array elemen tunggal, array dengan dua elemen, dan kemudian array yang sangat besar. Anda harus mempertimbangkan kasus batas tidak hanya untuk input, tetapi juga untuk output. [Ini disebut analisis nilai batas.]
  • Teknik lain adalah "Menebak kesalahan." Apakah Anda memiliki perasaan jika Anda mencoba kombinasi khusus yang dapat membuat program Anda rusak? Maka coba saja! Ingat: Tujuan Anda adalah untuk menemukan bug, bukan untuk mengkonfirmasi bahwa program tersebut valid . Beberapa orang memiliki kemampuan untuk menebak kesalahan.

(3) Akhirnya, anggaplah Anda sudah memiliki banyak tes bagus untuk cakupan papan tulis, dan teknik blackbox yang diterapkan. Apa lagi yang bisa kamu lakukan? Saatnya Menguji Tes Anda . Salah satu teknik yang bisa Anda gunakan adalah Mutation Testing.

Di bawah pengujian mutasi, Anda membuat modifikasi untuk (salinan) program Anda, dengan harapan membuat bug. Mutasi mungkin:

Ubah referensi dari satu variabel ke variabel lain; Masukkan fungsi abs (); Ubah kurang dari menjadi lebih besar dari; Hapus sebuah pernyataan; Ganti variabel dengan konstanta; Hapus metode pengesampingan; Hapus referensi ke metode super; Ubah urutan argumen

Buat beberapa lusin mutan, di berbagai tempat di program Anda [program masih perlu dikompilasi untuk menguji]. Jika tes Anda tidak menemukan bug ini, maka Anda sekarang harus menulis tes yang dapat menemukan bug di versi program Anda yang telah dimutasi. Setelah tes menemukan bug, Anda telah membunuh mutan dan dapat mencoba yang lain.


Tambahan : Saya lupa menyebutkan efek ini: Bug cenderung mengelompok . Artinya adalah semakin banyak bug yang Anda temukan dalam satu modul, semakin tinggi kemungkinan Anda akan menemukan lebih banyak bug. Jadi, jika Anda memiliki tes yang gagal (artinya, tes berhasil, karena tujuannya adalah untuk menemukan bug), Anda tidak hanya harus memperbaiki bug, tetapi Anda juga harus menulis lebih banyak tes untuk modul, menggunakan teknik di atas.

Selama Anda menemukan bug pada tingkat yang stabil, upaya pengujian harus dilanjutkan. Hanya ketika ada penurunan dalam tingkat bug baru yang ditemukan, Anda harus yakin bahwa Anda telah melakukan upaya pengujian yang baik untuk fase pengembangan tersebut.

Macneil
sumber
7

Menurut satu definisi itu lebih dapat dipertahankan, karena setiap perubahan yang melanggar lebih mungkin ditangkap oleh tes.

Namun, fakta bahwa kode lulus tes unit tidak berarti secara intrinsik berkualitas lebih tinggi. Kode mungkin masih diformat dengan buruk dengan komentar yang tidak relevan dan struktur data yang tidak sesuai, tetapi masih bisa lulus tes.

Saya tahu kode mana yang saya inginkan untuk dipertahankan dan diperluas.

ChrisF
sumber
7

Kode yang sama sekali tidak ada tes bisa sangat berkualitas tinggi, dapat dibaca, indah dan efisien (atau total sampah), jadi tidak, tidak adil untuk mengatakan bahwa kode dengan cakupan tes 80% lebih berkualitas daripada kode tanpa cakupan tes.

Bisa adil untuk mengatakan bahwa kode 80% tertutup dengan tes yang baik mungkin kualitasnya dapat diterima, dan mungkin relatif dapat dipertahankan. Tapi itu menjamin sedikit, sungguh.

Joonas Pulakka
sumber
3

Saya akan menyebutnya lebih refactorable. Refactoring menjadi sangat mudah jika kode ditutupi dengan banyak tes.

Akan lebih adil untuk menyebutnya lebih bisa dipertahankan.

Josip Medved
sumber
2

Saya setuju tentang bagian yang bisa dipelihara. Michael Feathers baru-baru ini memposting sebuah video pembicaraan luar biasa tentang panggilannya " Sinergi yang mendalam antara testabilitas dan desain yang baik " di mana ia membahas topik ini. Dalam pembicaraan dia mengatakan bahwa hubungan itu satu arah, yaitu, kode yang dirancang dengan baik dapat diuji, tetapi kode yang dapat diuji belum tentu dirancang dengan baik.

Perlu dicatat bahwa streaming video tidak bagus dalam video, jadi mungkin layak mengunduh jika Anda ingin menonton secara penuh.

Paddyslacker
sumber
-2

Saya telah bertanya pada diri sendiri pertanyaan ini untuk beberapa waktu sekarang sehubungan dengan "cakupan kondisi". Jadi bagaimana dengan halaman ini dari atollic.com "Mengapa analisis cakupan kode?"

Secara lebih teknis, analisis cakupan kode menemukan area dalam program Anda yang tidak dicakup oleh kasus pengujian Anda, memungkinkan Anda untuk membuat tes tambahan yang mencakup bagian-bagian lain dari program Anda yang belum diuji. Karena itu penting untuk memahami bahwa cakupan kode membantu Anda memahami kualitas prosedur pengujian Anda, bukan kualitas kode itu sendiri .

Ini sepertinya cukup relevan di sini. Jika Anda memiliki set kasus uji yang berhasil mencapai tingkat cakupan tertentu (kode atau lainnya), maka Anda kemungkinan besar menggunakan kode yang sedang diuji dengan set nilai input yang cukup lengkap! Ini tidak akan memberi tahu Anda banyak tentang kode yang sedang diuji (kecuali jika kode tersebut meledak atau menghasilkan kesalahan yang dapat terdeteksi) tetapi memberi Anda kepercayaan diri dalam set case uji Anda .

Dalam perubahan tampilan Necker Cube yang menarik , kode uji sekarang sedang diuji oleh kode yang sedang diuji!

David Tonhofer
sumber
-3

Ada banyak cara untuk menjamin bahwa program melakukan apa yang Anda inginkan, dan untuk memastikan bahwa modifikasi tidak akan membawa efek yang tidak diinginkan.

Pengujian adalah satu. Menghindari mutasi data adalah hal lain. Begitu juga sistem tipe. Atau verifikasi formal.

Jadi, sementara saya setuju bahwa pengujian pada umumnya adalah hal yang baik, persentase pengujian yang diberikan mungkin tidak banyak berarti. Saya lebih suka mengandalkan sesuatu yang ditulis dalam Haskell tanpa tes daripada pada perpustakaan PHP yang teruji dengan baik

Andrea
sumber
Apakah ini hanya pendapat Anda atau Anda dapat mendukungnya?
nyamuk
2
Menguji bukanlah cara untuk menjamin suatu program melakukan apa yang Anda inginkan.
Andres F.
1
Lalu saya bertanya-tanya apa itu pengujian
Andrea
@gnat ini tentu saja pendapat saya. Tetap saja, ia mengatakan apa yang dikatakan. Saya mengambil Haskell sebagai contoh bahasa yang kompilernya sangat ketat dan memberikan banyak jaminan tentang pembentukan input yang baik, jenis, efek samping, mutasi data. Saya mengambil PHP sebagai contoh bahasa yang interpreternya sangat lunak dan bahkan tidak memiliki spesifikasi. Bahkan dengan tidak adanya pengujian, keberadaan semua jaminan dari jenis dan efek sistem biasanya menghasilkan tingkat keandalan yang layak. Untuk mengimbangi itu dengan tes, orang perlu memiliki suite yang sangat komprehensif
Andrea
Saya mungkin sedikit tergesa-gesa ketika menulis - saya sedang menelepon - tetapi saya masih berpikir ada benarnya. Saya tidak ingin bash di PHP, tapi saya pikir mengatakan bahwa dalam perbandingan Haskell memberikan tingkat keandalan yang jauh lebih besar adalah pernyataan objektif
Andrea