Bu Sayfayı Paylaş:

Bilgi/Açıklama

Test

JUnit, Java'da birim sınama (unit test) yazılması ve çalıştırılmasını sağlayan açık kaynak kodlu bir framework'tür. Bu bölümde JUnit kullanarak yazılan kodların nasıl test edileceği anlatılacaktır.
Bir fonksiyonun test amacıyla yazıldığı belirtmek için @Test (Sına) annotation'ı kullanılır.
Aşağıdaki gibi bir sınıf olsun:
public class SimpleTest {
    public int topla(int a, int b){
        return a+b;
    }
}
Kod sadece verilen iki sayıyı toplamaktadır. Burada topla() yönteminin doğru çalıştığını test etmek için aşağıdaki gibi bir test sınıfı yazılabilir:
import org.junit.*;
import static org.junit.Assert.*;
public class Tester {
  @Test
  public void testTopla(){
    SimpleTest simple=new SimpleTest();
    int c=simple.topla(1,2);
    assertEquals(3, c);
 }
}
@Test annotation'ı bir fonksiyonun test kodu içerdiğini belirtir. Bir çok geliştirme ortamında bu ifadeyi doğrudan çalıştırmanızı sağlayacak bir takım destekler bulunmaktadır.
Test fonksiyonu testTopla() içinde SimpleTest sınıfının nesnesi yaratılıp, 1 ve 2 sayısı toplanmakta ve c'ye atanmaktadır. Buradaki c değerinin 3 olmasını bekliyoruz aksi takdirde hata var demektir. JUnit'de koşulları test etmek için assert (savla) ile başlayan çok sayıda fonksiyon bulunur. Biz değerin 3 olmasını kontrol etmek istediğimizden assertEquals() (eşitliği savla) fonksiyonunu kullandık.
JUnit'de bir değerin veya nesnenin, beklendiği gibi olup olmadığını test amacıyla kullanılan , assert ile başlayan en önemli yöntemler ve ne işe yaradıkları aşağıdaki gibidir:
  • assertEquals() (eşitliği savla) : Değer ile beklenen değerin eşitliğini kontrol eder. Eşit ise test başarılıdır
  • assertNotEquals() (eşitsizliği savla) : Değer ile beklenen değerin eşit olmamasını kontrol eder. Eşit değilse test başarılıdır
  • assertNull() (yokluğu savla) : Bir nesnenin null olmasını kontrol eder. Null ise test başarılıdır.
  • assertNotNull() (yoksuzluğu savla) : Bir nesnenin null olmamasını kontrol eder. Değer null değilse test başarılıdır.
  • assertTrue() (doğruluğu savla) : Değerini true olmasını kontrol eder. Değer true ise test başarılıdır
  • assertFalse() (yanlışlığı savla) : Değerini false olmasını kontrol eder. Değer false ise test başarılıdır
  • assertSame() (aynılığı savla) : İki nesnenin aynı olup olmadığını (aynı nesneye refrans vermesi) kontrol eder. İki nesne aynı ise test başarılıdır
  • assertNotSame() (aynısızlığı savla) : İki nesnenin aynı olup olmadığını (aynı nesneye refrans vermesi) kontrol eder. İki nesne aynı değil ise test başarılıdır
  • assertThat() (savla ki) : Macther ile belirtilen koşula uyup uyulmadığını kontrol eder. Hamcrest kütüphanesi desteklenmektedir
  • assertArrayEquals() (dizi eşitliğini savla) : İki dizinin eşitliğini kontrol eder. Eşit ise test başarılıdır.
JUnit , Hamcrest adı verilen bir kütüphane ile matching (eşleme) desteklemektedir. Kullanılabilecek bazı önemli fonksiyonlar aşağıdaki gibidir:
  • is() (budur) : Örneğin assertThat(d, is(1.3)) , d değerinin 1.3 olmasını test eder
  • not() (değil) : Örneğin assertThat(d, is(not(1.3))), d değerinin 1.3 olmaması durumunu test eder
  • equalTo() (buna eşit) : assertThat(str, equalTo("test")), str'in "test" ifadesine eşit olmasını test eder
  • anyOf() (bunlardan herhangi biri) : assertThat(str, anyOf(is("A"), is("B"), is("C"))) , str ifadesinin A veya B veya C olup olmadığını test eder. Eğer str A,B veya C ise test başarılıdır
  • allOf() (bunların hepsi) : assertThat(list, allOf(hasItem("A"), hasItem("B"))), list'de hem A hem de B var ise test başarılıdır
  • any() (herhangi bir) : assertThat(obj, is(any(String.class))) , obj nesnesi bir String ise test başarılıdır
  • instanceOf() (bunun örneği): assertThat(obj, is( instanceOf( String.class))), obj nesnesi bir String ise test başarılıdır
  • nullValue() (yok değerde) : assertThat(obj, is(nullValue())), obj nesnesi null ise test başarılıdır
  • notNullValue() (yok değerde değil) : assertThat(obj, is(notNullValue())); obj nesnesi null değilse test başarılıdır
  • sameInstance() (aynı örnek): assertThat(obj, is(sameInstance(other))) , obj ile other aynı instance ise test başarılıdır
  • containsString() (sicimi içerir) : assertThat(obj, containsString("Ali")), obj içinde Ali geçiyor ise test başarılıdır
  • startsWith() (bununla başlar) : assertThat( obj, startsWith("my")), obj my ile başlıyorsa test başarılıdır
  • endsWith() (bunula biter) : assertThat(obj, endsWith("Ali")), obj String ve Ali ile bitiyor ise test başarılıdır
  • hasItem() (bu maddesi var) : assertThat( list, hasItem("two")) , bir liste içinde "two" olan bir String maddesi var mı test eder
  • hasItems() (bu maddeleri var) : assertThat(list, hasItems("one", "two")), bir liste içinde one veya two varsa test başarılıdır
Test için kullanılan önemli annotation'lar aşağıdaki gibi listelenebilir :
  • @Before (Önce) : Bir test sınıfında, birden fazla test yönteminin ihtiyaç duyacağı değer ve nesneleri, testler çalışmadan önce yaratmak için kullanılan annotation.
  • @After (Sonra) : Bir test sınıfında, birden fazla test yönteminin çalışmasından sonra ortak bazı kodların çalışması için kullanılan annotation. Örneğin bazı kaynakların serbest bırakılması vb.. bu yöntem ile yapılır.
  • @BeforeClass (Sınıftan Önce) : Bir test sınıfındaki test yöntemleri çalıştırılmaya başlamadan önce yapılması gereken işlerin yapıldığı yöntemi tanımlamak için kullanılan annotation.
  • @AfterClass (Sınıftan Sonra) : Bir test sınıfındaki test yöntemlerinin hepsinin tamamlanmasından sonra yapılması gereken işlerin yapıldığı yöntemi tanımlamak için kullanılan annotation.
  • @Ignore (Yok Say) : Bir test methodunu çalıştırılmaması için kullanılan annotation. Bir test bloğunu silmek veya yorum yapmak yerine başına @Ignore eklemek yeterli olur.
Aşağıda Before ve After annotation'larını kullanalım. Aşağıdaki gibi bir sınıfınız olsun:
public class SimpleTest {
    public int topla(int a, int b){
        return a+b;
    }
    public int carp(int a, int b){
        return a*b;
    }
}
Bu sınıf içindeki topla() ve carp() yöntemlerini test eden sınıf aşağıdaki gibi yazılabilir:
import org.junit.*;
import static org.junit.Assert.*;
public class Tester {   
  SimpleTest simple=null; 
  @Before
  public void setUp(){
    simple=new SimpleTest();
  }   
  @After
  public void tearDown(){
    simple=null;
  }
  @Test
  public void testTopla(){
    int c=simple.topla(1,2);
    assertEquals(3, c);
  }
  @Test
  public void testCarp(){
        int c=simple.carp(1,2);
        assertEquals(2, c);
    }   
}
Yukarıdaki örnekte, SimpleTest nesnesi setUp() içinde yapılmaktadır. Bu şekilde her test öncesi nesne yaratılır ve test sonrası nesne null haline getirilir.
Bazı testler, exception oluşup oluşmadığını test etmek amacıyla yapılabilir. Örneğin pozitif bir int değeri alması gereken bir fonksiyonda, negatif bir sayı verildiğinde IllegalArgumentException (Yasadışı Argüman Kuraldışılığı) fırlatması gerekiyor ise, test negatif bir sayı ile çağırarak yapılabilir.
@Test(expected = IllegalArgumentException.class)
public void negatifTest(){
    Simple.isle(3,-1);
}
Simple sınıfındaki isle methodu , IllegalArgumentException fırlatmalıdır. Eğer IllegalArgumentException oluşmaz ise test başarısız olmuştur.
Bir JUnit sınıfında , sıralama için @FixMethodOrder (Yöntem Sırasını Onar) kullanılabilir:
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ExternalSubscriptionManageTest {
    @Test
    public void test2(){..}
    @Test
    public void test3(){..}
    @Test
    public void test1(){..}
}

Yukarıdaki örnekte yöntem isimlerine göre test yöntemleri sırayla çağrılmaktadır. NAME_ASCENDING (Ad Yükselen) değeri adların küçükten büyüye doğru sıralanmasını sağlar. Önce test1 , sonra test2 ve en son test3 çalıştırılacaktır.
Test yöntemleri ve sınıfları kategorilere ayrılabilir. @Category annotation'u @Category(X.class) biçiminde kullanıalrak bir test methodunun X.class kategorisine ait olduğu belirtilmiş olur.
Testin nasıl yapılacağını bildiren @RunWith (İle Sına) annotation'u @RunWith( Categories.class) biçiminde kullanılırsa test işlemi kategorilere göre yapılır. @IncludeCategory (Kategoriyi İçer) annotation'u @IncludeCategory( X.class) biçiminde kullanılırsa sadece X kategorisindeki testlerin çalışması sağlanabilir. Benzer şekilde @ExcludeCategory (Kategoriy Dışar) annotation'u @ExcludeCategory( X.class) biçiminde kullanılırsa X hariç diğer kategoriler için testin çalışması sağlanabilir.

Bilgi/Açıklama

Test Suite

JUnit'de birden fazla test sınıfından oluşan test grubuna Suit (Takım) adı verilir. @RunWith (İle Çalıştır) ve @SuiteClasses (Takım Sınıfları) annotation'ları birlikte kullanılmakadır.
Aşağıda basit bir test suite sınıfı örneği görülmektedir :
import org.junit.runner.*;
import org.junit.runners.*; 
@RunWith(Suite.class)
@Suite.SuiteClasses({
  Test1.class,
  Test2.class,
  Test3.class,
  Test4.class
})
public class SimpleTestSuite {
  // bu sınıfın dolu olmasına gerek yoktur
}
Test suite 4 test sınıfından oluşmaktadır ve test suite çalıştırıldığında testler sırasıyla çalıştırılacaktır.
Aşağıdaki gibi iki Java sınıfı bulunmaktadır:
public class Toplar {
    public int topla(int a, int b){
        return a+b;
    }       
}
public class Carpar {
    public int carp(int a, int b){
        return a*b;
    }   
}
Yukarıdaki iki sınıf için ayrı aşağıdaki gibi iki test sınıfı yapılmıştır:
import static org.junit.Assert.*;
import org.junit.*;
public class ToplaTest {
    Toplar simple;  
    @Before
    public void setUp(){
        simple=new Toplar();
    }   
    @Test
    public void testTopla(){
        int c=simple.topla(1,2);
        assertEquals(3, c);
    }
}
İkinci test sınıfı:
import static org.junit.Assert.*;
import org.junit.*;
public class CarpTest {
    Carpar simple;
    @Before
    public void setUp(){
        simple=new Carpar();
    }   
    @Test
    public void testCarp(){
        int c=simple.carp(1,2);
        assertEquals(2, c);
    }   
}
Yukarıdaki iki testi aynı anda çalıştırabilmek için aşağıdaki gibi bir suite yaratılabilir:
import org.junit.runner.*;
import org.junit.runners.*; 
@RunWith(Suite.class)
@Suite.SuiteClasses({
  ToplaTest.class,
  CarpTest.class
})
public class IslemSuit {
}

Yukarıdaki suit, ToplaTest ve CarpTest sınıflarını içermektedir. IslemSuit çalıştırılırsa önce ToplaTest , ardından da CarpTest sınıfları çalışacaktır.



Bu Sayfayı Paylaş:

İletişim/Bize Yazın   mh@fibiler.com   Google+   Facebook   Twitter   fibiler@googlegroups.com
Her Hakkı Saklıdır
Bu sitede yayınlanan tüm bilgi ve fikirlerin kullanımından fibiler.com sorumlu değildir.
Bu sitede üretilmiş , derlenmiş içerikleri, fibiler.com'u kaynak göstermek koşuluyla kendi sitenizde kullanılabilirsiniz. Ancak telif hakkı olan içeriklerin hakları sahiplerine aittir