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.
