Test kavramı bir yazılım için olmazsa olmaz. Sanırım artık bu herkesin kabul ettiği bir şey. Yazılımın çalıştığını kanıtlamak, ihtiyaçları karşıladığını göstermek ve belli kalite özelliklerinin sağlandığını doğrulamak için en somut çalışmalardan biri. Çeşitli test adımları, test türleri ve test süreçlerinden çok yazılımcı olarak, geliştirme aşamasında yapmadığımız testlerden bahsetmeye çalışacağım. Neden yapmadığımızın sebebini bulabiliriz belki…

Neden “test” yazmıyoruz?

Bir çok sebep sayabiliriz sanırım. “Zaman bulamıyorum”, “Gerek duymuyorum”, “Test benim işim değil ki”, “Test kodu yazacağıma, 10 tane ekstra özellik yazarım” falan gibi çeşitli sebepler sanırım çoğu kişinin ortak cevabı olacaktır. Biraz acı olacak belki ama ne yazık ki bunlar bahaneden başka hiç bir şey değil. Hiç biri geçerli bir sebep değil. Test yazmıyor olmamızın en büyük sebebi, aslında kendimiziz. Test

Yazdığımız kodların, test edilebilir olmaması test yazmıyor olmamızın en büyük sebebi. Test edilebilir kod yazmak, test yazmaktan çok daha zor bir olay ne yazık ki. Test yazmak isteyip de bu gerçekle karşılaştığımız zaman, motivasyonun kaybolması ve test yazmayı bırakmak en çok duyduğum ve bizzat da yaşadığım bir olay. Test edilebilir kod yazmak, belli bir zaman geçtikten sonra bazı konulara hakim olduktan sonra daha kolay olacaktır. Bu noktada herkes biraz öz eleştiri yaparsa benzer şeyleri düşüneceğine inanıyorum. Test edilebilir kod yazmak, çeşitli yazılım geliştirme prensiplerine hakim oldukça daha kolaylaşacaktır. Yazdığınız kodlar için birim test yazmaya başladığınızda bir noktada tıkanıyorsanız, yılmadan neden yazamadığınız, kodun neresinde tıkandığınız konusunda düşünmeye başlayın. Daha sonra problem ile ilgili olabilecek prensipleri(mesela OOP prensipleri yani SOLID ya da diğer prensipleri; YAGNI,KISS….vs.), kodunuzda doğrulamaya çalışın. Bu şekilde hem kodunuzu iyileştirmiş, hem de test edilebilir bir koda sahip olmuş olacaksınız. Zamanla bu bir alışkanlık haline geleceğinden, yazdığınız kod için birim test yazmak çok daha kolay olacaktır. Yazdığınız kodlara, test yazabiliyor olmak, programınızın çalışabilirliğini doğrulamak dışında, tasarımınızı da doğru bir şekilde refactor etmenizin en etkili yöntemi olacaktır ayrıca.

TDD

Test yazmak, farklı bir düşünce yaklaşımı da gerektirdiğinden, normal bir kodla, test kodu yazmak farklılık gösterecektir. Genelde metod yazarken, ilk olarak “doğru” sonuç odaklı bir yöntem izleriz. Çünkü, “doğru”yu zaten biliyor oluruz ve bu genelde kolay gelir. MusteriGetir() diye, belli bir parametre aldığında müşteri bilgilerini getiren metodu yazarken, getirilen müşterilerin aktif/pasif durumu, geçerli bölgesi, alışveriş durumları vs. gibi kontrol edilmesi gereken arka plandaki ihtiyaçlar sonradan kodumuzda yer bulur. Hele bu ihtiyaçlar net değilse, en basit kontrol durumları bile atlanır. Olmaz demeyin, oluyor… Ancak ilk olarak “doğru” sonuçlara odaklanmak yerine, olabilecek diğer ihtimalleri de kontrol edebilecek bir şekilde kodumuzu tasarlarsak, test edebileceğimiz kapıları kendiliğinden açmış olacağız. Daha sonra test yazmak zaten kolay olacaktır. Çünkü kapılar bize neleri test etmemiz gerektiğini gösterecektir. Bu noktada TDD(Test Driven Development)’ın altını çizmek isterim. Benim çok tercih ettiğim bir yaklaşım olmasa da belki size kolaylık sağlar. TDD ve test yazmanın farklı şeyler olduğunun da ayrıca özellikle altını çizmek isterim. TDD, birim testlerinizi önce yazarak kodu geliştirme yönünde sizi motive eden bir geliştirme yöntemidir. Bunun dışında, test yazmak, birim test geliştirmek, geliştirmelerinizi tamamladıktan sonra da yapabileceğiniz bir aktivite olduğundan TDD’den farklı olarak yorumlanmalıdır. TDD’nin, test edilebilir kod yazma konusunda etkili olduğuna inanıyorum ama daha yazmadığınız bir şeyi test ederek ortaya çıkarmak, yukarıda bahsetmiş olduğum tasarımı etkili refactor etme konusunda engel olarak karşınıza çıkabilir. En azından benim çıkıyor. Belki daha yeterince oturmamıştır bazı şeyler, kim bilir… Bu konu biraz karışık ve uzun. Hatta bu sene Martin Fowler, Kent Beck ve David Heinemeir Hansson’un güzel bir sohbeti var. Biraz uzun ama mutlaka izleyin, dinleyin derim… Bu adresten ulaşabilirsiniz.

Test edilebilir kod yazma alışkanlığı belli bir zaman sonra oturduğundan, zaten test yazma ihtiyacı kendiliğinden çıkacaktır. Ve bir bakmışsınız ki, NUnit, xUnit gibi birim test frameworkleri arasında kaybolmuşsunuz. Doğru yolu bulmak için kaybolmak iyidir. O yüzden yılmak yok…

Test

Test edilebilir kod yazmanın en büyük zorluklarından biri de, bağlılıklar ve bağımlılıklar. Geliştirdiğiniz nesnelerin bağlı oldukları ve bağımlı oldukları diğer nesneleri iyi yönetip, tasarlayamazsanız, test yazmanız oldukça zor olacaktır. Bu noktada SoC(Seperation of concerns) prensibi ve bu prensibi uygulayabileceğiniz DI,IoC gibi kavramlar bilinç altınızdan çıkıp, size yol göstermeli. Bunlarla beraber, kodunuzdaki bağlılıkları ve bağımlılıkları çözdüğünüzde, elinizde ayrı ayrı çok rahat bir şekilde test edilebilecek prizler ve fişler olacaktır.

Daha sonra bu birim testleri ile sistem ve entegrasyon testlerinizi oluşturabilirsiniz ve yazılımızını çeşitli kalite özelliklerine göre de test edebilirsiniz.

Açıkcası çok fazla test yazan bir yazılımcı değil(d)im. Kod kapsamı açısından bakıldığında %30-%40’larda kalıyordu genelde. Ama şu an gelişimden sorumlu olduğum bir projede, kendime bu oranın %70’lere kadar çıkması gerektiği konusunda bir hedef koydum. Dolayısıyla yazdığım her kodun sonrasında, birim testini de yazıyorum. Evet, TDD yöntemi ile ilerlemiyorum ve hatta bazen test yazmak için daha fazla zaman harcıyorum. Ama şunu söyleyebilirim ki, daha temiz bir kod ve en önemlisi hata oranı oldukça düşük bir code base oluşuyor. Ve görüyorum ki zaman geçtikçe test yazma ihtiyacı hatta birim testler kendiliğinden ortaya çıkıyor ve bir noktada cidden kolaylık sağlıyor.

Test yazmanın faydalarını, neden test yazmıyoruzu falan biraz sesli düşünerek paylaşmaya çalıştım. Biraz karışık olmuş olabilir ama faydalı olacağına inanıyorum. Bu konuda her türlü eleştiri,soru ve fikire açığım. Aklınıza bir şey gelir ya da takılırsa, hemen yapıştırın e-maili… 🙂