iOS’da Unit Test Yazmak (Bölüm 1)
Bu yazıda unit test yazımından ve bir iOS uygulamasında unit test nasıl yazılabileceğiyle ilgili bazı bilgiler paylaşacağım.
Gözlemlediğim kadarıyla test metodolojileri uygulamak her yazılımcının isteyip ama bir türlü gerçekleştiremediği bir durum olarak karşımıza çıkıyor. Bende bu süreçte kaynaklar okuyup bazı kurslar alıp yurtdışında ve yurtiçinde insanların test yazma bakış açılarını araştırmaya başladım ve bazı bulgular elde ettim. Aslında bu bölümde genel bir giriş yaparak Unit test ve Assertionlar(iddialar) için hangi metotlar kullanılır gibi konulara kısaca bir giriş yapmak istiyorum. Öncelikle neden kodumuza test yazmalıyız bunu konuşalım:
Öncelikle her teknoloji şirketi maliyetlerini en aza düşürmeyi hedefler ve bu süreçte belli düzenlemeler ve planlamalar yaparlar. Yazılımcılar olarak kod yazarken birçok hata ile karşılaşırız ve bu hataları bulmak için çok fazla zaman harcayabiliriz. Bir yeni özellik geliştirdiğimizde de herhangi bir test durumu yazmadan biz yazılımcılar tüm geri dönüş döngülerini kullanırız ve bu süreç boyunca aklımızda ‘Acaba bug var mı?’ ya da ‘Müşteri herhangi bir şikayet gönderecek midir?’ gibi sorular döner. Tabi ki bu da bildiğimiz gibi çok uzun süren bir döngü olarak aklımızda bulunur.
Günümüzde de bir problemi yerine ulaştırma ve geri dönüş alma sürecinin günlerimizi aldığı durumlar oluyor. Ve bu gibi problemleri engellemek için çoğu şirket manuel test’i tercih ediyor. Hepimiz biliyoruz ki bu işlemler de testçileri ve bizleri yorabiliyor ve bazen beklenmedik durumlarla karşılaşabiliyoruz. Hatta bu gibi durumlar crash’e bile sebep olabiliyor.Bu sebeplerden ötürü kafamızda sorular canlanıyor.
Bilgisayarlarımız büyük miktarda test yapabilseydi ne olurdu? ya da kendi bilgisayarımız bize direkt hata hakkında geri dönüş verse ne olurdu? Ve bu geri dönüş çok hızlı bir şekilde olsa ne olurdu? Bu sadece problemleri hızlıca yakalamakla kalmaz yazdığımız kodun kalitesini bile değiştirebilir. Aslında tüm bu soruların cevabı unit testler olarak sonuç buluyor. Hadi gelin biraz unit testler nedir ona bakalım.
Unit Test Nedir?
Burada aslında bir çok kavram üzerinde durabiliriz, tabi bazılarımız unit kısmına takılabilir, canlı kodun bir birimi olarak düşünülür.
John Reid’in kitabında da unit testleri açıklarken geri bildirim hızlı, tutarlı ve açık olarak tanımlarken otomatik testlerin bir alt kümesi olduğunu belirtmektedir.
Hızlı: Bir unit test mili saniye içinde tamamlanmalıdır. Çünkü biz binlerce test yazabiliriz.
Tutarlı: Verilen aynı kod ile unit test tarafında aynı sonuç raporunu vermelidir. Test çalışma sırası ve global durum farketmeksizin.
Açıklık: Bir hata yakalanırsa unit test bu hatayı hata olarak temiz bir şekilde rapor etmelidir.
Buraya kadar aslında unit test nedir ve neden unit test yazmalıyız kısmı kafamızda biraz canlanmıştır diye umuyorum. :)
Örneğimizde XCTest Framework kullanacağız. Öncelikle XCTest framework hakkında kısaca bilgi vermek gerekirse Xcode’un test iş akışıyla sorunsuz bir şekilde bütünleşen projelerimiz ile birlikte unit testi yazmak için XCTTest framework’ü projede import etmemiz gerekiyor. Daha sonra bu framework içerisinde çok kullanılan assertions’larından bahsedeceğim.
- Assertions ne için kullanılır?
- Assertions neleri rapor ederler?
- Doğru bir işte, doğru bir assertion’ı nasıl seçeriz?
sorularına cevap bulacağız.
Testler ile ilgili bir proje yaratalım:
Assertionslar , unit testlerine beklentilerini ifade etmek için bir yol sağlar. Eğer testler hata verirse bu beklentilerle tanımamış oluruz. Bu deneyleri yapabilmemiz için kendimize bir proje oluşturalım. Xcode menü, File > New > Project olarak include unit test ve StoryBoard seçeneği işaretli şekilde projeyi oluşturalım. Projenin ismine AssertUnitTestsExample
diyebiliriz.
Proje içinde AssertUnitTestsExampleTests
dosyası içindeki tüm methodları silebiliriz. Sadece boş bir sınıf(class) kalabilir.
Herhangi bir iOS simulatörü seçerek Product > Test ya da command + U
tuşlarına basarak testi çalıştırabilirsiniz. Burada herhangi bir hata görmeyeceğiz çünkü daha test kodunu yazmadık. Ama ekranında Test Succeeded olarak bir resim çıkacak.
Eğer bu yazıyı görmüyorsak Xcode preferences(Tercihler) oradan Behaviours tab’ından sol tarafta testing sekmesinden Notify using bezel or system notification seçeneğine tik atmamız gerekiyor. Hadi gelin ilk test assertion (iddiamızı) yazalım:
İlk olarak bu fonksiyon neler yapıyor ona bakalım:
- XCTestCase’in alt sınıfı olarak yarattık.
- Herhangi bir acccess control(private, public) ile yaratmadık.
- Metot’un ismi
test
olarak başladı. - Metot herhangi bir parametre almadı.
- Metot herhangi bir değer dönmedi.
Burada aslında genel araştırmalarım sonucu iyi bir test ismi üç bölüm içeriyor. test_input_expectedOutput şeklinde düşünebiliriz. Bu durumu ilerki bölümlerde de açıklayacağım. Ardında cmd + U
yaparsak testimizin hata verdiğini göreceğiz. Aşağıdaki görsel karşımıza çıkacaktır.
Burada da görmüş olduğumuz gibi eğer bir yerde hata var ise Xcode bunu bize hızlı bir şekilde göstermektedir. Ayrıca bu hatalara açıklama mesajları da ekleyebiliriz. Örnek olarak:
Test’i tekrar çalıştırdığımızda XCTFail’in içine yazdığımız yazıyı bize gösterecektir. Daha sonra testlerde koşullardan nasıl kurtulabiliriz bunları ele alalım. Test kodumuzu koşullara bağlı olarak değil de yine XCTTestCase’in bize sunduğu iddiaları kullanmak kodumuzu okumak açısından çok yararlı olacaktır.
Yukarıdaki kod parçacığından yola çıkarak ilk test assertion da koşullara bağlı olarak yazdık ekstra bir koşul geldiğinde bu olay bizim kodu okumamızı zorlaştıracaktır. 2. test assertion’da aynı sonucu veren bir test kodu yazdık. Daha sade ve okunabilir oldu.
Boolean değerleri yerine XCTAssertTrue() ve XCTAssertFalse() fonksiyonlarını kullanabiliriz. Bu durumda da bir çok koşuldan test kodumuz içerisinde kurtulmuş oluruz.
Eşitlik Testi
Şu ana kadar assertions’lar hakkında birkaç örnek denedik. Bunları genelde çıktı(output) olarak yaptık. Ama daha çok kullanacağımız assertion’dan bahsetmek isterim oda ‘gelen sonuç beklenen değere eşit’ mi kavramını nasıl ele alabiliriz?. Bir örnekle gösterelim:
Bu örnekte aslında actual olarak tanımladığımız değer XCTAssertEqual() ve genelde framework tarafında (expected, actual) olarak kullanılır. Ama aslında istediğimiz gibi yazabilir herhangi bir sıralama yapmasak da olur.
(“actual” eşit değildir “expected”) olarak görebiliriz. Diğer bir örneğimizi de eşitlik olarak verelim:
Yukarıdaki örneğimizde (“ilhan” eşittir “ilhan”) durumunu gördüğümüzde Xcode testin başarılı olduğunu bize gösterecektir. Aşağıya en çok kullanacağımız assertion fonksiyonların tablo olarak gösterimini koydum.
Sonuç
Elimden geldiğince size başlangıç olarak unit test nedir, bu iddialar günümüzde nasıl problemlerle karşımıza çıkıyor onları açıklamaya çalıştım. Son olarak anlattıklarımızı toplarsak maddesel olarak şu kavramlar ortaya çıkıyor:
- Metotların ismi
test
olarak başlar. - Metotlar herhangi bir parametre ve değer dönmüyor.
- Metotlar private değildir.
cmd + U
ile çalıştırabiliriz.- Olabildiğince test kodumuzu okunabilir ve basit tutmalıyız.
- Eğer hata alıyorsak bunu Xcode bize gösterecektir. Aksi halde testimiz başarılı olacaktır.
- Herhangi bir koşul veya özel bir hata içeriyorsa o assertion’a açıklama mesajı ekleyebiliriz.
Bir sonraki bölümde testin yaşam döngülerini yönetmek konusunu ele alacağız. Yazıyla ilgili varsa geri dönüşlerinizi bekliyorum.
Kaynaklar