Unit Test nedir? Junit Kullanımı ? Birim Testi neden yazmalıyız?
Javada test yazılırken en çok kullanılan kütüphanelerden birisi jUnit kütüphanesidir. Bizler için test yazmak önemlidir , tüm methodların testlerini biribirinden bağımsız şekilde yazabiliriz. Bu şekilde kodumuz daha ürün olmamışken sınanmış ve hata payını en aza indirgemiş oluruz. Birim testlerin yazılması temiz kod yazmamızıda sağlar , testin doğası gereği kodlarımızı daha anlaşılır kılmaya çalışırız. Mesela ben test yazarken tekrar kodu çok yazdığımı hep farkeder ve düzeltirim test aşamasında refactoring yaparım bir nevi …
Geliştirme yaparken çoğunlukla olması gerekeni yazıp olması gereken parametrelerle deneme yaptığımız için herşey yolunda gözükebilir J ama unit test yazdığımızda kendimizle yüzleşir gibi açığımızı bulmaya çalışırız ve bunun sayesinde belkide prodda çıkacak bug’ları test yazarken farkına varıp düzeltiriz . Bu yüzden birim test bir yazılımcının olmazsa olmazıdır.
Ozaman gelin bir birim test nasıl yazılır buna değinelim. Yapacağımız uygulama biz bir kelime veya cümle yolladığımızda bize kaç sesli yada kaç sessiz harfin olduğunu söyleyen Harf Bulma isminde uygulama .
Ben maven projesi açtım junit kütüphanesini pom.xml ile ekledim. Normal proje açan arkadaşlar ise aşşağıdaki linkten kütüphaneyi indirip projesine ekleyebilirler.
url : http://mvnrepository.com/artifact/junit/junit/4.11
dependency:
1 2 3 4 5 |
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency> |
Projemizde bulunan Test klasörünün altına bir tane AppTest.java isminde java sınıfı oluşturalım.Arkadaşlar dikkat ederseniz ilk test sınıfımı yazıyorum. Test sınıfımıza iki tane test metodu ekleyelim ve birisi sesli harfleri biriside sessiz harfleri test etsin . Senaryomuz şöyle HarfBulmaca isminde sınıfımızın olduğunu varsayalım ve içindede iki tane method olsun String parametre alan kacSesli(); ve kacSessiz();
Görüldüğü gibi iki tane test methodumuzu yazdık Test blokları olduğunu @Test notasyonu ile belli ediyoruz. Şuan HarfBulmaca isminde sınıfımız yok ve onlara bağlı methodlarımızda olmadığından editörümüz bize kızıyor.Senaryoyu bildiğimiz için test sınıfımızda öyle bir sınıf varmış gibi metodları varmış gibi davranıp yazıyoruz ve testini yazdığımız sınıfları methodları sonrasında oluşturuyoruz.Böylece test güdümlü yazılım yapmış oluyoruz . İlk önce testini ekle sonrasında kodla en sonda ise refactor et . (Test ekle – kodla – refactor et) Test-driven development(TDD).
Test metodlarımızı yazdık artık kodlamaya başlayalım.
Artık HarfBulmaca sınıfımız ve methodlarımızı oluşturduk. Gelelim içlerini yazmaya ne demiştik metodlarımız birer tane String parametre alıcak cümle veya kelime biz sesli ve sessiz harfin kaç tane olduklarını dönecektik.
HarfBulmaca.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
package com.mkilic.junitletter; import static com.mkilic.junitletter.App.kacSesli; /** * * @author mkilic (www.kilicmehmet.com) */ public class HarfBulmaca { public int kacSesli(String kelime) { String sesliler = "aeoöuüiAEOÖUÜIı"; int toplam = 0; for (int i = 0; i < kelime.length(); i++) { if (sesliler.indexOf(kelime.charAt(i)) != -1) { toplam++; } } return toplam; } public int kacSessiz(String kelime) { return kelime.length() - kacSesli(kelime); } } |
Sınıfımızı ve methodlarımızı yazıp içlerini doldurduktan sonra testimize başlayalım .Bunun için org.junit kütüphanesinden gelen Assert sınıfının statik metodlarını kullanacağız biz dönen sesli veya sessiz harfin kaç olması gerektiğini karşılaştıralım , bunun için Assert sınıfının assertEquals(param1,param2); methodunu kullanalım .
param1:Olması gereken değer
param2:Methodlarımızdan dönen değer
Test Sınıfımız:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
package com.mkilic.junitletter; import org.junit.Assert; import org.junit.Test; /** * * @author mkilic (www.kilicmehmet.com) */ public class AppTest { @Test public void testSesliHarfler() { HarfBulmaca ltrFnd = new HarfBulmaca(); int donenSesli = ltrFnd.kacSesli("www.turkishh.com"); Assert.assertEquals(3, donenSesli); //assertEquals methodu karşılaştırma yapıyor //2 parametre alıyor ilk parametre dönmesi gerekendeğer //ikinci parametre ise methoddan dönen değer //şart sağlandığında test'ten geçebilir projemiz } @Test public void testSessizHarfler() { HarfBulmaca ltrFnd = new HarfBulmaca(); int donenSessiz = ltrFnd.kacSessiz("www.turkishh.com"); Assert.assertEquals(9, donenSessiz); } } |
Run Test dediğimizde bakalım çıktısı ne olacak
Test’ten geçemedik çünkü sesli harflerin olması gereken 2 ama gönderdiğimiz kelimede 3 sesli harf var aynı şekilde sessiz harflerdede 9 sessizin olması lazım ama 13 tane varmış. Testimizi şu parametre’yi göndererek yapalım birde’’ www.kilicmehmet.com’’ ve olması gereken sesli:5 , olması gereken sessiz:14 olsun .
Test Run dedğimizde çıktısı
Ve testimizden geçti bu sefer çünkü olması gereken ile dönen değer eşleşti. Şimdi sıra geldi kodumuzda bi kaç değişiklik yapalım gerçi tam anlamıyla refactoring olmayacak ama parametreleri dışarı çekelim biraz daha güzelleştirelim kodumuzu .
HarfBulmaca.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
package com.mkilic.junitletter; import static com.mkilic.junitletter.App.kacSesli; /** * * @author mkilic (www.kilicmehmet.com) */ public class HarfBulmaca { public static String SESLILER = "aeoöuüiAEOÖUÜIı"; int toplam = 0; public int kacSesli(String kelime) { for (int i = 0; i < kelime.length(); i++) { if (SESLILER.indexOf(kelime.charAt(i)) != -1) { toplam++; } } return toplam; } public int kacSessiz(String kelime) { toplam = kelime.length() - kacSesli(kelime); return toplam; } } |
Birkaç notasyondanda bahsetmekte yarar var diye görüyorum.
- @Test : Methodun tes edileceğini gösterir
- @Test(expected = Exception.class) : Method hata fırlatmalıdır
- @Before : Methodtan önce çalışır.
- @After : Methodtan sonra çalışır
- @BeforeClass : Sınıf instance olduğunda bir defalığına çalışır
- @AfterClass : Metodları test ettikten sonra çalışır
- @Ignore : Test edilmesini istemediğimiz methodları temsil eder
Bir başka bilmemiz gereken şey ise birden fazla test sınıfı yazdığımızda aynı anda çalıştırabilmek için Suit sınıfı yazmalıyız ve alttaki notasyonları sınıfın başına eklemeliyiz.
AppTests.java
1 2 3 4 |
@RunWith(Suite.class) @SuiteClasses({ AppTest1.class, Aptest2.class }) public class AppTests { } |
Tüm anlattıklarımın sonunda şunu demek istiyorum Unit test(Birim test) candır 😛
Bir sonraki anlatmayı düşündüğüm kütüphane ise Mockito kütüphanesi mesela test yazdığımızda dönüş değerinin ne olabileceğini kestiremediğimiz durumlarda bu sınıf işimizi çözüyor . J
Umarım yararlı olmuştur J
İyi Çalışmalar