Anda di halaman 1dari 7

Bab 21

Mengevaluasi Kasus Uji


Siapa yang mengawasi para pengamat?
Juvenal (Satir VI, baris 347–8)
kira-kira akhir abad ke-1 Masehi
Sama seperti Juvenal satiris Romawi bertanya siapa yang akan menjaga para penjaga,
tidak peduli seberapa hati-hati serangkaian tes dikembangkan, software testers should ask how
good are their test cases.Edsger Dykstra mengamati bahwa pengujian dapat mendeteksi adanya
kesalahan tetapi tidak pernah dapat menyatakan ketidakhadirannya.
21.1 Pengujian Mutasi
Sebuah cerita tetap ada, sekarang dianggap sebagai legenda urban, tentang kesalahan
program luar angkasa awal dalam program FORTRAN di mana titik digunakan sebagai pengganti
koma (1976 M). Pernyataan itu (seharusnya) pernyataan seperti
DO 20 I = 0,100,2
yang masuk sebagai DO 20, I = 0,100.2, yang seharusnya mendefinisikan penghentian
Do-loop pada pernyataan nomor 20 di mana indeks loop, I , bervariasi dari 0 hingga 100 dalam
langkah 2. Versi lain menghilangkan bagian yang kosong, membuat pernyataan penugasan
DO20I = 100.2
Dengan kesalahan ketik, loop menggunakan kenaikan default 1. Seharusnya, kesalahan
ini menyebabkan penyelidikan Mariner I ke Venus gagal. Kesalahan semacam ini bisa ditangkap
dengan pengujian mutasi.
Istilah mutan dipinjam dari biologi, di mana ia mengacu pada variasi kecil dari organisme
asli. Pengujian mutasi dimulai dengan satu unit dan satu set kasus uji untuk unit itu, sehingga
semua kasus uji lulus saat dieksekusi. Kemudian perubahan kecil dilakukan pada unit asli, dan
kasus uji dijalankan pada mutan. Jika semua kasus uji lulus, kita tahu bahwa mutan itu tidak
terdeteksi.
Pada titik ini ada dua kemungkinan — baik perubahan kecil menghasilkan program yang
setara secara logis, atau set kasus uji tidak mampu mendeteksi perubahan.
21.1.1 Memformalkan Mutasi Program
P′ mutan dari program P adalah hasil dari perubahan kode sumber dari program asli P.
Pengujian mutasi menggunakan perubahan kecil, biasanya hanya satu, pada kode sumber P.
Pengujian mutasi dimulai ketika ada satu set T kasus uji P sedemikian rupa sehingga, untuk
setiap kasus uji t T, uji lolos; khususnya, output yang diharapkan dari P yang mengeksekusi t
cocok dengan output yang diamati. Inti dari pengujian mutasi adalah untuk melihat apakah
himpunan T mendeteksi perubahan kecil pada setiap mutan.
Diberikan sebuah program P, sebuah P′ mutan, satu set kasus uji T sedemikian rupa
sehingga setiap t T lolos untuk P, P′ mutan terbunuh jika setidaknya satu kasus uji t T gagal.
Mutan hidup adalah bagian tersulit dari mutasi. Hanya ada dua kemungkinan — apakah P′
mutan hidup secara logis setara dengan P, atau kasus uji di T tidak cukup untuk
mengungkapkan perbedaannya. Mengapa ini menjadi masalah? Menentukan apakah P dan P′
ekivalen secara logis secara formal tidak dapat diputuskan. Pada titik ini, teori pengujian mutasi
mengembangkan kuantitas pedoman yang melibatkan rasio jumlah mutan yang terbunuh
dengan jumlah total mutan (yang mencakup jumlah mutan setara yang tidak dapat ditentukan).
Misalkan sebuah program P, dan satu set M dari mutasi P, dan satu set kasus uji T
menghasilkan x mutan yang terbunuh dari y total mutan dalam M. Kemudian, rasio x/y adalah
skor mutasi P terhadap M.
Nilai skor mutasi yang lebih tinggi meningkatkan kepercayaan pada utilitas set tes asli T.
Pada titik ini, jelas bahwa ada sejumlah besar komputasi yang terkait dengan mutasi. Sampai
baru-baru ini, ukuran komputasi menurunkan pengujian mutasi ke status keingintahuan
akademis. Pada penulisan ini, ada beberapa alat yang tersedia; kebanyakan freeware.
21.1.2 Operator Mutasi
Ammann dan Offut (2008) adalah dua peneliti mutasi jangka panjang. Dalam buku mereka,
mereka mengembangkan 11 kategori operator mutasi (Hmmm ... mungkinkah ini "mutation
overkill"? Maaf, Saya tidak bisa menahan permainan kata.) Untuk mendapatkan rasa dari
penggantian ini, mutasi yang paling umum adalah hasil dari penggantian elemen sintaksis
dengan anggota lain dari himpunan yang sama. Misalnya, himpunan operator aritmatika, A,
adalah himpunan
A = {+, –, *, /, %}.
(Kita bisa menambahkan eksponensial dan primitif lainnya jika kita mau.) Demikian pula,
himpunan operator relasional, R, adalah himpunan
R = {<, <=, ==, ≠, >, >=}
Himpunan pengganti umum ketiga, L, berhubungan dengan penghubung logis yang kita temui
di Bab 3:
L = {∧, ∨, ⊕, ∼, →}
. Jika suatu program menggunakan fungsi trigonometri, semuanya dapat digantikan oleh fungsi
trigonometri lainnya; sama untuk fungsi statistik. . Tiga subbagian berikutnya menggunakan alat
pengujian mutasi online (PIT) gratis untuk menganalisis tiga contoh yang telah kami kerjakan
sebelumnya, isLeap (dari NextDate), isTriangle (dari program Triangle), dan versi masalah
komisi. Penguji mutasi dapat membiarkan imajinasi mereka menjadi liar dengan "ledakan
mutasi". Ingat kembali fungsi Boolean isLeap dari contoh sebelumnya.
Fungsi Publik adalahLeap(tahun) Sebagai Boolean
Tahun redup Sebagai Integer
Redupkan c1, c2, c3 Sebagai Boolean
1. c1 = (tahun% 4 == 0)
2. c2 = (tahun% 100 == 0)
3. c3 = (tahun% 400 == 0)
4. isLeap = Salah
5. Jika ((c1 DAN TIDAK(c2)) ATAU (c3)) Maka
6. IsLeap = Benar
7. Lain
8. IsLeap = Salah
9. EndIf
"Ledakan mutasi" hanya diisyaratkan di sini. Dalam mutasi penuh, ada empat mutasi dari
operasi % dalam pernyataan 1, ditambah dengan lima penggantian penghubung ==. Karena
mutasi dibuat secara tunggal, akan ada sembilan mutasi pada pernyataan 1, demikian pula
masing-masing sembilan untuk pernyataan 2 dan 3. Kondisi majemuk dalam pernyataan 5 berisi
tiga penghubung logis, dan masing-masing dapat digantikan oleh empat penghubung lainnya.
Kemudian kita dapat menambahkan sedikit perubahan pada konstanta: kita dapat mengganti 4
sembarang {–4, 3, 0, 5} dan 100 sembarang {101, 0, 99, –100}. Secara keseluruhan, kita dapat
membayangkan lusinan mutan dari isLeap dasar.
21.1.2.1 adalah Pengujian Mutasi Leap
Di sini isLeap dikodekan sebagai metode Java, isLeapYear, dan perlengkapan pengujian kelas,
TestisLeap. Rekan dan teman saya, Dr. Christian Trefftz, mengembangkan dan menjalankan
contoh di bagian ini.

public class IsLeap


{
public static boolean isLeapYear(int value)
{
return (value % 4 == 0 && value % 100 != 0)||value % 400 == 0;
}
}

import org.junit.Test;
import static org.junit.Assert.*;

public class TestIsLeap


{
@Test
public void testIsLeapYear()
{
assertTrue(IsLeap.isLeapYear(2012));
assertTrue(IsLeap.isLeapYear(2000));
assertTrue(!IsLeap.isLeapYear(2013));
assertTrue(!IsLeap.isLeapYear(1900));
}
}
PIT adalah program mutasi freeware yang terintegrasi dengan baik dengan Java. Berikut hasil
yang dilaporkan oleh PIT versi 0.29:
1. Mengganti modulus integer dengan perkalian: KILLED -> TestIsLeap.testIsLeapYear(Test
IsLeap)
2. Mengganti modulus integer dengan perkalian: KILLED -> TestIsLeap.testIsLeapYear(Test
IsLeap)
3. Mengganti pengembalian nilai ukuran integer dengan (x == 0 ? 1 : 0): KILLED ->
TestIsLeap.test IsLeapYear(TestIsLeap)
4. Negasi bersyarat: KILLED -> TestIsLeap.testIsLeapYear(TestIsLeap)
5. Negasi bersyarat: KILLED -> TestIsLeap.testIsLeapYear(TestIsLeap)
6. Negasi bersyarat: KILLED -> TestIsLeap.testIsLeapYear(TestIsLeap)
7. Mengganti modulus integer dengan perkalian: KILLED -> TestIsLeap.testIsLeapYear(Test
IsLeap)
PIT melakukan mutasi yang dipilih dengan memeriksa kode sumber dan memilih kemungkinan
mekanisme penggantian mutator. Dalam contoh ini, mutator berikut digunakan oleh PIT:
 INCREMENTS_MUTATOR
 CONDITIONALS_BOUNDARY_MUTATOR
 RETURN_VALS_MUTATOR
 VOID_METHOD_CALL_MUTATOR
 INVERT_NEGS_MUTATOR
 MATH_MUTATOR
 NEGATE_CONDITIONALS_MUTATOR

21.1.2.2 adalah Pengujian Mutasi Segitiga

public class IsTriangle


{
public static boolean isATriangle(int a, int b, int c)
{
return ((a < (b + c)) && (b < (a + c)) && (c < (a + b)));
}
}

import org.junit.Test;
import static org.junit.Assert.*;

public class TestIsTriangle


{
@Test
public void testIsTriangle()
{
assertTrue(IsTriangle.isATriangle (3,4,5)); assertTrue(!
IsTriangle.isATriangle (5,2,3)); assertTrue(!IsTriangle.isATriangle (6,2,3));
assertTrue(!IsTriangle.isATriangle (2,5,3)); assertTrue(!
IsTriangle.isATriangle (2,6,3)); assertTrue(!IsTriangle.isATriangle (3,2,5));
assertTrue(!IsTriangle.isATriangle (3,2,6));
}
}
Kutipan dari laporan PIT

1. Negasi bersyarat: KILLED ->TestIsTriangle.testIsTriangle(TestIsTriangle)


2. Batas bersyarat yang diubah: KILLED -> TestIsTriangle.testIsTriangle(TestIsTriangle)
3. Negasi bersyarat: KILLED ->TestIsTriangle.testIsTriangle(TestIsTriangle)
4. Negasi bersyarat: KILLED ->TestIsTriangle.testIsTriangle(TestIsTriangle)
5. Penambahan bilangan bulat diganti dengan pengurangan: KILLED ->
TestIsTriangle.testIsTriangle(Test IsTriangle)
6. Mengganti pengembalian nilai berukuran integer dengan (x == 0 ? 1 : 0): KILLED ->
TestIsTriangle. testIsTriangle(TestIsTriangle)
7. Penambahan bilangan bulat diganti dengan pengurangan: KILLED ->
TestIsTriangle.testIsTriangle(Test IsTriangle)
8. Batas bersyarat yang diubah: KILLED -> TestIsTriangle.testIsTriangle(TestIsTriangle)
9. Penambahan bilangan bulat diganti dengan pengurangan: KILLED ->
TestIsTriangle.testIsTriangle(Test IsTriangle)
10. Batas bersyarat yang diubah: KILLED -> TestIsTriangle.testIsTriangle(TestIsTriangle)

Mutator aktif
 INCREMENTS_MUTATOR
 CONDITIONALS_BOUNDARY_MUTATOR
 RETURN_VALS_MUTATOR
 VOID_METHOD_CALL_MUTATOR
 INVERT_NEGS_MUTATOR
 MATH_MUTATOR
 NEGATE_CONDITIONALS_MUTATOR

Tes diperiksa
 TestIsTriangle.testIsTriangle(TestIsTriangle) (92 mdtk)
21.1.2.3 Pengujian Mutasi Komisi
Contoh ini lebih menarik. Dalam laporan PIT, kami melihat bahwa dua mutan (11 dan 17)
selamat. Sayangnya, tidak ada informasi lebih lanjut tentang mutasi yang masih hidup.
Lari ini akan memberikan skor mutasi 19/21, atau 0,905. Dua contoh sebelumnya memiliki nilai
mutasi sempurna (1,0).

public class SalesCommission


{
public static int calcSalesCommission (int locks, int stocks, int barrels)
{
int sales,commision;
sales = 45*locks + 30*stocks + 25*barrels;
if (sales <= 1000)
commission = sales*0.10;
if ((sales > 1000) && (sales <= 1800))
commission = 100 + (sales – 1000)*0.15;
if ((sales > 1800)
commission = 100 + 800*0.15 + (sales – 1800)*0.20;

return commission;
}
}
import org.junit.Test;
import static org.junit.Assert.*;

public class TestSalesCommission


{
@Test
public void testCommission()
{
assertEquals(SalesCommission.calcSalesCommission (1,1,1), 10);
assertEquals(SalesCommission.calcSalesCommission (8,8,8), 80);
assertEquals(SalesCommission.calcSalesCommission (10,10,10), 100);
assertEquals(SalesCommission.calcSalesCommission (11,11,11), 115);
assertEquals(SalesCommission.calcSalesCommission (17,17,17), 205);
assertEquals(SalesCommission.calcSalesCommission (18,18,18), 220);
assertEquals(SalesCommission.calcSalesCommission (19,19,19), 240);
assertEquals(SalesCommission.calcSalesCommission (10,0,0), 45);
assertEquals(SalesCommission.calcSalesCommission (0,10,0), 30);
assertEquals(SalesCommission.calcSalesCommission (0,0,10), 25);
}
}
Mutator aktif
 INCREMENTS_MUTATOR
 CONDITIONALS_BOUNDARY_MUTATOR
 RETURN_VALS_MUTATOR
 VOID_METHOD_CALL_MUTATOR
 INVERT_NEGS_MUTATOR
 MATH_MUTATOR
 NEGATE_CONDITIONALS_MUTATOR

Tes diperiksa
 TestSalesCommission.testCommission(TestSalesCommission) (112 ms)

21.2 Kabur (Fuzzing)


Fuzzing adalah keingintahuan akademis yang dimulai di University of Wisconsin (Miller
et al., 1989). Dalam bentuk novel roman sejati, laporan mani mencatat bahwa, "pada malam
yang gelap dan penuh badai ..." ide itu tidak sengaja ditemukan. Barton Miller dan dua
mahasiswa pascasarjana, Lars Fredriksen dan Bryan So, menggunakan koneksi Internet dial-up
selama badai. Kebisingan elektronik pada saluran menghasilkan string karakter yang kacau yang
menyebabkan kegagalan pada beberapa utilitas UNIX. Ini menggelitik rasa ingin tahu mereka,
dan berkembang menjadi studi yang berlarut-larut. Studi mereka memeriksa 88 utilitas yang
berjalan pada tujuh versi UNIX, dan kesalahan yang menyertainya diungkapkan oleh string
karakter acak.
Sejak itu, ide fuzzing telah diperluas ke beberapa sistem operasi. "Fuzzers" adalah
program yang menyajikan string karakter acak sebagai input ke baris perintah dan aplikasi
interaktif. String acak merupakan keuntungan karena dapat mengungkapkan situasi yang tidak
akan pernah terpikirkan oleh penguji. Kelemahannya adalah bahwa bagian keluaran yang
diharapkan dari kasus uji tidak dapat ditentukan. Ini tidak terlalu menjadi masalah karena
biasanya respons terhadap input yang salah adalah pesan kesalahan.
21.3 Jumlah Fishing Creel dan Penyisipan Kesalahan
Kantor pengelolaan ikan dan satwa liar di negara-negara bagian dengan program penangkapan
ikan yang kuat menggunakan metode berdasarkan "jumlah creel" untuk menilai keberhasilan
kebijakan penebaran ikan. Sebagai contoh, Sungai Rogue dekat Rockford, Michigan, adalah
sungai trout yang ditunjuk. Setiap tahun, ditebar dengan ikan pembenihan. Sirip adiposa (dekat
ekor) dihilangkan, dan selama musim, pemancing diminta untuk berpartisipasi dalam
penghitungan creel di mana mereka secara sukarela melaporkan hasil tangkapannya.
Berdasarkan data ini, manajemen sungai dapat membuat perkiraan populasi relatif dari alam
liar (dengan sirip adiposa) dan tempat penetasan ikan trout. Misalkan, contoh, Sungai Rogue
dipenuhi dengan 1000 ikan trout bertanda, dan bahwa selama musim penangkapan ikan, total
laporan creel adalah 500 ikan yang ditangkap, 300 di antaranya adalah ikan trout tempat
penetasan. Tim pengelola sungai akan menyimpulkan bahwa 60% ikan trout di Sungai Rogue
adalah ikan pembenihan (ditanam). Total populasi juga dapat diperkirakan; dalam hal ini, 500
ikan yang ditangkap mewakili 30% dari total populasi. Pendekatan estimasi ini mengasumsikan
bahwa tempat penetasan dan ikan liar dicampur dengan cara yang seragam.

Anda mungkin juga menyukai