iOS Snapshot Test
Merhabalar, bugün iOS uygulamalarında yazılım geliştiriciler tarafından sıklıkla tercih edilen bir test çeşidi olan Snapshot testlerini tanıyacağız.
Snapshot testleri kabaca uygulamamızdaki ekranımızın bir ekran görüntüsünü alır ve bunu sonraki değişikliklerle karşılaştırmak amacıyla referans olarak kullanır. Böylelikle uygulamamızda beklenmedik bir UI değişikliği yaşanırsa bundan haberdar olmamızı sağlar.
Snapshot testlerinin en belirgin avantajları;
- Implementasyon kolaylığı.
- Uygulamamızdaki ekranların beklenildiği şekilde olduğunu manuel bir şekilde test etmek yerine Snapshot test yazarak kontrol ettiğimiz senaryoda elde ettiğimiz zaman tasarrufu.
Gelin şimdi örnek bir proje oluşturalım ve uygulamamıza Snapshot testleri ekleyelim.
Öncelikle Xcode’da projemizi oluşturalım ve Include Tests seçeneğini seçelim.
Bu projemizde Snapshot testleri kullanmak için bir kütüphane kullanacağız.
Cocoapods kullanarak projemize yukarıdaki kütüphaneyi ekleyelim.
Bunun için terminalden proje dizinine giderek pod init komutunu çalıştırıp Podfile oluşturalım.
Ardından oluşan Podfile’a girip yukarıdaki gibi ‘pod SnapshotTesting’ yazarak Podfile’ı kaydedip kapatalım. Ardından terminalde pod install komutunu çalıştırdığımızda kütüphanemizin başarıyla eklendiğini göreceğiz.
Artık SnapshotTesting kütüphanesini uygulamamıza eklediğimize göre hazırız :)
Örnek uygulamamız için kullanıcı adı ve şifre alanlarının olduğu basit bir kullanıcı giriş ekranı tasarladım.
Diyelim ki bu ekranımızın UI’ında gerçekleşebilecek değişiklerden haberdar olmak istiyoruz.Bu durumu karşılayan testlerimizi uygulamamıza ekleyelim.
Öncelikle test class’ımıza SnapshotTesting’i eklemek için import SnapshotTesting yazalım.
import XCTest
import SnapshotTesting
@testable import SnapshotTestExample
Ardından testLoginViewController isminde bir method ekleyelim.
final class LoginViewControllerTestClass: XCTestCase {
func testLoginViewController() {
let vc = LoginViewController()
assertSnapshot(matching: vc, as: .image)
}
}
Yukarıdaki kod bloğundaki assertSnapshot fonksiyonunda görebildiğiniz üzere 2 adet parametre bulunmakta.
- matching(matching value): referansla karşılaştıracağımız değer olarak ifade edilebilir.
- as: bu parametre aslında test edebileceğimiz farklı opsiyonları kabul eder.(image,json,dump,plist vb.)
Bu kısa açıklamadan sonra artık her şey tamam ve testimizi çalıştırabiliriz :)
Yazdığımız test failed oldu ve aşağıdaki hatayı verdi, peki neden?
Yazdığımız testLoginViewController() içindeki assert() fonksiyonu ilk defa çağrıldığı zaman snapshot otomatik olarak kaydedilir ve test fail olur. Yukarıda paylaştığım hata mesajında da bu kaydedilen referansın path’ini görebiliriz.
Proje dizininde hata mesajında gösterilen path’e gittiğimizde __Snapshots__ isimli bir klasör oluşturulduğunu ve onun içinde de “testLoginViewController.1.png” isminde bir png olduğunu görüyoruz.
İşte yukarıda bahsettiğim assert fonksiyonunun ilk çalıştığında kaydettiği ekran görüntüsü bu. Yani uygulamamızın mevcut ekranı :)
Testi ikinci kere çalıştırdığımızda bir hata almadığımızı göreceksiniz çünkü referans olarak kaydedilen snapshot image ile tekrar çalıştırdığımızda çektiği snapshot image’ları arasında bir fark yok. (Ekranımızda bir tasarım değişikliği yapmadık çünkü)
Günümüzde yazılım geliştiricilerin çoğu büyük ekiplerde çalışmakta ve bu yazılım geliştiricilerin çalıştığı “ekranlar” bazen aynı olabiliyor.
Varsayalım ki uygulamamızdaki bu giriş ekranında bir yazılımcı yanlışlıkla veya istemeden tasarımsal değişiklikler yaptı ve bunun olmasını istemiyoruz/beklemiyoruz.
Yeni ekranımızda görebileceğiniz üzere backgroundColor’ı .gray olarak güncelledik ve Giriş butonunun backgroundColor’ı ve Hoşgeldiniz label’ının textColor’ını .systemRed olarak güncellendik.
Haydi şimdi tekrar testimizi çalıştıralım ve sonucu birlikte inceleyelim.
Daha detaylı incelemek için “Show the Report Navigator” butonundan fail olan testimize geldiğimizde Attached Failure Diff kısmını görüyoruz.
Şimdi gelin bu Attached Failure kısmındaki 3 farklı image’a göz atalım.
Referans olarak gördüğümüz ekran görüntüsü aslında ilk kaydettiğimiz ekran, failure olarak gözüken ise yaptığımız yeni ekran. Difference kısmında ise aynı kalan yerlerimiz siyah ile ‘boyanmış’ değişiklik olan yerler ise yukarıdaki ekran görüntüsünde görülebiliyor.
Peki bu değişikliği istemeden değil de isteyerek yaptıysak ve artık yeni referans image’ımızın yeni güncellediğimiz tasarımımız olmasını istiyorsak ne yapmalıyız ?
Aşağıdaki gibi assert fonksiyonumuza record parametresini true olarak verdiğimiz zaman mevcut ekranımızı referans olarak kaydederiz.
Tekrar bir hata mesajı aldık ama bu sizi yanıltmasın. Mesajı okuduğumuz zaman record mode’un aktif olduğunu ve verilen dizinde yeni ekran görüntümüzün referans olarak kaydedildiğini anlıyoruz.
Record parametresini silip tekrar çalıştırdığımızda ise:
Testimiz başarılı oldu :) Vakit ayırıp okuduğunuz için teşekkür ederim.
Snapshot testler ile ilgili daha fazla içeriğe ulaşmak istiyorsanız aşağıdaki kaynaklara göz atabilirsiniz.