Functional Testing vs Unit Testing

Her ne kadar TDD ve Unit Testing' i bir boyutta uygulasam da yazılım geliştirirken XP (extreme programming) ya da benzer bir metodolojiyi sıkı sıkıya takip etmiyorum. Her konuda yaptığım gibi açık fikirli olup, değişik yaklaşımları analiz edip, haklarında bilgi toparlayıp kendi durumuma göre kendi hybrid modelimi kullanmaya çalıştırıyorum. Bu aralar özellikle yazılım geliştirme ile çok iç içeyim ve bunun sonucunda Unit Testing, TDD ve Functional Testing konularında denemeler yapıp en iyi birleşimi bulmaya, işimi en iyi görecek çözüme ulaşmaya çalışıyorum.

Devam etmeden Functional Testing ile Unit Testing' e ve aralarındaki farklara bakalım.

Unit Testing

  • Sistemin en küçük birimlerini test etmektir,
  • Hızlıdırlar,
  • İzolasyon kritiktir ve hiç bir testin diğer testleri ya bir dış kaynağın çalışan testleri etkilememesi gerekir. Bu amacı yerine getirmek için bir web server ya da file system erişimde, ya da diğer herhangi bir class ile konuşma noktasında Mocking devreye girer,
  • Kodda hata oluştuğunda kesin olarak hatanın nerede oluştuğunu saptamak çok kolaydır. (Çünkü sistemin en küçük birimlerini test ediyoruz),
  • Yüksek Code Coverage almaya uygundur,
  • Genelde koddaki her değişiklikten sonra çalıştırılır. Bu sayede kodda gözü kapalı değişiklik yapabilir ve bir sorun varsa anında farkına varabilirsiniz. Bunun anlamı sorun çok daha büyümeden ya da tasarımın içerisine girmeden sorunu çözmek demektir.


Functional Testing (Automated)

  • Sistemin parçalarını ya da sistemin bütün olarak işleyişini otomatik şekilde test etmektir,
  • Daha gerçekçi testler ortaya çıkmasını sağlar,
  • Yavaştırlar (izolasyonun az olması bunun ana nedenidir),
  • Kodun bir yerinde hata oluşması testlerin büyük bir kısmını geçersiz hale getirebilir,
  • Kodda hata oluştuğunda nokta atışı hatayı bulmak pek basit olmayabilir,
  • Bazı testler Unit Testing' e göre çok daha hızlı yazılabilir, çünkü çok daha az test yapmak gerekir. Mesela bir class' ın private method' ları vs. test edilmez. Class' ın geneli beklendiği gibi çalışması yeterlidir,
  • Code Coverage' i yükseltmek zor olabilir çünkü her durumu geniş perspektiften simule etmek mümkün olmayabilir ya da gereğinden çok efor gerektirebilir,
  • Yavaşlığından dolayı ve coverage azlığından dolayı her kod değişikliğinden ya da yeni koddan sonra çalıştırılmaya pek uygun değildir.


Functional Testing' i Unit Testing ile birlikte kullanmak popüler kullanımlardan biri, bu sayede en ince detayda ve tam bir bütün olarak kodun beklenildiği gibi çalıştığı otomatik olarak kontrol edilebilir.

Genel olarak insanların TDD (önce test, sonra kod) ya da klasik Unit Testing yapmamalarının nedeni testleri yazmanın getirdiği ekstra külfet. Özellikle Türkiye gibi agresif, kısa deadline' lı projeler ile dolup taşan yerlerde yazılımcılara Unit Testing önermek küfürmüş gibi algılanıyor. Açıkçası kimse gerçek bir getirisi olmayan bir şey için ekstra vakit ayırmak istemez ama bu işin gerçek ve gözle görülür bir getirisi var (kanıtlanmış mı? Hem evet hem hayır! o başka bir yazı konusu).

Hybrid Model
Eğer...

  • Yazılımınınız çok kritik bir iş yapmıyorsa, (örnek: Ayda cirit atacak robot kontrolü, Nükleer füze tetikleyicisi, Merkez Bankasının para-girdi çıktı düzenleyicisi, Britney Spears' a hava durumuna göre ayakkabı önermeciliği )
  • Geniş bir takıma ve uzun, rahat geliştirme planına sahip değilseniz,
  • Az koyup çok almak istiyorsanız...

bu model sizin işinizi görebilir. Pareto Prensibini bilirsiniz, hani şu 80/20 kuralı. Bir süredir bu mantığa dayanarak Functional Testing ile ve aralarda Unit Testing desteği ile bir proje geliştiriyorum ve otomatik testlerden alacağım faydanın %80' ini %20 efor ile aldığıma inanıyorum.

  • Private method vs. leri test etmiyorum,
  • Çok az mock objesi kullanıyorum,
  • Aşırı izolasyon yapmıyorum,
  • Küçük detayların harici uzun soluklu functional testlere odaklanıyorum,
  • Hata çıkarma olasılığı çok olan, kritik olan kod kısımlarını Unit Testing ile destekliyorum.

Bu modelin en ciddi sorunlarından biri kodun highly coupled (Law of Demeter) olmasına izin veriyor. Tabii ki bunu düzeltmek geliştirici olarak sizin elinizde ama TDD odaklı bir geliştirmede highly coupled class' lar bulmanız pek mümkün olmayacaktır. Açıkçası highly/tightly coupled olmayan kod yazmak gerçekten zor bir iş.

Bu benim yaklaşımım şu ana kadar benim için istediğim kıvamda çalıştığını söyleyebilirim. Eğer şimdiye kadar hiç yapmadıysanız bu şekilde hafif bir başlangıç yapabilir ve biraz tadını çıkartabilirsiniz.
Farklı deneyimleri duymak da hoşuma gider. Özellikle Unit Testing yapıp mutlu olanlar ya da yapmayı deneyip verim alamayanlar gibi.

Taner Diler - 07.01.2010

Her konuda oldugu gibi Türkiye TDD konusunda da çok geri maalesef. Maalesef sirketler yeterli sabri gösteremiyorlar. Halbu ki bütçelendirerek kurduklari test ekiplerinden ne kadar fayda alabiliyorlar? 1. Test ekibinde çalisan o kadar kisinin maaliyeti 2. Insan gözüyle yapilan testlerin etkinliligi ve kalitesi 3. Test ekibinin verimsizligi; is olmadiginda bos kalmalari yada Sürekli ayni seyleri test etmek (ayni form'a 100 den fazla kez veri girisi yapmak) ve o kisilerde olusacak olan moral bozuklugu 4. Test ekibi var diye gelistiricilerin yapacagi son kontrolu gerçeklestirmemesi 5. Yapilan bi degisiklige bagli olan baska bir usecase'in etkilenmesi ve bunun gelistirici & testçinin farkinda olmamasi Halbu ki hem gelistiricilerin hem de testçilerin güzel bir egitim ile TDD pratiklerini kazanmasi, gelistiriciler birim testleri yazarken, testçilerin de integration test'lerini gerçeklestirmesi... Deadline uzayabilir ama sonrasinda yasanacak olan rahatligi bir düsünün. Çalistigim sirkette, insan gözüyle test edilen bir projenin birim testlerinin yazilmasi (ilk basta araçlarla üretilmesi) projelendirilmisti. Otomatik test kodlari üretildi ama sadece o asamada kaldi. Gelistirilen baska bir proje de ise Spring üzerinde TDD yapilmaya çalisildi. ama belli bi asamadan sonra TDD'ye devam edilmedi. Olay proje yöneticilerinde, sirket sahiplerinde ve müsterilerde bitmekte.

1 - 26.12.2008

ferruh abi bu sayfayi optimum da açip kaçiyorum bu kiyagimi unutma =PP

Taylan - 17.12.2008

dayioglu'nun dediklerine katilmakla birlikte, birim testin kod yazimindan önce, fonksiyonelite testin ise ürün verilmeden önce yapilmasi gerektigine inaniyorum. Metodolijisi de böyle degil midir? Bu arada elestirim yanlis anlasilmasin yenilige her zaman için açik biriyim. Kullanisli olduguna inanirsam süreçte degisime gidebilirim. : ) Böyle yazilarla karsilasmak ayri bir mutlu ediyo beni. Yaptigim isin önemini tekrar tekrar ifade ediyor. Tesekkürler.

Oguzhan - 17.12.2008

Tabiki TDD disiplinini benimsedigimizde getirisi oluyor ama Türkiyede proje yöneticileri dahil benimsenen prensip Guerilla Coding tarzinda. Piyasada bunu zorluyor. O sebepten çok kaliteli projeler çikamiyor.

Ufak ölçekli yazilim sirketinin müsteriyle anlasmasini saglayan en büyük etken maliyet ve zaman oldugu için kodu en kisa zamanda bitirmek yazilim firmalarinin piyasada tutunmasini sagliyor.

Bu havalarin, bu taraflara esmesine daha zaman var gibi geliyor bana...

Ferruh Mavituna - 16.12.2008

@burak onu yazmamin sebebi automated functional testing ile unit testing karsilastirdigimi irdelemeye calismamdi. Yani Manual Functional Testing bambaska bir konu, karisiklik olmasin diye ekledim.


@M. Orçun Topdagi : Bu nedenle, kod gelistirirken ve test yazarken, kafayi farkli çalistirmakta, farkli bir kimlik ile klavye basina geçmekte fayda var.


Haklisin, yani gelistirici olarak konuya her zaman ilimli yaklasip "zaten caliscak" seklinde kod yaziyorsunuz, eger test eden kisi olarak yaklasiyorsaniz bunu nasil "patlatirim" diye koda bakiyorsunuz:) Guvenlik testlerinde de ayni sorun soz konusu sistemi ana tasarlayan kisinin guvenlik aciklarini bulmasi diger kisilere gore cok daha zor olabiliyor.

M. Orçun Topdagi - 16.12.2008

Türkiye deki içler acisi durumu degistirmek yine yazilimcilarin elinde. Bu da ancak senin gibi, bilinçlendirme yada en azindan haberdar etmeye çalisanlar sayesinde olabilir.
Bir ekleme de ben yapmak istedim. Gerçi Türkçe blog yazsaydim uzun bir cevap/destek yazisi yazardim ama burayi istila etmeden, küçük bir hatirlatma yapayim.

Öncesinde tasarim ile desteklenmeyen, kod ile beraber yazilan unit-testler genellikle sadece code-coverage in yüksek görünmesine neden olup, bug'larin önüne pek geçmiyor. Yinede uzun vadeli projelerde, bozulmalari tespit ekmekte fayda saglayabilir. Bazen de olmayan tasarimin daha çabuk ergenlesmesini saglayabilir.

TDD hakkinda benimsedigim görüs, yapilacak bir isin farkli bakis açilarindan iki kere tanimlanmasi oldugudur. Insan hatasi elbet olur (100 satirda 1 diyelim), ama iki kisinin ayni yerde ayni hatayi yapma ihtimali oldukça düsürmekte (10000 de 1). Bu nedenle farkli kisilerin bu isi yapmasi daha iyi sonuç veriyor. Tabi bu her zaman (genellikle) mümkün olmuyor. Bu nedenle, kod gelistirirken ve test yazarken, kafayi farkli çalistirmakta, farkli bir kimlik ile klavye basina geçmekte fayda var.

dayioglu - 16.12.2008

Ferruh'çum, Keyifle takip ediyorum, ellerine saglik. Bu son yazida Functional Testing'in yaninda parantez içerisinde "automated" yaziyor ya; ona takildim. FT'in otomatize olmasi sart degildir her halde, degil mi?;) -dayioglu

Yorum Yazın


Tüm yorumlar onaydan geçmektedir, bu işlem en uzun 30 dk. sürecektir. E-mail adresleri yeni yorumları bildirme harici hiç bir başka amaçla kullanılmamaktadır ve sitede gözükmemektedir.



Captcha Kodu