Bu sayfadaki yazılar
Sayfanın metni
Sayfa 67
Denklik Sınıfları
Bir programa giren girdiler, eğer sürekli bir kümeden gelmiyorsa, sınırlardan bahsetmek mümkün olmayabilir. Örneğin haftanın günlerinden biri girdilerden birini oluşturuyor ise, ve program hafta sonu için farklı hafta içi için farklı davranacağını söylüyorsa sınırlar nedir. Cuma olduğunu düşünebilirsiniz. Belki... Ama bu tip durumlar (ve sürekli kümeler için de) sınır koşullarına bakmak dışında bir perspektif daha vardır. Girdinin alabileceği değerler kümesini "denklik sınıfları"na bölmek.
Denklik sınıfları, adından da tahmin edebileceğiniz gibi bir girdinin alabileceği bütün değerleri speklere göre sınıflara ayırır. Aynı sınıfa ait üyelerin aynı şekilde işlem göreceği ve bir denklik sınıfından sadece bir (veya birkaç) değerin testte kullanılması öngörülür. Bu şekilde tıpkı sınır koşullarını kullandığımız zamanki gibi test birimi sayısını azaltabiliriz.
Kod Kapsama
ve Şeffaf kutu testleri
Az önce programa ve testlerimizin programın hatalarını ne kadar yakaladığına dair güvenimizi nasıl ölçebileceğimizi sorgulamıştık. Bu kaygıyı birebir cevaplamamakla beraber, bazı sayısal metrikler mevcuttur ve sayısal metrikler her zaman "içimden bir ses böyle söylüyor"dan daha iyidir.
Fakat ne zaman ki kod kapsamadan bahsediyoruz, o zaman kapalı kutudan bahsetmiyoruz demektir. Çünkü birazdan göreceğiniz gibi, kod kapsama tekniklerinden faydalanmak, yazılan kodun içini bilmeyi ve bu bilgiden faydalanmayı gerektirir. Bu bilgiyi kullanarak yapılan testlere de "Şeffaf Kutu Testleri" denir.
Aşağıdaki fonksiyona bir bakın:
int Topla( int Sayil, int Sayi2)
if ((Sayil>-0)&&(Sayil<100))1 if((Sayi2>-0) &&(Sayi2<100))( Jelsel //Sayi 2 istenilen aralikta degil returmn -İ; ) )Jelsel // Sayi 1 istenilen aralikta degil return -l
Bu fonksiyonu test ederken ne zaman emin oluruz. İşte kod kapsama kavramı burada devreye girer. Kod kapsama, yazılan bir kodun içindeki değişik birimlerden hangilerinin testler esnasında sınandığını ve ne kadarının sınanmadan geçtiğini ifade eder. Değişik kod kapsama türleri vardır. Şimdi bunlardan bir kaçına değinelim.
Kod
satırlarını veya kod dallarını kapsamak
Bu örneğimizi bir adet test birimi ile test ettiğimiz zaman hangi satırların çalıştığına bakabiliriz. Koşullu ifadelerden (yani if-else) dolayı bir test birimi bu fonksiyondaki her satıra uğramayacaktır.
Bir grup test birimini çalıştırdıktan sonra fonksiyonda uğranan satırların sayısını daha da artırmış oluruz. Böylece iyi seçilmiş test birimleri ile her hangi bir programın sahip olduğu kod satırlarının büyük bölümünün "kapsanmasını" sağlayabiliriz. Ve diyebiliriz ki bu programımızı testlerimizle 485 satır kapsaması sağlayarak test ettik. Bu ölçülebilir bir metriktir. Örneğin koda eklemeler yaptıkça kapsama yüzdeniz azalacaktır. Bir proje ekibi kapsama yüzdesi örneğin %30'un altına düşen bir yazılımı çıkarmayı reddedebilir. Çünkü kodun %70'inin test edilmediği ve orada kritik buglar olabileceğini düşünebilirler.
Bazen de koddaki satırların kapsamasını incelemek yerine koddaki dalların (blokların) kapsamasını inceleyebiliriz. Bunu takip etmek kimi projelerde daha mantıklı olabilir. Fakat temelde aynı mantıktır.
Son olarak Kapsama değerlerini ölçen programlar vardır. Yani kapsama değerlerini siz elle ölçmezsiniz. Bunun için favori derleyicinizin kod kapsama (code coverage) özelliklerini araştırın
Koşul ifadelerini kapsamak
Daha önce en çok hata yapılan yerlerin koşullar olduğundan bahsetmiştik. Eğer karmaşık koşul ifadeleri yazılırsa, dikkat etmemiz gereken bir nokta daha var. Şu örneğe bir bakın. Eğer elimizde şöyle bir if satırı olsaydı: if ( ( Sayı > 0 )
&& ( Sayi2 < 99 ) )
Bu if satırından dolayı kod iki farklı yere atlayabilir. Ya bir alt satıra ya da else bölümüne. Diyelim ki Sayı1 ve Sayı2 için sırasıyla -1, 99 değerlerini verdik. Bu durumda aradaki && işleminin yarattığı bir problem var. Bu operatör kendisinden önceki ilk koşula (Sayı1 >= 0) bakıp onun yanlış olduğunu gördüğü anda else bölümüne atlar. Yani ikinci koşulu test etmez. Bu yüzden biz ikinci koşulda yaptığımız hatayı fark etmeyebiliriz.
Bu yüzden kimi projeler metrik olarak "Koşul Kapsaması"nı da kullanırlar. Test birimlerinin hangi koşul ifadelerine uğradığını takip ederler. Kod satırı kapsamadan farklı olarak genelde koşul kapsama metrikleri kullanıldıkları yerlerde koşul kapsaması aranır.
Durum Motorlarını kapsamak
Bir diğer şeffaf kutu yaklaşımı da durum motorlarını test ederken karşımıza çıkar. Bir yazılım eğer çeşitli durumlara ve durumlar arası tanımlı geçişlere sahip bir durum motoru olarak tasarlanmış ise, bu durumda test birimlerimizin hangi durumları ve hangi geçişleri kapsadığından bahsedebiliriz. Durum motorlarını test ederken ayrıca komutların gönderiliş sıraları da karıştırılarak durum motorunun tepkisi test edilir. Bu konuyu bu yazıda daha detaylı incelemeyeceğiz.
Hata Enjeksiyonu
Klavyeyle gezinmek için ← ve → tuşları.
Sayfa 66
Yazılım Doğrulama Birimleri: Test Birimleri
Buraya kadar anlattığımız bütün test türlerinde genellikle testler küçük veri gruplarından oluşur. Bir seferde programa verilecek veriler ve programın vermesini beklediğimiz cevap bir "Test Birimi"ni oluşturur.
Örneğin elinizde toplama yapan bir program var. Bu programa iki sayı veriyorsunuz ve o da toplamını döndürüyor. Bu programa 3 ve 5 verip cevap olarak 8 beklemek bir test birimidir.
İyi test birimleri tasarlamak çok önemli bir yetidir. Her programın veya kütüphanenin test birim tasarımı farklı olacaktır. Fakat test birimleri tasarlarken dikkat edilecek bazı ortak noktalar var. Bunlara değinelim.
Kapalı
kutu test tasarımı
Kapalı kutu test tasarımı yaparken bildiğiniz (veya bildiğinizi varsaydığınız) tek şey test ettiğiniz yazılımın spekidir. Spekin parçası olarak programla nasıl etkileşileceği (yani arayüz) açıklanmıştır. Mesela daha önce değindiğimiz toplama örneğini ele alalım.
Toplama yazılımı: Bu yazılım iki adet iki basamaklı pozitif sayıyı girdi olarak alır, bu sayıların toplamını çıktı olarak döndürür. Eğer hatalı bir girdi verilirse sonuç -1 olarak döndürülür.
Bu örnekte bahsettiğimiz yazılım bir GUI programı da olabilir, bir konsol programı da, ya da bir API'nin parçası olan bir fonksiyon da olabilir. Biz burada bunu önemsemiyoruz. Yani girdileri, GUI veya konsola mı veriyoruz, yoksa bir fonksiyona argüman olarak mı geçiriyoruz, buna şimdi dikkat etmeyeceğiz. Biz daha çok test birimini belirlemeye çalışacağız. Yani bu yazılımı hangi sayı çiftleri ile test edeceğimizi tartışacağız.
Sınır Koşulları
Bir programa verilen olası girdi değerlerinin tümünü deneyebilseydik programla ilgili kendimizi çok güvende hissedebilirdik. Fakat bu genellikle imkansızdır. Bu yüzden bir Test Birimi tasarlarken mutlaka girdilerin alabileceği hangi değerlerin kritik olduğuna ve olası hataları ortaya çıkarabileceğine bakarız.
Genel olarak programlar kabul ettikleri girdiler ile ilgili bazı sınırlar belirtirler. Bu sınırların dışında kalan değerlerin kabul edilmediğini veya bir sınırın üstünde ve altında değerler için farklı işlemler yapıldığını belirtebilirler.
Genellikle pek çok hata bu sınırlar ve onların hemen yakınında olur. Mesela örnek programımızda verilen sayıların iki basamaklı pozitif sayılar olması bekleniyor. Programın içinde sayının üst sınırının kontrol edildiğini düşünelim. Bu kontrolü yapan kod şöyle bir şey olabilir.
1f (
( Verilen Sayi < 99 )
veya belki de şöyledir:
( Verilen Sayi >- 100 )
ya da böyle:
( Verilen Sayı < 100 )
Dikkat ederseniz buradaki karşılaştırma koşulu bir olası hata noktası. Verdiğimiz ilk iki kod hatalı. İlki geçerli bir girdi olan 99 değerini reddedecek. İkincisi ise geçersiz bir girdi olan 100 değerini kabul edecek.
Böyle problemlere çok sık rastlandığı için genelde sınır değerleri yakınında ve üzerinde değerler içeren test birimleri hazırlamak mantıklıdır. Örneğin;
. . 0,5 . 1,5 . 98,5 . 99,5 100,5 . 12,-1 . 12,0 . 12,1 . 12,98 . 12,99 12,100
Bu 12 test birimi ile sınır koşullarını her iki girdi için de test etmiş oluyoruz. Eğer bütün olasılıkları test edecek olsaydık 100 x 100 toplam 10000 test birimi hazırlamak gerekirdi. Burada sadece 12 test birimi ile 10000 birimlik testimize çok yakın bir güven elde edebiliriz (Bu güveni nasıl nümerik olarak ölçebiliriz birazdan göreceğiz)