M.Onur ATÇI

Kişisel Web Günlüğü

NUNIT ile Test Güdümlü Yazılım Geliştirme

Yazılım geliştirme sırasında klasik olarak uygulanan yöntem önce problemi tesbit ederek problemi çözecek olan algoritmanın geliştirilmesi ve sonrasında kodun çalıştırılarak çalışma zamanında hatalarının tesbit edilmesidir. Ben de yıllardır bu yöntemle yazılımlar ürettim ve bu yöntemin eksikliklerine göre çalışma şeklimi iyileştirmeye çalıştım. İlk olarak nesne yönelimli yazılım tasarımına geçtiğimi söyleyebilirim çünkü iyi yazılmış sınıflarla image processing, veritabanı işlemleri ve mail, logging gibi enterprise uygulamaları birer sınıf olarak tasarlayıp kullanmayı öğrendim. İlk etapta bu işlem çok büyük yarar sağlıyorsa da bazen bu temel sınıflarda yaptığınız değişikliklerin nereleri etkileyeceğini kestirmeniz mümkün olmayabiliyordu. Tüm durumları test etmek ve bu testleri her seferinde tekrarlamak ise imkansızlaşıyordu. Bu gibi durumlar için test güdümlü yazılım geliştirme teknikleri geliştirilmiş. Bu teknik test işlemi için üretilmiş bir framework ve test araçlarının kullanımıyla uygulanıyor. En yaygın test frameworkü Xunit. Xunit olarak isimlendirilmesinin sebebi java için geliştirilmiş Junit frameworkünün çok beğenilip .Net (Nunit), C++ (CppUnit) , Python (PyUnit) gibi diller için de yazılmış olması. Ben .net ve java ile ilgilendiğim için genellikle Nunit ve Junit ile çalışmaktayım.
Test güdümlü yazılım geliştirme konusunda bazı sıkıntılar da yok değil. Öncelikle test güdümlü yazılım geliştirmede sanılanın aksine önce test kodunu yazmanız ve sonrasında ürün (production ) kodunu yazmanız gerekiyor. Sonrasında ise test işlemini başlattığınızda kodun hangi testlerden geçip geçemediğini belirliyorsunuz. Ayrıca doğal olarak yazdığınız test kodu, sadece o anda kodun iyileştirilmesi için ve ilerde yazılımın değiştirilebilmesi için kullanılıyor yani müşterinin sisteminde çalışacak olan yazılımda test kodunun doğrudan bir görevi olmuyor. Test güdümlü yazılım geliştirmede yazdığınız kodun en az yarısının test kodu olacağı düşünüldüğünde bunun boşa giden zaman ve emek olduğunu düşünüp TDD(Test Driven Development) tekniğini kullanmanın gerçekten yararlı olup olmadığı konusunda ikileme düşüyorsunuz. Ama yazılmış bir sistemdeki yapılacak tek bir değişikliğin nasıl yeni buglar çıkaracağını ve domino etkisi yaratacağını tecrübe etmiş birisi iseniz TDD tam size göre olabilir. Ayrıca TDD için beklemeye hiç gerek yok. Bundan sonraki yazılan kodlarda biraz da test kodunun yer alması ve bu testlerin her zaman tekrar edilebilir ve kullanılabilir olması gerçekten yaptığınız işte daha emin adımlarla yol aldığınızı gösteriyor. Buraya kadar TDD hakkında internetteki bazı kaynakları okuyarak elde edilebilecek şeylerden söz ettim. Test güdümlü yazılım geliştirme tekniklerini Visual Studio IDE üzerinde uygulamaya çalışacağım. Basit bir test kodu da içeren uygulamaya yer vereceğim. Java ile junit kullanımının daha kolay olduğunu söyleyebilirim. Özellikle Netbeans ortamı test için hazır olarak geliyor.Ama Nunit ve Junit çalışma mantığı ve assertions'lar bakımından birbirinin aynısı olduğu için birini öğrenmenin yeterli olacağını düşünüyorum. Öncelikle .net ortamında NUNit kullanabilmek için http://www.nunit.org/?p=download adresinden NUnit-2.5.5.10112.msi paketini indirip kuruyoruz. (Bu yazı yazılırken Nunit 2.5 versiyonuna sahipti. Daha güncel paketler de indirilebilir.) Bu paket ile bilgisayarımıza Nunit GUI, Nunit Framework kurulmuş oluyor. Visual Studio ile Nunit'i kullanabilmek için http://www.testdriven.net/download_release.aspx?LicenceType=Personal adresinden TestDriven.Net dosyasını indiriyoruz. Bu programla Visual Studio içerisinde testlerimizi çalıştırabileceğiz. (Kişisel kullanımı ücretsizdir.) Bu iki yükleme sonucunda sistemimizde test ortamı hazırlanmış oluyor. Şimdi yapmamız gereken sadece Nunit frameworkü projemize referans olarak eklemek ve test kodumuzu yazmak. Test kodunun yazımında ise farklı yollar izlenebilir. İlk yol aynı solution için yeni bir proje açıp test kodumuzu hep bu projede yazmaktır. Diğer yol ise projemiz içindeki bazı sınıfları test projesi olarak kullanmaktır. Ben öğrenmek için yazdığım kodlarda aynı proje içindeki test sınıflarını kullanıyordum. Örnekte de yeni bir windows console application oluşturarak test kodumu da bir sınıf içinde yazdım.

Burada Math.cs içinde basit bir iş yapan metod yazacağım ve TestKodu.cs içerisinde yazdığım test kodu ile metodu de test etmiş olacağım.
Test ortamını oluşturmak için yapmamız gereken son bir adım kaldı. O da Nunit referanslarının eklenmesi.


Şimdilik mock objelerle çalışmayacağımız için 2. referansın (nuint.mock) eklenmesine gerek yok. Nunit.framework referansını ekliyoruz. Artık test kodu yazmaya başlayabiliriz.
Senaryomuzda 4 sayıdan en küçüğünü bulan bir metod yazmak isteyelim ve bunun için gerekli olan test kodunu senaryoları düşünerek oluşturalım. Öncelikle negatif sayıları test etmeliyiz ve sayıların metoda giriş sıralamasının vereceği tesadüfi doğru sonuçları da engellemeye çalışacağız.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
namespace NUnitTestProjesi
{
[TestFixture]
public class TestKodu
{
[Test]
public void testEt()
{
Math p = new Math();

Assert.AreEqual(4,p.EnKucukBul(new int[] { 9, 4, 7 }));
Assert.AreEqual(9,p.EnKucukBul(new int[] { 9, 12, 15 }));
Assert.AreEqual(-9,p.EnKucukBul(new int[] { -9, 4, 7 }));
}
}
}

Test.cs nin içeriği.

Burada [TestFixture] sınıfın test aygıtı (elektronikçe adı) ve [Test] metodun test olarak çalıştırılacağını belirten attribute'lar. Assert ise tüm test metodlarına verilen ad. Test sonucuna göre çıktı olarak testin başarılı ya da başarısız olduğu döndürülüyor. Aynı metod içinde 1 adet assertion olabileceği gibi çok sayıda da olabilir. Çok sayıda assertion içeren testlerde assertionlardan birisi hatalı olduğunda o test başarısız sayılır. AreEqual ise expected (beklenen) ve actual(dönen değer) i karşılaştıran test metodudur.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NUnitTestProjesi
{
class Math
{
public int EnKucukBul(int[] sayilar)
{
int min = sayilar[0];
for (int i = 0; i < sayilar.Count(); i++)
{
if (sayilar[i] < min)
min = sayilar[i];

}
return min;
}
}
}

Math.cs içeriği.

Yukarıda da en küçük sayıyı bulan algoritmaya ait metod var. Bu iki sınıfı yazdığımızda test işlemini başlatmak yeterli.

Test sonucum ise şöyle:

Şimdi biraz kodda ya da test kodunda değişiklik yapıp hata oluşturmaya çalışalım. Assertion işlemlerinden birisini değiştirdiğimde


Assert.AreEqual(p.EnKucukBul(4,new int[] { 9, 4, 1 }));

için beklenen değer 1 olması gerekirken 4 olarak işaretledim. Algoritmamızın yanlış değer döndürdüğünü varsayarsak (ki bunu sağlamak da zor değil aslında) beklenen değerin 4 olduğunu ama dönen değerin 1 olduğunu söyleyen bir hata alırız.

Test senaryolarının ve metodlarının artmasıyla tüm testlerimiz her defada çalışacak ve sınıflarımız değişikliklere karşı tekrar tekrar test edilmiş olacaktır. Şu ana kadar sadece NUnit ve Test Güdümlü Yazılım Geliştirme tekniğine giriş yapmış olduk. Agile Principles ve TDD üzerine yazılarıma devam etmeyi düşünüyorum. Şimdilik hoşçakalın.

,

One Response to “NUNIT ile Test Güdümlü Yazılım Geliştirme”

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*

Şu HTML etiketlerini ve özelliklerini kullanabilirsiniz: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>