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

Biz Bunları Gist’lerimizde Anlattık! – PostgreSQL

Geliştirici olarak bir projeden/işyerinden ayrılırken “bu projeye çok emek verdi(m)(k), bazı kısımlar şahane, lazım olur günün birinde, zipleyeyim de atayım kenarda dursun” hissiyatı çoğumuzda olur. Ben ise şu iki sebeple bunu yapmaya gerek görmüyorum:

  1. Geçmiş deneyimlerimiz ile yeni çevrede öğrenilen yeni bilgileri harmanlayarak daha iyilerini yazabileceğimize inanıyorum
  2. Geçmiş deneyimlerimi unutmamak için blog ve Gist yazıyorum

(Ayrıca projeyi o şekilde başka yerlere kopyalamak yasal olarak da sıkıntılı olsa gerek.)

github-gist

Gist yazmak da blog yazmak gibi, ama ağırlıklı olarak kod parçaları -hatta çoğu zaman dosyalar- içermekte. Bir baktım 2015’ten bu yana Gist karalıyormuşum. Bazıları public, bazıları private, bazıları blog tarzında uzunca (onları buraya taşısam daha iyi olacak), bazıları bir kaç kelime açıklama ardından bir kaç dosyadan oluşmakta. Her gün işim düşmese de 1-2 ayda bir işim düşüyor oradaki notlarıma.

Bu sabah production ortamındaki bir durumu çözmeye çalışırken öğrendiğim bir yöntem için yeni bir Gist yazınca, ben neden Gist yazıyorum diye tekrardan bir düşünüp yazıya dökmek istedim. Gist PostgreSQL üzerineydi. Geriye dönüp bakınca farkettim, 1 yıl içinde PostgreSQL ile alakalı faydalı olduğunu düşündüğüm 5 adet Gist yazmışım. Günün birinde sizlere de faydalı olması dileğiyle, buyrunuz…

ALTER TABLE ve başka pahalı sorguların çok daha hızlı çalışması için:

Tabloyu kilitlemeden INDEX ekleyip çıkarmak için:

Devamı »

Java 8 Sertifikasyonu (OCAJP 8) – Bölüm 1: Java’nın Temelleri

Bu birinci bölümden itibaren sınavda karşımıza çıkacak konulara değinmeye başlıyoruz. Verilen bilgilerin bazıları zaten bildiğiniz şeyler olacak, ancak bir sınava gireceğimizi ve pek çok yanıltıcı soru olacağını unutmayalım. Bazılarına önceleri benim de dikkat etmediğim, sınavda çeldirici olabilecek bazı özel noktaları “DİKKAT!” etiketiyle belirtiyorum. Verilen bilgilerin çoğunu bu kategoriye girmeye aday olanlardan seçmeye çalıştım. Eğer tamamını okumaktan sıkılırım diyorsanız sadece “DİKKAT!” etiketli kısımları okuyabilirsiniz.

Java Sınıf (Class) Yapısı

  • Java sınıflarının iki temel elemanı vardır: metotlar (methods) ve alanlar (fields).
  • Bunlara aynı zamanda sınıfın üyeleri (members) da denir.
  • Metotlar fonksiyon (function) yada prosedür (procedure) olarak da ifade edilebilir.
  • Alanlar değişkenler (variables) olarak da bilinir.
  • Alanlar sahip oldukları değerler itibariyle sınıf örneğinin (instance) durumunu (object’s state) belirlerken, metotlar sınıf örneğinin durumu üzerinde işlem (operation) yapar ve sınıfın davranışlarını tanımlar.
  • Bir sınıf bu sınıf üyelerinin hiçbirini barındırmayabilir, yada birini veya her ikisini barındırabilir. Yani şu üçü de geçerli sınıf tanımlarıdır:
class Animal {
}
class Animal {

    String name;

}
class Animal {

    String name;

    public String getName() {
        return name;
    }

    public void setName(String newName) {
        name = newName;
    }

}
  • Bir başka sıklıkla karşımıza çıkan kod parçaları ise yorumlardır (comments). Yorumlar kod içerisine eklediğimiz açıklamalardır ve derleyici (compiler) tarafından dikkate alınmaz. Tek satırlı, çok satırlı ve Javadoc tipinde yorumlar mevcuttur:

Devamı »

Java 8 Sertifikasyonu (OCAJP 8) – Bölüm 0: Giriş

Java 8 sertifikasyon sınavına (OCAJP 8) hazırlanırken aldığım notlardan derlemelerimi içeren yazı dizisine hoş geldiniz. 5 yıldan uzun süredir Java programlama dili ile geliştirme yapan birisi olarak burada paylaşacağım notlar haliyle daha çok “highlights” (önemli noktalar) tadında olacak.

java8-logo

Lafı uzatmadan…

OCAJP 8 nedir?

  • Açılımı “Oracle Certified Associate, Java SE 8 Programmer”.
  • Oracle Sun’ı satın almadan ve kapsamını bölerek iki ayrı sertifikasyon programı haline getirmeden önceki adı “Sun Certified Java Programmer (SCJP)” olan sertifikasyon programının birinci aşaması.
  • Java’nın temel/görece basit konularının ele alındığı bu programın bir büyüğü ise OCAJP 8 (Oracle Certified Professional, Java SE 8 Programmer)
  • Bu iki program da Java SE konularını kapsamaktadır ve Java EE ile ilgili sertifikasyon programlarının ön koşuludurlar.
  • Kapsamı, giriş ücreti (şu sıralar 798 TL / 210$ civarı) ve sınav merkezi lokasyon bilgisi için (Türkiye’de pek çok test merkezi mevcut): http://education.oracle.com/pls/web_prod-plq-dad/db_pages.getpage?page_id=5001&get_params=p_exam_id:1Z0-808

OCAJP 8 konuları?

Devamı »

“Clean Code’dan Notlar”

Clean Code kitabından özenle seçilmiş notlar temel alınarak hazırlanmış 12 bölümlük bir yazı dizisi:

Hayat arkadaşım Büşra Uzun tarafından kaleme alınmış olması ayrı bir gurur, zaman zaman dahil olup katkıda bulunmuş olmak ayrı bir mutluluk…

Başı-Boş Satırlar – IntelliJ ile Bahar Temizliği Bölüm 2

Geçenlerde IntelliJ’de tek bir hamlede tüm Java kodumuzun biçimsel düzenini sağlamanın yöntemine göz atmıştık: Kodunuza İyi Bakın – IntelliJ ile Bahar Temizliği

Şimdi ise Java kodumuzdaki tüm gereksiz boş satırları silmenin yolarına göz atacağız. Birinci bölümdeki yöntemi uyguladıktan sonra “Edit > Find > Replace in Path…” özelliğini uygun regexler ile kullanarak şunlardan kurtulabiliriz:

Kodun herhangi bir yerinde yer alan ard arda iki boş satırdan…

Text to find:
\n\n\n

Replace with:
\n\n

Metot gövdesi başlangıcındaki boş satırdan…

Text to find:
\) \{\n\n

Replace with:
\) \{\n

Metot gövdesi sonundaki boş satırdan…

Text to find:
;\n\n    }

Replace with:
;\n    }