.Net Core İle Unit Test 2
İlk serimizde Unit Test nedir, avantajları nelerdir, alternatifleri nelerdir ve ilk adımlarını sizlerle paylaşmıştım. Bu yazımızda ise Unit Test yazmaya başlayacağız.
Bir unit test yazmak 3 aşamada oluşmaktadır. Yani bir uygulama içerisindeki bir metodu test etmek istiyorsanız 3 aşamayı uygulamak zorundasınız. Bu aşamalar; Arrange, Act, Assert..
Öncelikle App projemizde Calculator isminda bir class oluşturalım. Erişim belirleyicisi olarak publi yapalım. Methodumuz add işlemi yapan ve int dönen bir metot olsun.
Test projemizde ise aynı şekilde CelculatorTest adında bir class oluşturalım. Bu class içinde AddTest isminde bir methodumuz olsun. Hatırlarsanız yazımızın başında test in 3 aşamadan meydana geldiğinden bahsetmiştik. Tanımlama, Atama ve Sonuç gibi düşünelim. Son olarak Test metodu olduğunu belirtmek için Fact Attr ekleyelim. Burda önemli olan nokta eğer method değer almıyorsa Fact Attr kullanılır. Değer alan method lar için farklı Attr ler kullanılmaktadır. Onları aşağıda bahsediyor olacağım.
Şimdi gelin uygulamayı derleyelim ve test explorer dan testimizi çalıştıralım.
Görüldüğü üzere testimiz başarılı olarak çalışmıştır.
En Çok Kullanılan Assert Methodları nelerdir ?
Assert iki değer alır bu değerlerde verilen methoda göre işlemi kontrol eder. İlk parametre verdiğimiz değer ikinci parametre ise dönen sonuç.
Contains => Verilen değerin sonuç değer içerisinde bulunmasını bekler
DoesNotContain => Verilen değerin sonuç değer içerisinde bulunmamasını bekler.
1.Örnek
Tabi bu örnekte normal bir string ifade içerip içermediğini kontrol ettik. Birde IEnumerable bir data içerisinde kontrol edelim.
kullanım şekilleri mevcuttur.
2.Örnek
True/False Methodları
Assert.True => içerisindeki şartı sağlıyorsa başarılıdır.
Assert.False => içerisindeki şartı sağlamıyorsa başarılıdır.
3.Örnek
Matches / DoesNotMatch
Regex ifadesi alır. bu ifade üzerinde beklediğimiz değer dönüyorsa başarılı veya başarısız olarak döner.
4.Örnek
StartsWith / EndWith
İlk kelimesi ve son kelimesine bakar.
5.Örnek
Empty/NotEmpty
Aldığı dizinin boş veya boş olmamasını kontrol eder.
6.Örnek
InRange / NotInRange
Belirtilen değer ilgili değer arasındaysa veya değilse testin true veya false olmasını belirler.
7.Örnek
Single => İçerisinde vermiş olduğumuz array/dizinin bir eleman gelmesini bekler.
8.Örnek
IsType / IsNotType
Tip kontrolü yapar. Generictir tipin doğru olup olmadığını gerçekleştirir.
9.Örnek
IsAssignableFrom
Bir tipin bir tipe referans verip veremeyeceğini kontrol eder.
10.Örnek
Null / NotNull
İçerideki ifade null veya null değilse true veya false döner.
11.Örnek
Equal / NotEqual
Adı üstünde iki değeri karşılaştırmak için kullanılıyor. Eğer iki değer aynıysa true veya false döner.
Test Methodlarımızı Parametre Alma Durumları
[Fact]
[Theory]
[InlineData](param-1, param-2, param-3)
Hatırlarsanız Test method umuzu yazarken Attr olarak Fact Attr kullanmıştır. Fact Attr aynı zamanda ikinci bir anlamı vardır. İlki test methodu olduğunu belirtmek için ikincisi de ilgili metodun parametre almama durumunda Fact Attr kullanmış oluyoruz.
Peki test methodumuz parametre alırsa o halde [Theory] Attr kullanırız. Theory Attr parametre almak zorundadır. Peki ilgili parametreleri method a nasıl geçeceğiz derseniz. Orada ise ikinci bir Attr olan [InlineData] Attr kullanabiliriz. Şimdi bir örnek yapalım.
AddTest2 methodumuzda ilgili Attr lerimizi ekledik. 3 parametre aldığını söyledik. Calculator class ımızın altında add metodumuzla toplama işlemini gerçekleştirip Equal ile değeri karşılaştırıyoruz.
Eğer testin farklı değerlerle iki kere çalışmasını istiyorsak InlineData Attr çoğaltabiliriz.
Testlerimizi yazarken InlineData ile yazmak test methodumuz çok fazla ise best practises açısından InlineData ile göndermek daha mantıklıdır.
Test Class Constructor Method Kullanma
Örneklerimizi yazarken AddTest ve AddTest2 şeklinde iki method umuz vardı. Biri parametre alıyor diğeri ise almıyordu. Burda dikkat ederseniz Calculator nesne örneğini iki method da alıyor. (new Calculator)
Bu best practises açısından uygun değil. Bunu gelin Tüm methodlarımız da kullanacağımız bir prop oluşturup ardından constructor tanımlayalım.
Gördüğünüz gibi yukarıda tanımladığımız ctor ımızı aşağıda kullanabiliyoruz. Bir class içerisinde farklı ortak sınıflarımız varsa ilgili ctor içerisinde nesne örneğini yazarak aşağıda çağırabilirsiniz.
Test Method İsimlendirme
isimlendirme yaparken aslında kullanım şekilleri belli bir kalıba göre olmalıdır.
Kalıp=> [MethodName_StateUnderTest_ExpectedBehavior]
Örnek=> add_simpleValues_returnTotalValue
Örnek=> IndexReturnsARedirectToIndexHomeWhenIdIsNull gibi olmalıdır. Aslında method ismini tek bir bakışta testin ne olduğunu anlatmalıdır. O yüzden açıklayıcı olmalıdır. İnternette bununla ilgili birçok best practies bulunmaktadır. En çok kullanılan isimlendirme tarzından bahsedecek olursam 3 parçaya bölüyoruz ve bunları alt tire ile ayırıyor olacağız. İlk başta test edeceğimiz metodu yazıyoruz. Bizim örnek yazdığımız kodda method umuzun ismi neydi ? add di ilk değer add olacak o halde sonrasında add methodunda biz neyi test ediyoruz basit değerler gönderiyorum. Sonuçta çok basit bir metot a + b toplama yapan bir metot sonrasında test sonucunda nasıl bir davranış bekliyorsak onu ifade ediyoruz. Biz napıyoruz Hesaplanmış toplam değeri alıyoruz. Bu şekilde kolay bir şekilde anlayabiliriz. Farklı bir senaryo örneğini yapalım.
Hatırlarsanız add metodumuz bizim sadece toplama işlemini yaparak dönüş sağlıyordu artık iki kontrol yapmış bulunmakta. İlkinde a veya b ye 0 verdiğimizde 0 almamız lazım bu beklediğimiz bir davranış ikinci bir davranış ise a veya b 0 olmadığı zaman toplam değeri verme durumu. Şimdi gelin bununla ilgili testi yazalım.
Büyük projelerde adaptasyonun hızlı sonuçlanmasında UnitTest önemli bir rol oynamaktadır.