JUnit ile Test Odaklı Geliştirme

Test Odaklı Geliştirme ( Test Driven Development) en basit haliyle; uygulama geliştirirken test kodlarını yazarak başlamak ve diğer gereken sınıfların (class) ve metodların bu test koduna göre yazılmasıdır.

En çok kullanılan test altyapısı birim test (UnitTest) dir. Eğer bir java uygulaması geliştiriyorsanız kullanacağınız birim JUnit dir.

Şimdi sizlerle Test Odaklı Geliştirme'ye bir giriş yapalım ...

Geliştirme ortamı olarak Eclipse kullanacağız. En son sürüm olarak Galileo'yu indirmenizi tavsiye ederim. Ve tabi ki bir de JUnit'i indirin (Bu yazıyı yazarken en son sürüm 4.7).

Şimdi indirdiğiniz .zip dosyasını açalım. Size tavsiyem yazılım geliştirirken Development / Tools / JUnit gibi bir dizin kullanmanız.

Eclipse'de bir java projesi oluşturuyoruz : File-> New-> Java Project

















Proje ismi olarak TestDrivenDevelopment verelim ve finish'e tıklayın.

Projemize sağ tıklayın -> Build Path -> Configure Build Path 'i seçelim.















Burada Libraries sekmesinden Add External JARs diyoruz. Ve indirdiğimiz, Development / Tools / junit4.7 olarak açtığımız klasördeki junit-4.7.jar arşivini seçiyoruz.

Artık JUnit kullanmaya hazırsınız!

Şimdi, oluşturduğumuz projede yeni bir paket oluşturalım ; com.tdd.test

İçerisine yeni bir class oluşturalım ; CalculatorTest

Burada basit bir hesap makinesi Test Driven Development ile nasıl yapılır onu göreceğiz... CalculatorTest sınıfımız TestCase'i extends edecek. Eğer ctrl+space ile TestCase abstract sınıfını inherit ettiğimizde import sorunu yaşıyorsanız BuildPath de bir hata yapmışsınızdır. CalculatorTest sınıfımızda bir adet testTwoPlusFour methodu oluşturun.

package com.tdd.test;

import junit.framework.TestCase;

public class CalculatorTest extends TestCase {

public void testTwoPlusFour() {

Calculator calculator = new Calculator();

assertEquals(6, calculator.add(2, 4)); // Beklenen sonuç 6 , çağırılan
// metod calculator objesinin
// add metodu.
}

}

Fark ettiğiniz gibi daha Calculator sınıfını yazmadan öyle bir obje olacağını ve bu sınıfın add() diye bir metodu olacağını belirledik. Bu noktadan sonra yapacaklarımız Eclipse quix fix özellikleri ile gereken sınıfları oluşturmak. Hatalı (altı çizili) yerlere gelerek gereken adımları izleyeceğiz, calculator nesnesi için Calculator sınıfı oluşturuyor ve bu sınıfa daha sonra add methodu ekliyoruz. Quick fix bize object döndüren ve argüman olarak iki adet integer değer alan bir method oluşturdu Calculator sınıfında.
package com.tdd.calculator;

public class Calculator {

public Object add(int i, int j) {

return null;
}

}



Şimdi CalculatorTest sınıfımızı çalıştıralım; sağ tık -> run as -> JUnit Test

Test sonucu olarak kırmızı yani hata aldık. Şimdi add metodunu yeniden düzenliyoruz.

package com.tdd.calculator;

public class Calculator {

public int add(int i, int j) {

return i+j;
}

}
Şimdi tekrar çalıştırıyoruz. Sonuç : Yeşil! Metodumuz hatasız bir şekilde çalışıyor... Tabi yazdığımız add metodu aslında try catch bloğu ve if else statement 'leri ile çok daha hatasız ve doğru bir hale getirilebilir.. Ama bu yazının amacı ne kadar iyi bir kod yazılacağı değil. Dikkat ettiyseniz hiçbir metodu veya hiçbir sınıfı direk olarak oluşturmadık. Yaptığımız testde çıkan gereksinimlerden dolayı yazdık.. Bu sayede testimizi geliştirdikçe kodumuz da gelişecektir..
Yazdığımız test sınıfına yeni test metodları ekledikçe kodumuz gelişecek ve aynı zamanda eski testler sürekli olarak kontrol altında olacak. Test odaklı geliştirmenin en büyük artılarından birisi de yeni eklenen kod bloklarının eski kodlarda hataya yol açıp açmayacağını çok kolay bir şekilde izlememizi sağlamasıdır...

Umarım aklınızda birşeyler oluşturmuş, ve sizleri araştırmaya itecek soru işaretlerine yol açmışımdır..





4 comments:

Anonymous said...

Merhaba,
öncelikle güzel anlatımın için teşkkr ederim. Aslında hep derinlemesine öğrenme isteğim var test odaklı geliştirme yapmayı ama malesef fırsat olmuyor..


bir sorum olacak;

1-) assertEquals(6, calculator.add(2, 4));

Buralardaki 6
2 ve 4'ün yerine logic işlemler sonucunda oluşacak, static şeyler yazmasak olur mu?


Derinlemesine örneklerini bekliyorum:) Çalışmalarında başarılar..

NurettinYAKIT said...

Merhabalar Ferhan,

Test odaklı geliştirmeyi öğrenmeni şiddetle tavsiye ederim.. İlk başlarda biraz değişik gelse de faydasını göreceksindir..

Soruna gelince ;

assertEquals(param1,param2);

Metodu iki parametrenin aynı olup olmadığını karşılaştıran bir metod.

Yani birinci ve ikinci parametrenin bir obje veya primitive olması gerekiyor. Tabi bu objenin yerel bir değişken olması şartı yok. Örnekteki gibi bir metod sonucu da olabilir.

Benim verdiğim örnekte metodun sonucu ile 6 değerini karşılaştırdım. param2 olarak kullandığım metod eğer başka bir obje mesela bir String veya Employee (Kendi oluşturduğum nesne) de olabilirdi. Buna göre param1 de aynı sınıf dahilinde olmalı.

Senin istediğin durumu sağlamak için başka bir metod olan assertTrue() 'yu kullanabilirsin. Şöyle bir örnek vereyim;

assertTrue((calculator.add(0, 1)<2));

İyi çalışmalar..

Hasan Avsar said...

Cok tesekkürler, sahim adina giris seviyesinde bana cok faydali oldu. Basarilar dilerim

NurettinYAKIT said...

Ben teşekkür ederim Hasan,

Faydalı olmasına çok sevindim.