UNIT TEST
Birim test, bir yazılımın en küçük parçasının (metod, fonksiyon) tek başına test edilmesidir. Birim test yazılım testinin ilk seviyesidir. Genelde yazılım geliştiriciler tarafından yapılan Beyaz Kutu (White Box) testidir. Birim test sonucunda bulunan bulgular yazılım geliştirici tarafından düzeltilir. Birim test temel olarak belirlenen girdiler ile kod bloğunun çalışabilirliğini kontrol eder. Birim testin başarılı sonuç vermesi, son kullanıcıların kullanımı sırasında sistemde hata olmayacağı anlamına gelmez. Birim test sadece belirtilen metod ya da fonksiyonun sorunsuz çalıştığını test eder. Birim testin asıl amacı; ilk aşamada birimlerin doğru çalıştığını doğrulamaktadır. Birim test yazılım geliştiriciyi aynı zamanda kaliteli ve bakımı kolay kod yazmaya teşvik etmektir.
BİRİM TEST AVANTAJLARI
- Test edilecek kod bloğu yazılmadan birim test yazılabilir. Bu sayede temiz kod yazılır ve kodun kalitesi artar. Bu durum Test Odaklı Geliştirme(Test-Driven Development) olarak isimlendirilmektedir. Test Odaklı Geliştirme ile hemen hemen tüm kod blokları test edilir.
- Kodda yapılan değişiklikler sonrasında hata tespiti, birim test ile çok hızlı yapılır. Tespitler sonucu yazılım geliştirici kodda düzenleme yapar.
- Test birimlerini bir kez oluşturduktan sonra testler, otomatik koşturulur.
- İlk başta test metodlarını yazmak zaman kaybı gibi görünür. Ancak yeni kod parçaları sisteme eklendikçe testin zaman tasarrufu sağladığı görülür.
- Kodun doğru çalışabilirliği yazılım aşamasında test edildiği için sistemin maliyetini azaltır.
BİRİM TEST YAPISI
- ÖN KOŞUL (GIVEN): Gerekli ortamın hazırlanması, objenin istenen state getirilmesidir. Örneğin: Bir kredi kartı borç ödeme sistemi düşünüldüğünde burada oluşması beklenen ortam, kredi kartından harcama yapılarak borçlu (eksiye) durumuna düşmesi.
- AKSİYON (WHEN): Senaryonun tetiklenmesi, objenin gerekli aksiyonu almasıdır. Örneğin: Kredi kartı borcu ödeme işlemi için ödeme metodu tetiklenmelidir.
- SONUÇ (THEN):Test edilen objenin, yeni durumudur. Örneğin: Ödeme metodu çalıştırıldıktan sonra objenin durumu ödendi olarak güncellenmelidir.
BİRİM TEST NASIL YAZILIR?
Geliştirilecek yazılımdan önce birim testlerin yazılması beklenmektedir. Çünkü yazılımdan ne bekleniyor ve hangi durumlarda nasıl çalışılması gerektiği belirlenmelidir. Bu sebeple birim test yazarken uyulması gereken bazı kurallar vardır.
- Yazılımın en küçük parçacığı test edilmelidir.
- Test metodunun içeriği belirli bir sıraya göre yazılmalıdır. (Örneğin;Given, When, Then)
- Tek seferde sadece bir senaryo test edilmelidir.
- Test metod ismi, test edilen senaryoyu yansıtmalıdır.
- Test edilen metod diğer metodlardan bağımsız çalışabilmelidir.
- Testler tam otomatik şekilde çalışmalıdır.
- Hızlı çalışabilmeli ve çabuk sonuçlar vermelidir.
- Okunaklı, anlaşılabilir ve sürdürülebilir olmalıdır.
- Test başarısız olduğunda durmalı ve anlaşılır bir hata raporu döndürülmelidir.
- Her zaman aynı sonuç çıkmalıdır.
- Birim test yalnızca public metodlar için yazılmalıdır. Private metodlar ilgili public metodlardan çağrıldıkları için dolaylı olarak test edilmiş olurlar. Private metodlar için bunun dışında test metodu yazılmasına gerek yoktur.
- Bir metod da mevcut sınıf dışından, örneğin bir servisten veri alınması gereken durumlar olabilir.Bu durumda servisten çekilen veri değiştiği zaman testin sonucu da değişecektir. Bu durumun önüne geçmek için taklit (mock) objeler kullanılmaktadır. Metoda veri sağlayan servisin aynısı local ortamda oluşturulup her seferinde aynı veri çekilmesi sağlanmalıdır.Her test için bir tek mock obje kullanılmalıdır.
Birim test yazarken sıklıkla kullanılan Framework’ler;
- JUnit
- Xunit
- MbUnit
- NUnit
- TestNG
- MSTest
- Mocha
Örnek birim test metodları Junit5 framework ile yazılacaktır.
JUNİT 5
Junit5, Java dilinde uygulamalarımızı test etmek için kullanabileceğimiz açık kaynak kodlu bir test framework üdür. Junit 5, Java 8 ve sonrası sürümleri desteklemektedir.
Junit5 kurulumu için, Junit5 kütüphanesi pom.xml dosyasına dependency olarak eklenir.
JUNİT 5 ANNOTATION LARI NELERDİR?
Sıklıkla kullanılan Junit annotationları;
- @Test : Metodun test edileceğini gösterir ve içerisinde test adımları yer alır. Bu tür metodlar, geçersiz kılınmadıkları sürece bir önceki sürümden miras alınır.
Şekil 1. Test Annotation
- @ParameterizedTest : Bir testin farklı argümanlarla birden fazla çalıştırılacağını, parametreleştirilmiş bir test olduğunu belirtir. Bu tür metodlar, geçersiz kılınmadıkları sürece bir önceki sürümden miras alınır.
Şekil 2. ParameterizedTest Annotation
- @RepeatedTest : Bir metodun, tekrarlanan bir test için bir test şablonu olduğunu belirtir. Bu tür metodlar, geçersiz kılınmadıkları sürece bir önceki sürümden miras alınır.
Şekil 3. RepearedTest Annotation
- @DisplayName : Test sınıfı veya test metodu için özel bir, görünen ad belirtilir.
Şekil 4. DisplayName Annotation
- @BeforeEach : Metodun tüm test metodlarından önce çalıştırılacağını belirtir. (daha önce @Before)
Şekil 5. BeforeEach Annotation
- @AfterEach : Metodun tüm test metodlarından sonra çalıştırılacağını belirtir. (daha önce @After)
Şekil 6. AfterEach Annotation
- BeforeAll : Metodun geçerli sınıftaki tüm test metodlarından önce çalıştırılacağını belirtir. (daha önce @BeforeClass)
Şekil 7. BeforeAll Annotation
- @AfterAll : Metodun geçerli sınıftaki tüm test metodlarından sonra çalıştırılacağını belirtir. (daha önce @AfterClass)
Şekil 8. AfterAll Annotation
- @Disabled : Bir test sınıfını veya metodunu devre dışı bırakmak için kullanılır. (daha önce @Ignore)
Şekil 9. Disabled Annotation
- @Tag : Sınıf veya metod düzeyinde filtreleme testleri için etiket bildirmek için kullanılır.
Şekil 10. Tag Annotation
JUNIT ASSERTION KULLANIMI
Test edilen fonksiyonların döndüğü değerlere göre sonucu belirleyen assertion lar vardır.
Junit framework de sekiz adet assertions tipi vardır. Bunlar;
- Assert.assertEquals
assertEquals , beklenen sonucu gerçek sonuç ile karşılaştırmak için kullanılır. Beklenen sonuç ile gerçek sonuç eşit değil ise gerçekleştirilen test senaryosu sonucunda assertionError hatası fırlatır. - Assert.assertTrue
assertTrue, beklenen bir sonucun true olduğunun doğrulanması gerektiği zaman kullanılır. - Assert.assertFalse
assertFalse, beklenen bir sonucun false olması doğrulanması gerektiği durumda kullanılır.
- Assert.assertNull
assertNull, beklenen bir sonucun null olup olmadığının kontrol edilmesi için kullanılır. Bir objeyi parametre olarak alır ve obje null değil ise assertionError hatası fırlatır.
- Assert.assertNotNull
assertNotNull, beklenen bir sonucun null olmadığını doğrulamak için kullanılır. Bir objeyi parametre olarak alır ve obje null ise assertionError hatası fırlatır. - Assert.assertSame
assertSame, parametre olarak verilen iki nesnenin aynı nesneye karşılık gelip gelmediğini kontrol eder. Eğer objeler aynı değil ise assertionError hatası fırlatır.
- Assert.assertNotSame
assertNotSame, parametre olarak verilen iki objenin birbirine eşit olmadığı kontrolünü sağlar. Eğer aynı objeye karşılık geliyor ise assertionError hatası fırlatır.
- Assert.assertArrayEquals
assertArrayEquals, parametre olarak verilen iki dizinin eşit olup olmadığını kontrol eder. Her iki dizi içinde null değeri var ise bunlar eşit olarak kabul edilir. Eğer eşit değil ise assertionError hatası fırlatır.
Örnek Birim Test:
Junit5 framework’ü maven projesinde kullanabilmek için pom.xml dosyasına dependency bilgileri eklenerek kullanılabilir. Bir diğer yöntem olarak, Junit5 web sitesinden indirilen jar dosyaları projeye eklenerek kullanılabilir. Bunun dışında farklı bir build otomasyon aracı kullanılacaksa https://github.com/junit-team/junit5/wiki adresinden gerekli bilgilere ulaşılabilir.
Junit5 web sitesi ve github adresi;
https://github.com/junit-team/junit5
İlk olarak Intellij IDE kullanılarak bir maven projesi oluşturulur. Junit5 kütüphanesi pom.xml dosyasına dependency olarak eklenir.
Şekil 11. JUNIT Örnek-pom.xml dosyası
src/test altında TestToplamHesapla isimli yeni class oluşturulur. Class içerisine Junit5 kullanılarak test metodu yazılır. Her test metodun başına @Test annotation eklenmelidir. Testi yazılan metodun sınıfı daha sonra oluşturulacaktır.
Şekil 12. JUNIT Örnek-Test Metodu
src/main altında Toplama isimli yeni class oluşturulur. Sınıf ve metod tanımlamaları yapılır.
Şekil 13. JUNIT Örnek-Test Edilecek Metod
Yukarıdaki örnekte, topIslem metodu ile basit bir toplama işlemi yapılmıştır.
Yukarıdaki metodda assertion kullanımı da gösterilmiştir. Assertion, oluşan sonuç ile oluşması beklenen sonucun karşılaştırılmasıdır. Örnekte (Assert.assertEquals (sonuc,9);) oluşan sonuç, 1. Parametreye eklenmiştir. Toplama işlemi sonrası oluşması beklenen sonuç 2. Parametreye eklenmiştir. Parametre 1=sonuc, Parametre 2=9 dur.
Şekil 14. JUNIT Örnek-Sonuç Çıktısı
Tek test metodu olduğu için çalıştırılacak metodun üzerinde sağ tık / Run Focused Test Method seçilmelidir. Test sınıfı içerisindeki tüm metodları çalıştırmak için sınıfın üzerinde sağ tık/ Run File seçilir.
Test metodu çalıştırıldığında, Assertion içerisinde belirtilen şart doğru karşılanırsa ekranda sonuç çıktısı görülür.
Junit5 Test Suite
Birden fazla Test sınıfını aynı anda tetiklemek için Suit sınıf yazılmalıdır. Suit sınıfı junit.platform.runner dependency pom.xml içerisine eklenmelidir.
Şekil 15. JUNIT5 Test Suite Dependency
SelectedClasses içerisine yazılan test sınıfları, yazıldıkları sıraya göre tetiklenmektedir.
Şekil 16. JUNIT5 Test Suite Ornek
KAYNAKÇA
- https://medium.com/@bi4code/birim-test-unit-testing-688a8a6329af
- https://medium.com/@cengizhandumlu.35/unit-testing-nedir-ve-nas%C4%B1l-yaz%C4%B1l%C4%B1r-446073767e60#:~:text=Unit%20Test%2C%20bir%20yaz%C4%B1l%C4%B1m%C4%B1n%20en,geli%C5%9Ftiriciler%20kendileri%20yazar%20ve%20y%C3%BCr%C3%BCt%C3%BCrler.
- https://www.it-swarm.dev/tr/java/junit-fiksturu-neden-statik-olmali/967214413/
- https://www.mobilhanem.com/junit-assertions-kullanimi-ve-sik-kullanilan-assertionlar/
- https://devqa.io/junit-5-annotations/
- https://junit.org/junit5/docs/current/user-guide/
Sinem AKTAŞ