Merhaba bu yazıda Golang ile unit testing işlemlerinin nasıl yapılacağını size aktarmaya çalışacağım. Çoğu programcı buna ben de dahil fail senaryolarını test etmeyiz. Kimimiz bunun bilincindeyiz kimimiz ise test işlemlerinin çalışan sistemde gerçekleştirilenden ibaret olduğunu düşünmekte.
Ancak fail senaryoları bazen çalışan sistemde yaşanacak yanlışlıkları henüz o türlü bir test aşamasına gelmeden önce engellememize yardımcı olabilir.
Profesyonel bir yazılımcısınız yani 10 yıllık geçmişiniz var ancak buna rağmen hatalarınız çıkabiliyor. Örneğin müşterilere belirli zaman aralıklarında SMS atan bir fonksiyonumuz var. Bu fonksiyona girilen telefon numarası minimum 7 karakter olmalı. Fakat bir müşterimiz 6 karakter girmiş. Haliyle SMS gönderilmiş olsa bile yanlış bir numaraya gitmiş olacak.
Bunun nedeni ise gerekli doğrulamayı gerçekleştirilen metodu belki de tam anlamıyla beklendiği gibi yazmayışımız.
Ne Yapmalıyım
Kedi arkadaşın dediği gibi unit testler ile mantıksal hataların önüne geçebileceğimiz bazı testler yazabiliriz.
Go Dilinin Varsayılan Olanağı
Bu yazının devamı olur mu bilmiyorum ama şu an için bu yazıda testing isimli modülü kullanacağız. Dosya isimlendirmesi ise şöyle olmalı. MUST
dosya.go
dosya_test.go
Ardından sms işlemlerini gerçekleştireceğimiz şöyle 2 dosya oluşturalım:
sms.go
sms_test.go
Buradan anlayacağımız şey test dosyaları mutlaka suffix olarak _test almalı. Hemen sms.go dosyası için basit bir doğrulayıcı metod yazalım:
func CheckPhone(phone string) bool { if len(phone) >= 7 { return true } else { return false } }
Yukarıda söylediğimiz senaryoya göre ilerliyoruz. Bu kodumuzun sms.go içerisinde olduğunu unutmayan hemen sms_test.go dosyası için de testimizi yazalım:
package sms import "testing" func TestCheckPhone(t *testing.T) { kontrol := CheckPhone("1234567") if kontrol { t.Log("Test başarılı") } else { t.Fatalf("Telefon karakter sayısı geçemedi", kontrol) } }
Burada vereceğiniz mesajlar testing modülünden geliyor ya da paket diyelim biz buna. Yukarıdaki kodda dikkat etmemiz gereken ilk şey öncelikle import "testing"
ifadesidir. Kısacası testing modülünü çağırdık.
Ancak buna rağmen eğer doğru isimlendirmeyiz yapmazsanız testleriniz go dili yorumlayıcısı tarafından bulunamayacaktır. Go programlama dilinde yazılan tüm testler Test prefix’i ile başlamalıdır. Yukarıda yazılı testi çalıştıralım. Test dosyalarını go run
parametreleri ile çalıştıramazsınız. Bunun yerine bulunduğunuz dizinde go test
ya da go test -v
parametrelerini verebilirsiniz. Her iki parametrenin de verdiği çıktıya göz atalım:
go test
--- FAIL: TestCheckPhone (0.00s)
sms_test.go:11: Telefon karakter sayısı geçemedi%!(EXTRA bool=false)
FAIL
exit status 1
FAIL _/home/ali/Projects/go/go_unit_test 0.001s
go test -v
=== RUN TestCheckPhone
--- FAIL: TestCheckPhone (0.00s)
sms_test.go:11: Telefon karakter sayısı geçemedi%!(EXTRA bool=false)
FAIL
exit status 1
FAIL _/home/ali/Projects/go/go_unit_test 0.001s
Farklı olan tek şey hangi test metodunun çalıştırıldığını da görebiliyor oluşumuz. Peki birden fazla test yazar mıyız? Elbette yazarız. Çoğu go projesi birden fazla dosyayı içerisinde barındırmaktadır. Örneğin email doğrulayan bir paketimiz daha olsun. Bu durumda yapımız şöyle değişiyor:
sms
--- sms.go
--- sms_test.go
email
--- email.go
--- email_test.go
Örneğin şöyle bir email doğrulama fonksiyonuna sahip olalım:
package email import "regexp" func CheckEmail(mail string) bool { match, _ := regexp.MatchString("[^@]+@[^@]+\\.[^@]+", mail) return match }
Bu fonksiyon girilen email adresinin doğruluğunu kontrol eder ve true ya da false sonuç döndürür. Mükemmel bir doğrulayıcı da değil bu arada bunu referans almayın. Şimdi bunun testini yazalım:
package email import "testing" func TestEmail(t *testing.T) { check := CheckEmail("ahmetin_maili~et~yokmail.com") if check { t.Log("Test başarılı") } else { t.Fatalf("Girilen mail adresi testi geçemedi") } }
Test için verdiğimiz komut satırı parametreleri biraz evrimleşecek ve şöyle olacak:
go test ./... -v
Bu tüm dizinleri dolaşıp orada yer alan test dosyalarını test edecektir. Bu parametreden sonra çıkan sonucumuz şöyle oluyor:
=== RUN TestEmail
--- FAIL: TestEmail (0.00s)
email_test.go:11: Girilen mail adresi testi geçemedi
FAIL
FAIL _/home/ali/Projects/go/go_unit_test/email 0.001s
=== RUN TestCheckPhone
--- PASS: TestCheckPhone (0.00s)
sms_test.go:9: Test başarılı
PASS
ok _/home/ali/Projects/go/go_unit_test/sms 0.001s
Evet bu yazıda kısaca go programlama dili ile bir unit test nasıl gerçekleştirilir onu görmüş olduk. Umarım faydalı olur.