Ne Olup Bittiğinden Habersiz Testlere Derman: MocksCollector

Test yazmanın en büyük getirisi yazılan koda dair hızlıca geri bildirim alabilmek.

https://ufukuzun.wordpress.com/2017/04/19/unit-testing-sunumu/

Test yazmaya başlayacak yada yeni başlamış geliştiricilerin aklındaki ilk soru genelde şu şekilde oluyor: “Ne kadar test yazmalıyız / nerede durmalıyız / hedefimiz sadece %100 coverage (kapsama) mı olmalı?” — Örnekler çoğaltılabilir. Bu soruların cevabının test yazmanın temel getirisi olan geri bildirim almakta saklı olduğunu düşünüyorum. İdeal durumda testlerimiz öyle kapsayıcı olmalı ki, yapılan her geliştirmeye doğru geri bildirimler vermeli, ve testler geçiyorsa canlıya çıkmaya hazırdır denecek kadar içimizi rahat ettirmeli. İşte tam bu noktada karşımıza “kaliteli test” kavramı çıkmakta. Her geliştirmemize karşılık doğru geri bildirimler veren, tabiri yerindeyse arkamızı kollayan testlere “kaliteli”dir diyebiliriz. %100 branch/line coverage bizi bu hedefe yaklaştırsa da çoğu zaman yeterli değildir.

Test kalitesini arttırma çabasına bir örnek olması açısından yaklaşık 5 sene önce n11’de çalışırken karşılaştığım bir test kalitesi sorunsalını çözümeye çalışırken uyguladığım yaklaşımı sizlere paylamak istiyorum:

MocksCollector

Java ile web uygulaması geliştirenlerin neredeyse vazgeçilmezi haline gelmiş Spring çatısı ile geliştirme yaparken Controller / Service / Repository katmanlarına ayrılmış bir şekilde kodlarımızı yazarız. “Service” katmanında ilgili domainin “business logic”leri kodlanır, ve bu sırada ilgili domainin “Repository”si ve pek çok başka “Service” enjekte edilerek (@Autowired) ve kullanılarak business logic gerçeklenir. Bu servisler zamanla büyür, büyüdükçe belli ilgilere göre metotlar gruplanarak başka serviscikler meydana getirilir, böyle devam eder gider.

Şöyle bir durumla karşı karşıyaydım: Geliştirme yapacağım servis 10’dan fazla servisi kullanılıyordu. Bu servislerden bir kaçının farklı şekillerde kombine edilerek çağrıldığı birden fazla public metoda sahipti. Bu metotların birim testleri de yazılmıştı, ve “coverage” %100’dü. Ben de farklı bir business logic için çağrılacak yeni bir metot ekleyecektim. Ekledim de. Fakat testini yazarken şunu farkettim: Metodumda farkında olmadan, aslında benim metodumda çağrılmaması gereken, hatta çağırıldığında çalışma zamanında (runtime) business logic anlamında sıkıntı çıkaracak bir servisi çağırmıştım. Fakat testim bu durumdan habersizdi. Güvendiğim dağlara yazıklar olmuştu. Testim geçiyordu fakat kodum yanlıştı. Hemen testimde değişikliğe giderek o an o test sınıfında tanımlı tüm mock servisleri geçtiğim bir verifyNoMoreInteractions(…) satırı ekledim. Böylece verifyNoMoreInteractions(…) öncesinde verify() ile varlığını kontrol ettiğim mock etkileşimleri (interactions) dışında başka bir etkileşim olmadığı konusunda içim rahatladı. Yanlışlıkla başka bir servis ile etkileşime girildiğinde testim bana anında geri bildirimde bulunacaktı. Ancak o sırada aslında bu durumun ne kadar da yaygın olduğunu farkettim. Mock kullanılan neredeyse tüm testlerde bu durum gözden kaçıyordu. verifyNoMoreInteractions() kullanımı bu farkındalık olmadığı için pek de yaygın sayılmazdı.

Devamı »
Reklamlar

“Systems Thinking”, yine mi sen!

Son aylarda katıldığım yada internetten izlediğim sunumlarda sıkça rastlamaya başladım “Systems Thinking” (Sistem Düşüncesi) kavramına. Biri “Hangi Agile?”, biri “Strategic Growth Hacking”, bir diğeri “One Hacker Way” başlıklı sunumlarda, hiç beklemediğim anda bu kavram çıkıverdi karşıma.

İlki Erik Meijer’in “One Hacker Way” sunumuydu:

Erik Meijer sunumunda bir noktadan itibaren matematiğin öneminden konuya girip Computer Science ve “Systems Thinking” (Control Theory) ilişkisini anlatmaya başlıyor, ve üniversitelerin Computer Science bölümlerinde neden “Systems Thinking” konusunun anlatılmadığından yakınıyor. Özetle; yazılımların geri bildirim döngüleri (feedback loops) ışığında geliştirilirlerse başarılı olabileceklerini söylüyor.

Sonraki, İTÜ Çekirdek’te katıldığım “Strategic Growth Hacking” sunumuydu. Kılıçhan Kaynak uzun yıllar Amerika’da yaşamış, girişimler kurmuş ve batırmış (kendi ifadesiyle) birisi. Sonra oturup düşündüğünde ve araştırdığında aradığı cevabı “Systems Thinking” yaklaşımında bulmuş. Sonra bu birikimini “The Spaghetti Startup: A Tale of Startup Survival or How to Achieve Radical Growth with Systems & Design Thinking” adlı kitabı yazarak ve girişimcilere/girişimci adaylarına sunumlar yaparak paylaşmak istemiş.

(Sunum sırasında İTÜ Çekirdek tarafından kayıt yapılıyordu ancak videosunu maalesef bulamadım.)

Son sunum ise dün akşam izlediğim “Hangi Agile?” başlıklı sunum oldu. Abdulkadir Yaman sunumun hemen başlarında “Neden Agile yapıyoruz?”u anlamak için “Systems Thinking” bilmemiz gerekir diyince bu bloğu yazmam şart oldu diye düşündüm. :)

(Sunumu organize eden Istanbul Coders grubuna teşekkürü borç bilirim.)

Konuşmacıların ortak söylemleri şöyle:

  • Her şeyi sistem olarak değerlendirebiliriz. Her şeye, mesela evliliğe bile sistem olarak yaklaşırsanız, daha mutlu olursunuz. :)
  • Sistemlerdeki geri bildirim döngülerini iyi anlamalıyız. Örneğin TDD (Test Driven Development) yazılımcının yazdığı kodun çalışıp çalışmadığıyla ilgili en hızlı şekilde geri bildirim almasını sağlayan bir geri bildirim döngüsü barındırır.
  • Sistem bileşenleri arasında bilgi akışı (information flow) sağlanmalı.

Dün akşam izlediğim sunumdan sonra artık “Systems Thinking” üzerine okumalar yapmaya başlamanın zamanı geldi de geçiyor diye düşündüm. Ve buna Kılıçhan Kaynak’ın “The Spaghetti Startup…” kitabıyla başlayacağım gibi görünüyor: http://lasagnac.com/