Unit Test türleri neler ve hangileri işine yarar?

Orhun Begendi
7 min readJun 18, 2019

Merhabalar,

Serinin bu yazısında sizlere test türlerinden bahsedeceğim. Kapsamı daha doğru belirtmek için test türleri demek daha uygun olacak, yazı başlığındaki Unit Test kelime öbeğine takılmayın, öyle yazmamın temel sebebi “Test=Unit Test” şeklinde düşünen çok fazla kişi var. Bu yazı sayesinde aslında öyle bir durum olmadığını testing denilince çok geniş bir yelpazeden bahsettiğimizi anlayacaklar. Siz zaten bunu biliyorsanız daha da güzel! Ayrıca bahsedeceğim test türlerinden hangileri gerçekten işinize yarar sorusuna kendi kendinize karar verebilmeniz için kendi görüşlerimi paylaşacağım, çünkü tek tek anlatarak hangisi doğru olduğunu söylemem çok yanlış, buna sizin karar vermeniz gerekli!

“Unit Test nedir?” diye sormuştuk ve önceki yazımda bir cevap vermiştim, okumadıysanız serinin önceki yazılarını okumanızı tavsiye ederim.

Unit test ve test konseptleri çok karışan konular. “Unit Test” bir Unit’in test edilmesi demiştik. Unit ise tek bir işi yapan en küçük yazılım birimi demiştik. Test işlerinde biraz ilerlediyseniz, Unit Test’in tek başına yetmeyeceği ve denileni yapmak için ekstra efor sarf etmeniz gerektiğini ve bunun gerçekten gerekli olup olmadığını sorgulamaya başlamış olmanız lazım. Eğer öyleyse doğru yerdesiniz!

Serinin diğer yazıları için;

1- Unit test

2- Test için araç kutusu ve kullanım talimatları

3- Test yazarken bilmeniz gerekenler sıralı tam liste

4- Unit test türleri nelerdir ve hangileri işinize yarar? (bu yazı)

5- Moq’nun efektif kullanımı (yakında)

6- Unit test için design pattern’lar (yakında)

7- Testable architecture’a doğru (yakında)

8- Testable architecture (yakında)

9- Temel TDD (yakında)

10- Eski projelerinize yeni bir soluk TDD (yakında)

11- Advanced Unit Testing Teknikleri (yakında)

12- AspNet Core için Unit Testability (yakında)

İlk önce teori

Testing işlerinde teorik olarak her Unit’i her olasılık dahilinde test etmeliyiz. Uygulama büyüklüğüne göre belirli bir oranla integration testler ile uygulamalar arası iletişim test coverage altına alınmalı. GUI olan bir uygulama üzerinde UI testleri olmalı ve her olasılık için testler olmalı. Unit Test’ten daha üst katmanlara doğru ilerledikçe testlerin çalışma süreleri ciddi oranda artar ve test geliştirme süreleri daha da uzun sürer. Testlerin ürünü geliştiren developer’ın sorumluluğunda ise işlerimiz önemli ölçüde yavaşlaması söz konusudur.

Herkesin duyduğu şu meşhur test piramidine baktıktan sonra devam edelim.

Bu piramide göre Unit Test çok daha fazla yazılması gereken bir şey olduğunu ve olmazsa olmaz olduğunu düşünebilirsiniz. Bu sadece tek bakış açısından doğru hatta kısmen doğru. Şöyle ki sadece Unit Test yazarak kaliteli ve sağlam bir uygulama yazamazsınız. E o zaman Unit Test neden bu kadar abartılıyor? Yapacağınız işe göre Unit Test daha fazla ihtiyacınız olan bir şey olabilir ama olmaya da bilir. Nasıl yani diyebilirsiniz, şöyle temel bir açıklama yapayım; eğer Asp.Net framework’unu geliştiriyorsanız sadece unit testler yazmanız gerekecektir ancak günlük iş hayatımızda böyle şeyler geliştirmiyoruz, günlük çalışmalarımızdan üzerinden bir durum üzerinden konuşalım. Birçok ürünü birbirine entegre ettiğiniz bir ürün geliştirmesinde Unit Test çok anlam ifade etmiyor hatta entegre ettiğiniz ürünlerin test servisleri yoksa da ciddi sıkıntılar bizi bekliyor demektir. Bir SOAP servis kullanımı yapılan bir kodu unit test ile test etmek başlı başına zaten zor bir durum. Bu durumlarda bizim kalite ve test ihtiyaçlarımızı ağırlıklı olarak Integration Test çözecek.

Özetle yaptığımız işe göre ihtiyacımız olan test tipi fark edebiliyor. Bu ihtiyacı en iyi şekilde anlamalı ve daha sonra aksiyon almalıyız.

Test Sınıflandırması

Testleri genel olarak functional ve non-functional olarak sınıflandırabiliriz. Kısaca bakarsak;

Functional testing türleri:

  • Unit testing
  • Integration testing
  • System testing
  • Sanity testing
  • Smoke testing
  • Interface testing
  • Regression testing
  • Beta/Acceptance testing

Non-functional testing türleri:

  • Performance Testing
  • Load testing
  • Stress testing
  • Volume testing
  • Security testing
  • Compatibility testing
  • Install testing
  • Recovery testing
  • Reliability testing
  • Usability testing
  • Compliance testing
  • Localization testing

Bunlar dışında da size en az 30 türde test türü sayabilirim. Bu kadar çok tür olması anlamlı mı? Genelde anlamlı, çünkü hepsi ayrı bir ihtiyacı temsil ediyor. Özellikle functional testler kodlama açısından aynı şekilde yazılıyor, asıl ayraç yöntem ve yaklaşım oluyor. Functional test yazmaktaki asıl sorunun yattığı temel yer, “Test yazdık ama bu hangi tür?” sorunu oluyor. Bunların çizgilerini çok net belirlemek gerekli. Yoksa aldığınız test çalışma sonucu raporları(Test runner report) yeterli olmayacak. Test sonuçları gelince hata varsa bu sorun kod kaynaklı değilse bile developer’a söylemek gereksiz iş gücü kaybı olacak. Test yazmanın temel amacı ileriye dönük zaman kaybı olmaması ve otomasyon olması için yazıyoruz. Mantık daha çok şöyle olmalı, bir testte hata var ve bu test load testing’den oluyor. Olması gereken yükte doğru çalışmıyorsa burada burada sorun var demeniz kişi developer olmaması muhtemel, belki database belki de sistemciniz olabilir hatta belki de test datasında bir problem olabilir. Sadece bunlarla ilgilenecek ve durumu takip edecek QA ekibi vb. bir ekibe ihtiyacınız olacaktır. Firma büyüklüğüne göre bunları lead pozisyonunuzdaki arkadaşların yürütmesi gerekecektir.

En önemlisi unit test mi?

Her zaman en önemlisi en çok sayıda yazılması gereken Unit Test değil. Amaç yüksek yükte basit bir data sağlayan uygulamanın testleri daha fazla Integration Test ve Load Test içermesi daha mantıklı. Bir websiteniz varsa mesela Hesapkurdu.com gibi, burada API’lerin verdiği yanıtlar, entegrasyon yanıtları, sayfa yüklenme süreleri ve her sayfanın sorunsuz bir şekilde çalışabilmesi daha önemli olacak. Bizim ortamımızda çok fazla entegrasyon kodu ve datası var. Bizim durumumuzda Unit Test yapsak elde edeceğimiz avantaj daha az olacak dolayısıyla değerli saatlerimizi Unit Test’e odaklanmak yerine dataların doğru olmasına ve Integration Test’lere verdik.

Ben hangi türde test yazmalıyım?

Bu sistemin ihtiyaçlarına göre değişen bir konu. Örneğin milyonlarca hit alan bir API’niz varsa Load Test ihtiyacınız vardır. Eğer kullanıcı bilgisayarına kurulan bir dağıtım üretiyorsanız Install Testing sizin için gerekli. Biz genel olarak bir internet şirketi olduğumuz için hiç bir zaman Install Testing’e ihtiyaç duymuyoruz ve sadece Türkiye’de hizmet verdiğimiz için Localization Testing’lerimiz de yok. Eğer siz global bir şirket iseniz Localization test ihtiyacınız olabilir. Hangi türde test yazmalıyım konusunda temel mantığı bu şekilde basit işletmeniz gerekiyor hemen arkasından test hedeflerinizi koymanız gerekli. Ne kadar coverage olmalı, Load Test’in sınırı ne olmalı gibi konularda bir analiz yapıp bunu hedef olarak koymanız ve işleme öyle başlamanız gerekli. Yoksa günün sonunda biri bu testleri neden yazmadık diyebilir 🙂

Non functional testler bir anda çığrından çıkabiliyor. Non functiona testing mantığı hakkında bir kaç not düşmek istiyorum.

Uygulamanızda tüm functional test’ler hatasız çalıştıktan sonra non functional testing süreci başlamalı. Çünkü non functional testing’in mantığı zaten elinizde kusursuz çalışan bir uygulama olduğu varsayılarak bunu ekstrem koşullara tabi tutarak sizin için değerli olan metrikleri ölçmek.

Non functional testler çoğu zaman CI’ınızı yani sürecinizi durdurup bir soruna işaret etmesi için kullanılmıyor. Test sonuçları eski rapor sonuçlarıyla birleştirilip ne yöne doğru gidiyoruz diye takip amaçlı kullanımı daha yaygın. Load Testing’de ne kadar session kaldırabiliyoruz diye bir grafiğe bakmak gerçekten çok faydalı. Tabi bunları belirli threshold’lar(eşik değeri) ile yapmak daha doğru. Best practice olarak örneğin 10.000 anlık paralel request kaldırmak minimum zorunluluk olarak düşünüp, altına düşerse fail, yüksekse OK diyip devam edersiniz ve raporlarınızdan iyileşme var mı diye düzenli kontrol sağlamak en doğrusu olacaktır.

En önemlisi unit test ve integration test ayrımı

Unit Test ve Integration Test’leri birbirine en yakın iki tip diyebilrim. Bu iki testing tipini birbirine karıştıran çok oluyor. Unit Test’te en önemli nokta şu, herhangi bir 3rd Party bir yere dokunmadan sadece o methodu test etmeniz gerekli. Evet, Database de 3rd party bir ürün! Dolayısıyla data driven bir yapınız varsa Unit Test size aşırı anlamlı olmayabilir. Integration Test 3rd party ürünlerle çalışabilirliğini kontrol ettiğiniz testler, mesela Database’den data alıp onun üzerinde bir işlem yapıp dönüyorsanız bu Integration Test kapsamına girer. Database’den dataları çekip isim ve soyisimleri birleştirip dönen bir methodunuz varsa ve isimde ikisinin de olduğunu kontrol etmek de bir Integration Test. Bunu Unit Test ile yapmak için database’i mocklamalı ve test datası ile dönüş sağlamalı ve dönüşü kontrol etmelisiniz.

Biz ağırlıklı olarak hangisini yazıyoruz?

Çalıştığım firmada API-based bir sistemimiz olduğu için xUnit ile API’ye Http Request atıyoruz. Bunun dönüşlerinin istediğimiz datalara sahip olduğunu kontrol ediyoruz. Bunu API’ler için Integration Test yazarak yapıyoruz. Unit Test seviyesinde yaptığımız her şey Database’le yani gerçek datayla çalıştığı için bunlarda yazdığımız Unit Test’ler aslında Regression Test oluyor. Unit testi gerçekten yazduğımız bir kısım var o da hesaplama araçlarımız. Bizim sitemizde sizin çektiğiniz kredinin ödeme planları, faiz hesaplama vb. tüm konularda hesaplama işlemleri için Unit Test ile coverage altında tutuyoruz.

CI (Continous Integration) pipeline’larımızda da bulunan önemli bir adım olarak Smoke Testing yapıyoruz. Smoke testing bizim yüzlerce sayfamızı tarayarak HTTP OK görmeyi bekliyor. Burada bir hata varsa sayfa açılışımızda bir problem olduğunun farkına varıyoruz ve Production ortamına çıkmadan sayfa hatalarını yakalıyoruz. Sürekli yeni özellikler eklediğimiz için ve SEO için sitemizde her sayfanız çalışır durumda kalabilmesi önemli. Bu yapıyı destekleyen testing sistemimizle hatayı nokta atışı yakalayabiliyoruz ve zaman kaybetmeden sorunun temeliyle ilgilenip sorunu hızlıca çözebiliyoruz.

Beta/Acceptance test için manual olarak ürün yöneticilerimiz testlerini gerçekleştiriyorlar ve ürün istenildiği gibi geliştirildiğini teyit ediyorlar. Bu süreçleri project management tool’ları üzerinden yürüyoruz ve olası sorunları burada tespit ediyoruz.

System, stress testing gibi şeyler önceliğimiz değil çünkü AWS üzerinde çalıştığımız için cloud’un bize sağladığı avantajı kullanıyoruz ve çok yüksek yükleri bile stabil bir performans ile sunabiliyoruz.

Comparisan Testing konusunda Google’un A/B testing’ini kullanıyoruz. Bu şekilde yeni geliştirilen ürünün ya da özelliğin nasıl perform ettiğini öncekine göre karşılaştırmalı bir şekilde görebiliyoruz.

Bizim gibi firmalar için çok önemli olan konulardan biri Browser Test’lerini browserstack ile çözüyoruz. Bu bize bir farm kullanmamıza ihtiyaç kalmadan fiziksel tüm cihazları almadan test etmemizi sağlıyor. Tüm major web browser’larını bu şekilde sağlam bir şekilde desteklediğimizden emin oluyoruz.

Bunlarla beraber neye ihtiyacımız olduğunu çıkarttık. Bizim için performans önemli olduğu için Performance Testing ciddi bir önem taşıyor. Sayfaların açılış süresi bizim için çok önemli bir noktada duruyor. Bunu UI testlerle ilerletmek gibi bir amacımız var. UI testi için düşündüğümüz şeyler var, bunları da ilerleyen yazılarda aktaracağım.

Siz hangi türde testler yazıyorsunuz? LinkedIN, Twitter üzerinden veya bu yazı altında sizde paylaşın, konuşalım, tartışalım.

Saygılarımla.

--

--

Orhun Begendi

Senior Enginner, Tech Lead, Hardcore Developer, Software Craftsman.