State Based Testing

Uzun zamandır Test Driven development ile alakalı yazı yazmıyordum. Açıkçası en çok önem verdiğim konu hakkında vakit bulupta yazamamak beni oldukça rahatsız ediyordu. En azından herkesin faydalanması için bu tarz kaynaklara çok fazla ihtiyaç olduğu fikrindeyim.Test Driven Development hakkında yazacağım önümüzdeki birkaç makale için daha önce hiç denemediğim ve doğaçlama olarak küçük bir Hesap Makinası uygulaması yapacağız.Uygulama .NET C# kullanarak geliştireceğiz.

Öncelikle hesap makinası için yapmamız gereken şeyleri Windows”un kendi hesap makinasını inceleyerek öğrenebilirsiniz.Bu yüzden liste halinde yazmıyorum.Aslında bu örnekte hem state based testing nedir nasıl yapılır ona değinmek istiyorum hem de sizin doğaçlama olarak uygulamanın Test Driven Development mantığıyla nasıl geliştirildini görmenizi istiyorum. Şuanda bu satırları yazarken bende bu konuda tamamen bilgisizim uygulamanın ne tasarımını yaptım ne de hangi sınıf olmalı birbiriyle nasıl ilişki halinde olmalıdır diye kurguladım. Bu yazıyı yazılım geliştirirken düşüncelerimin yazıya aktarılmış hali olarak düşünebilirsiniz. Ayrıca Test Driven Design  ın nasıl yapıldığınıda görmüş olacağız.

Öncelikle geliştirme ortamımızı hazır edelim. İlk olarak .NET için en popüler Unit Test framework olarak kullanılan NUnit(2.0 binary zip sürümü) i indiriyorum. Ardından Visual Studio için olmazsa olmazlardan Resharper 4.0 ı indiriyorum. Sebebini soracak olursanız kod geliştirirken üretenliğinizi oldukça arttıran, Testleri kolaylıkla çalıştırmak,Refactoring yapmak için mükemmel bir araç. Zaten bu konuda ödüllü olduğu için bunu başka bir yazı konusu olarak sonraya bırakıyorum. Sadece kurun ve kullanın ne demek istediğimi çok iyi anlayacaksınız. Benim geliştirme ortamım bu arada VS.NET 2008. NUnit ve Resharper VS.NET 2005″de de çalışacaktır.

Ortamı hazırladık.İlk olarak VS.NET de yeni bir Class Library projesi oluşturuyorum.Adına HesapMakinesi dedim. Ardından ilk yaptığım şey test kodunu yazmak olacak bunun için projeye HesapMakinesiTest adında bir sınıf ekledim. Öncelikle aşağıdaki gibi test kodlarını görüyorsunuz.

<br />
using NUnit.Framework;<br />
namespace HesapMakinesi<br />
{<br />
 [TestFixture]<br />
 public class HesaplayiciTest<br />
 {<br />
 private Hesaplayici hesaplayici;</p>
<p> [SetUp]<br />
 public void Setup()<br />
 {<br />
 hesaplayici = new Hesaplayici();<br />
 }</p>
<p> [Test]<br />
 public void Olustur()<br />
 {<br />
 Assert.IsNotNull(hesaplayici);<br />
 }</p>
<p> [Test]<br />
 public void IntegerToplama()<br />
 {<br />
 hesaplayici.Islem = &quot;Toplama&quot;;<br />
 hesaplayici.Sayi1 = 3;<br />
 hesaplayici.Sayi2 = 2;<br />
 Assert.AreEqual(5,hesaplayici.Hesapla());<br />
 }</p>
<p> [Test]<br />
 public void DoubleToplama()<br />
 {<br />
 hesaplayici.Islem = &quot;Toplama&quot;;<br />
 hesaplayici.Sayi1 = 3.123;<br />
 hesaplayici.Sayi2 = 4.567;<br />
 Assert.AreEqual(7.69, hesaplayici.Hesapla());<br />
 }</p>
<p> [Test]<br />
 public void IntegerCikarma()<br />
 {<br />
 hesaplayici.Islem = &quot;Cikarma&quot;;<br />
 hesaplayici.Sayi1 = 6;<br />
 hesaplayici.Sayi2 = 5;<br />
 Assert.AreEqual(1, hesaplayici.Hesapla());<br />
 }</p>
<p> [Test]<br />
 public void DoubleCikarma()<br />
 {<br />
 hesaplayici.Islem = &quot;Cikarma&quot;;<br />
 hesaplayici.Sayi1 = 3.432;<br />
 hesaplayici.Sayi2 = 5.123;<br />
 Assert.AreEqual(-1.691, hesaplayici.Hesapla(),0.001);<br />
 }</p>
<p> [Test]<br />
 public void IntegerBolme()<br />
 {<br />
 hesaplayici.Islem = &quot;Bolme&quot;;<br />
 hesaplayici.Sayi1 = 10;<br />
 hesaplayici.Sayi2 = 5;<br />
 Assert.AreEqual(2,hesaplayici.Hesapla());<br />
 }</p>
<p> [Test]<br />
 public void DoubleBolme()<br />
 {<br />
 hesaplayici.Islem = &quot;Bolme&quot;;<br />
 hesaplayici.Sayi1 = 8;<br />
 hesaplayici.Sayi2 = 5;<br />
 Assert.AreEqual(1.6, hesaplayici.Hesapla());<br />
 }</p>
<p> [ExpectedException(typeof(SifiraBolmeHatasi))]<br />
 [Test]<br />
 public void SifiraBolme()<br />
 {<br />
 hesaplayici.Islem = &quot;Bolme&quot;;<br />
 hesaplayici.Sayi1 = 8;<br />
 hesaplayici.Sayi2 = 0;<br />
 hesaplayici.Hesapla();<br />
 }<br />
 }<br />
}<br />

Yukarıdaki test kodunu yazdıktan sonra testi geçecek aşağıdaki gibi HesapMakinesi sınıfı içindeki kodu ?? ???????? ??????? yazdık.

<br />
namespace HesapMakinesi<br />
{<br />
 public class Hesaplayici<br />
 {<br />
 private string islem;<br />
 private double sayi1;<br />
 private double sayi2;</p>
<p> public string Islem<br />
 {<br />
 get { return islem; }<br />
 set { islem = value; }<br />
 }</p>
<p> public double Sayi1<br />
 {<br />
 get { return sayi1; }<br />
 set { sayi1 = value; }<br />
 }</p>
<p> public double Sayi2<br />
 {<br />
 get { return sayi2; }<br />
 set { sayi2 = value; }<br />
 }</p>
<p> public double Hesapla()<br />
 {<br />
 double sonuc = 0;<br />
 if (Islem == &quot;Toplama&quot;)<br />
 sonuc = Sayi1 Sayi2;<br />
 else if (Islem == &quot;Cikarma&quot;)<br />
 sonuc = Sayi1 - Sayi2;<br />
 else if (Islem == &quot;Bolme&quot;)<br />
 {<br />
 if(Sayi2==0)<br />
 throw new SifiraBolmeHatasi(&quot;Sifira bolunemez&quot;);<br />
 sonuc = Sayi1 / Sayi2;<br />
 }</p>
<p> return sonuc;<br />
 }<br />
 }<br />
}<br />

Burada ritimi hissedin diye söylüyorum.Burada kodun hepsini bir arada görüyorsunuz fakat geliştirirken öncelikle bir özelliği edecek test metodu yazdık ardından sadece o testi geçecek kodu yazdık.Yazı fazla uzamasın diye testlerin ve kodların bu şekildeki tüm halini yapıştırdım.Yukarıdaki koda baktığınızda string olarak Toplama işlemi için karşılaştırma yapmışız. Bana bir code smell gibi geliyor.Şimdilik böyle bırakalım ileride Refactoring yaparak bunu düzeltiriz.

Şimdi test metodlarından herhangi birini daha yakından inceleyelim.

<br />
	[Test]<br />
 public void DoubleBolme()<br />
 {<br />
 hesaplayici.Islem = &quot;Bolme&quot;;<br />
 hesaplayici.Sayi1 = 8;<br />
 hesaplayici.Sayi2 = 5;<br />
 Assert.AreEqual(1.6, hesaplayici.Hesapla());<br />
 }<br />

Yukarıdaki test kodlarına baktığınızda test etmek istediğimiz hesaplayici sınıfını öncelikle oluşturup ardından ona yapmak istediğimiz işlemi atıyoruz. Ardından hesaplanacak sayılarıda verdikten sonra nesnenin test etmek istediğimiz özelliğinin sonucunu Assert.AreEqual(1.6, hesaplayici.Hesapla())… gibi Assert metodlarıyla test ediyoruz.Yani bu şekilde nesnenin durumundaki değişiklikleri Assert metodlarıyla test etmeye State Based Testing denir. Klasik test metodu olarak en çok kullanılan test metodu State Based Testing”dir.Bu test metodu genellikle nesnelerin diğer nesnelerle ilişkisinin az olduğu ya da hiç olmadığı durumlarda daha çok kullanılır.Eğer test etmek istediğimiz sınıflar veritabanı,network,GUI… gibi test ortamında oluşturulması zor olan şeyler ise bu test metodunu kullanmak daha zor olabilir tabi imkansız değildir.Bu tarz durumlarda da Stubs adı verilen sınıflarla yine State Based testing yapabiliriz.

Şimdi aklınıza diğer test metodu nedir diye bir soru gelmiştir. Cevabı diğer yazımızda Interaction Based Testing”i örneğimize kaldığımız yerden devam ederek bu test metodunu inceleyeceğiz.

2 thoughts on “State Based Testing

  1. Ali Toz

    Yazıdan önce tüm test metodlarını yazdınız gibi bir anlam cikardim. TDD de kucuk adimlarla ilerlemek gerekmiyor mu?

  2. M. Cihat Altuntaş Post author

    “Burada kodun hepsini bir arada görüyorsunuz fakat geliştirirken öncelikle bir özelliği ekleyecek test metodu yazdık ardından sadece o testi geçecek kodu yazdık.Yazı fazla uzamasın diye testlerin ve kodların bu şekildeki tüm halini yapıştırdım”
    Yazıda bu şekile belirtmiştim gözünüzden kaçmış olsa gerek.

Comments are closed.