"Teori pengujian perangkat lunak" Googling tampaknya hanya memberikan teori dalam arti kata yang lembut; Saya belum dapat menemukan apa pun yang akan diklasifikasikan sebagai teori dalam matematika, informasi teoretis atau pengertian bidang ilmiah lainnya.
Apa yang saya cari adalah sesuatu yang memformalkan pengujian itu, pengertian yang digunakan, apa itu ujian, kelayakan menguji sesuatu, kepraktisan menguji sesuatu, sejauh mana sesuatu harus diuji, definisi formal / penjelasan tentang cakupan kode, dll.
UPDATE: Juga, saya tidak yakin, secara intuitif, tentang hubungan antara verifikasi formal dan apa yang saya minta, tetapi jelas ada semacam koneksi.
testing
math
theory
formal-methods
information-theory
Erik Kaplun
sumber
sumber
double pihole(double value) { return (value - Math.PI) / (value - Math.PI); }
yang saya pelajari dari guru matematika saya . Kode ini memiliki satu lubang , yang tidak dapat ditemukan secara otomatis hanya dari pengujian kotak hitam. Dalam Matematika tidak ada lubang seperti itu. Dalam kalkulus Anda diizinkan menutup lubang jika batas satu sisi sama.(a,b)=>a/b
, yang perlu diperluas dengan nilai melimpah, agar dapat dikomposasikan dengan benar.Jawaban:
Untuk buku yang mengeksplorasi matematika di balik pengujian perangkat lunak ... buku mani yang didapat adalah Seni Analisis Kinerja Sistem Komputer: Teknik untuk Desain, Pengukuran, Simulasi, dan Pemodelan Eksperimental
Meskipun pertama kali diterbitkan pada tahun 1991 masih populer sampai sekarang karena ini adalah buku matematika terapan yang berfokus hanya pada analisis kinerja, simulasi, dan pengukuran.
sumber
Saya tidak dapat menunjuk ke sumber daring yang bagus (artikel Wikipedia bahasa Inggris tentang topik ini cenderung tidak dapat diperbaiki), tetapi saya dapat merangkum ceramah yang saya dengar yang juga membahas teori pengujian dasar.
Mode pengujian
Ada beberapa kelas tes, seperti tes unit atau tes integrasi . Tes unit menyatakan bahwa sepotong kode yang koheren (fungsi, kelas, modul) diambil sesuai dengan fungsinya sendiri, sedangkan tes integrasi menyatakan bahwa beberapa bagian tersebut bekerja dengan benar bersama-sama.
Sebuah test case adalah lingkungan yang dikenal di mana sepotong kode dieksekusi, misalnya dengan menggunakan input tes khusus, atau dengan mengejek kelas lain. Perilaku kode kemudian dibandingkan dengan perilaku yang diharapkan, misalnya nilai pengembalian spesifik.
Sebuah tes hanya dapat membuktikan adanya bug, tidak pernah tidak adanya semua bug. Tes menempatkan batas atas kebenaran program.
Cakupan Kode
Untuk menentukan metrik cakupan kode, kode sumber dapat diterjemahkan ke grafik aliran kontrol di mana setiap node berisi segmen linier dari kode. Kontrol mengalir antara node-node ini hanya di akhir setiap blok, dan selalu bersyarat (jika kondisinya, maka goto node A, kalau tidak goto node B). Grafik memiliki satu simpul mulai dan satu simpul ujung.
Oleh karena itu seringkali berguna untuk memeriksa cakupan kondisi .
true
danfalse
. Ini menyiratkan cakupan cabang penuh, tetapi agak mahal. Program mungkin memiliki kendala tambahan yang mengecualikan kombinasi tertentu. Teknik ini baik untuk mendapatkan cakupan cabang, dapat menemukan kode mati, tetapi tidak dapat menemukan bug yang berasal dari kondisi yang salah .Saat membuat input uji menggunakan cakupan kondisi, maka hubungan arus pendek harus diperhitungkan. Sebagai contoh,
kebutuhan untuk diuji dengan
foo(false, whatever)
,foo(true, false)
, danfoo(true, true)
untuk cakupan kondisi beberapa minim penuh.Jika Anda memiliki objek yang dapat berada dalam beberapa status, maka pengujian semua transisi status yang dianalogikan untuk mengontrol aliran tampaknya masuk akal.
Ada beberapa metrik cakupan yang lebih kompleks, tetapi umumnya mirip dengan metrik yang disajikan di sini.
Ini adalah metode pengujian kotak putih , dan sebagian dapat diotomatisasi. Perhatikan bahwa rangkaian uji unit harus bertujuan untuk memiliki cakupan kode tinggi dengan metrik apa pun yang dipilih, tetapi 100% tidak selalu mungkin. Terutama sulit untuk menguji penanganan pengecualian, di mana kesalahan harus disuntikkan ke lokasi tertentu.
Tes fungsional
Lalu ada tes fungsional yang menyatakan bahwa kode mematuhi spesifikasi dengan melihat implementasi sebagai kotak hitam. Tes semacam itu berguna untuk pengujian unit dan pengujian integrasi. Karena tidak mungkin untuk menguji dengan semua data input yang mungkin (misalnya menguji panjang string dengan semua string yang mungkin), maka berguna untuk mengelompokkan input (dan output) ke dalam kelas yang setara - jika
length("foo")
benar,foo("bar")
kemungkinan akan bekerja juga. Untuk setiap kemungkinan kombinasi antara input dan output kelas kesetaraan, setidaknya satu input representatif dipilih dan diuji.Satu juga harus menguji
length("")
,foo("x")
,length(longer_than_INT_MAX)
,length(null)
, danlength("null byte in \x00 the middle")
...Dengan angka, ini berarti pengujian
0, ±1, ±x, MAX, MIN, ±∞, NaN
, dan dengan perbandingan titik mengambang menguji dua pelampung yang berdekatan. Sebagai tambahan lain, nilai tes acak dapat diambil dari kelas ekivalensi. Untuk memudahkan debugging, ada baiknya merekam seed yang digunakan ...Tes non-fungsional: Load test, Stress test
Sepotong perangkat lunak memiliki persyaratan non-fungsional, yang harus diuji juga. Ini termasuk pengujian pada batas yang ditentukan (tes beban), dan di luar batas itu (tes stres). Untuk gim komputer, ini bisa berarti jumlah minimum frame per detik dalam uji beban. Sebuah situs web mungkin diuji stres untuk mengamati waktu respons ketika pengunjung dua kali lebih banyak dari yang diperkirakan menghancurkan server. Tes semacam itu tidak hanya relevan untuk seluruh sistem tetapi juga untuk entitas tunggal - bagaimana tabel hash terdegradasi dengan sejuta entri?
Jenis pengujian lainnya adalah pengujian sistem keseluruhan di mana skenario disimulasikan, atau tes penerimaan untuk membuktikan bahwa kontrak pengembangan telah dipenuhi.
Metode non-pengujian
Ulasan
Ada teknik non-pengujian yang dapat digunakan untuk jaminan kualitas. Contohnya adalah penelusuran, tinjauan kode formal, atau pemrograman pasangan. Sementara beberapa bagian dapat diotomatisasi (misalnya dengan menggunakan linter), ini umumnya memakan waktu. Namun, tinjauan kode oleh programmer berpengalaman memiliki tingkat penemuan bug yang tinggi, dan sangat berharga selama desain, di mana tidak ada pengujian otomatis yang memungkinkan.
Ketika ulasan kode sangat bagus, mengapa kita masih menulis tes? Keuntungan besar dari test suites adalah mereka dapat berjalan (kebanyakan) secara otomatis, dan sangat berguna untuk tes regresi .
Verifikasi formal
Verifikasi formal berjalan dan membuktikan sifat-sifat tertentu dari kode. Verifikasi manual sebagian besar layak untuk bagian-bagian penting, kurang untuk seluruh program. Bukti menempatkan batas bawah pada kebenaran program. Bukti dapat diotomatisasi ke tingkat tertentu, misalnya melalui pemeriksa tipe statis.
Invarian tertentu dapat secara eksplisit diperiksa dengan menggunakan
assert
pernyataan.Semua teknik ini memiliki tempat masing-masing, dan saling melengkapi. TDD menulis tes fungsional di depan, tetapi tes dapat dinilai dengan metrik cakupan setelah kode diterapkan.
Menulis kode yang dapat diuji berarti menulis unit kode kecil yang dapat diuji secara terpisah (fungsi pembantu dengan rincian yang sesuai, prinsip tanggung jawab tunggal). Semakin sedikit argumen yang dilakukan masing-masing fungsi, semakin baik. Kode tersebut juga cocok untuk penyisipan objek tiruan, misalnya melalui injeksi ketergantungan.
sumber
Mungkin "pengujian berbasis spesifikasi" juga menjawab pertanyaan Anda. Periksa Modul Pengujian ini (yang belum saya gunakan). Mereka mengharuskan Anda untuk menulis ekspresi matematika untuk menentukan set nilai tes, daripada menulis tes unit menggunakan nilai data tunggal yang dipilih.
Tes :: Lectrotest
Seperti yang dikatakan penulis, Modul Perl ini terinspirasi oleh Modul Pemeriksaan Cepat Haskell . Ada lebih banyak tautan di halaman ini, beberapa di antaranya sudah mati.
sumber
Salah satu pendekatan berbasis matematis adalah pengujian semua pasangan . Idenya adalah bahwa sebagian besar bug diaktifkan oleh pilihan opsi konfigurasi tunggal, dan sebagian besar sisanya diaktifkan oleh sepasang opsi tertentu yang diambil secara bersamaan. Dengan demikian sebagian besar dapat ditangkap dengan menguji "semua pasangan". Penjelasan matematis (dengan generalisasi) ada di sini:
Sistem AETG: pendekatan untuk pengujian berdasarkan pada desain kombinatorial
(ada lebih banyak referensi seperti itu)
sumber
Ada beberapa persamaan matematika yang digunakan, tetapi itu tergantung pada jenis pengujian perangkat lunak yang Anda gunakan. Sebagai contoh, Critical Fault Assumption mengasumsikan bahwa kegagalan bukanlah hasil dari 2 atau lebih kesalahan simultan. Persamaan berikut adalah: f = 4n + 1. f = fungsi yang menghitung jumlah kasus uji untuk sejumlah variabel tertentu ( n) + 1 adalah penambahan konstanta di mana semua variabel mengasumsikan nilai nominal.
Tipe lain dari pengujian yang membutuhkan persamaan matematika adalah Robustness Testing adalah pengujian ketahanan, atau kebenaran kasus uji dalam proses pengujian. Dalam tes ini, Anda akan memasukkan variabel dalam rentang input yang sah (kasus uji bersih) dan variabel input di luar rentang input (kasus uji kotor). Anda akan menggunakan persamaan matematika berikut: f = 6n +1 . 6n menunjukkan bahwa masing-masing variabel harus mengasumsikan 6 nilai yang berbeda sedangkan nilai lainnya mengasumsikan nilai nominal. * + 1 * mewakili penambahan konstanta 1.
sumber