Golang: Unit Test

Unit Test günümüz yazılım dünyasında artık olmazsa olmaz bir kural olarak bütün projelerde yazılması zorunlu hale gelmekte. DevOps açısından düşündüğümüzde Continuous Integration ve Continuous Deployment tool’ları yazmış olduğumuz kodları build edip deploy etmeden önce ilk olarak test metotlarını çalıştırır ve metotlardan herhangi biri fail verdiğinde deploy’u durdurabilir. Böylelikle unit test yazmak artık yazılım geliştirme dünyasında Nice to Have olmaktan çıkıp Is Must haline gelmektedir. 

Bir yazılım sistemindeki hataları (bug) bulmak birim testler ile mümkün değildir. Çünkü birim testlerin yaptığı iş yazılımın en küçük parçalarını kendi içerisinde test etmektir. Peki bu küçük parçaların kendi içlerinde çalışıyor olması, yazılımın gerçek kullanıcılar tarafından kullanılmaya başladığı zaman bir bütün olarak çalışacağını gösterir mi? Kesinlikle hayır. Bir yazılım sistemi, onu oluşturan parçaların toplamından çok daha fazlasıdır. Dolayısıyla bu bütünü test etmek için farklı yöntemler kullanmak gerekir. İşlevsel test (functional testing), bütünleştirme testi (integration testing) bunlara örnek verilebilir ancak konumuz birim test olduğu için bunlara değinmeyeceğim.

Golang de Unit Test

Neredeyse her programlama dilinin Unit Test yazılmasına yönelik imkanları vardır. Geliştirme IDE’lerinde pek çok kolaylık bulunmaktadır. Çoğu ortam zaten standart kütüphaneler veya paketlerler ile bizleri olabildiğince Unit Test yazmaya yönlendirir. GO tarafında bu iş için dahili paketlerden olan “testing” kullanılmakta. Pek tabii github üzerinden bulabileceğiniz farklı test paketleri de mevcut.

Öncelikle dosya isimlendirilmesi çok önemli: “proje.go” projemizi yazdığımız ve test etmek istediğimiz fonksiyonları barındıran dosyamızdır. Bunun yanında test dosyamızın adı da kesinlikle “proje_test.go” olmak zorunda.

Hemen bu adımlara basit bir örnek üzerinden devam edelim.

Yukarıda ki kod da iki tane fonksiyon bulunmaktadır. Birisi ipv4 kontrolü diğeri ise private ip kontrolünü yapmaktadır.

Test kodumuz da yukarıda ki gibidir. Dikkat edilmesi gereken husus *_test.go dosyalarında test fonksiyonları “Test*” ile başlamak zorunda. Son olarak klasör yapısı şu şekildedir.

.
├── ipvalid.go
└── ipvalid_test.go

Şimdi de yazdığımız testleri çalıştıralım. Bunun için “go test” daha detaylı bilgi için “go test -v” kodu aynı dizinde çalıştırılır.

-race parametresi de önemli.
Örneğin testlerinizde goroutine kullanıyorsunuz ve bu rutinlerin aynı anda aynı memory alanına erişip erişmediğini -race parametresi ile öğrenebiliyorsunuz, aklınızda bulunsun.

“go test ./… -v” Bu komut ise bütün dizileri dolaşarak test fonksiyonlarını tek tek çalıştırmaktadır.

$ go test -v
=== RUN TestPrivateIP
— PASS: TestPrivateIP (0.00s)
=== RUN TestValidIP4
— FAIL: TestValidIP4 (0.00s)
ipvalid_test.go:14: false
FAIL
exit status 1
FAIL icssight/golang-test 0.003s

Test çalıştırıldıktan sonra çıktımız yukarıda ki gibi olmaktadır. Sonuca göre birinci test pas, ikinci test fail almış bulunmaktadır.

Vs Code’da yazılan testleri direkt çalıştırabilirsiniz.

Testlerin Kontrolü

Büyük çaplı projelerde çok fazla miktarda fonksiyon dolayısıyla unit test yazmak gereklidir ve bu testleri tek bir noktadan ve sürekli kontrol edilebilmesi çok önemlidir. Bunun için https://github.com/smartystreets/goconvey projesi kullanılabilir. Kurulum için aşağıdaki adımların yapılması gerekmektedir. Daha sonra “http://localhost:8080/” adresinden tarayıcı üzerinden bütün testlerin kontrolü sağlanmaktadır.

Aşağıda görüldüğü gibi “Goconvey” ile testler çok kolay bir şekilde takip edilebiliyor. Değişiklikler anında yansımaktadır.

Bir sonraki yazıda görüşmek üzere. Kod parçalarına buradan erişebilirsiniz.

Leave a Reply