İçeriğe geç
academia.sh

Ders 18 / 19

Mağaza Listelemesi

Kayıtlı ekran görüntüsüyle eşitliğe bakan denetimin, referans kusurlu derlemeden alındığında doğru sürümü kaldırıp kusurlu sürümü geçirdiğinin ve alt başlık sınırı denetiminin kusuru göremediğinin ölçümü.

Yayın Güncelleme

Bu derste

  • Mağaza listelemesinin iki parçasını, ekran görüntülerini ve alt başlığı, ayrı birer denetim konusu olarak ayırır
  • Kayıtlı referansla eşitlik denetiminin referans kusurlu derlemeden alındığında ters çalıştığını ölçer
  • Alt başlığın sınırı aşmadığına bakan denetimin iki sürümde de aynı yanıtı verdiğini doğrular
  • Referansı doğru derlemeden almanın ve içeriği doğrudan sınamanın ayrımı geri getirdiğini gösterir
İçindekiler

Mağazadaki uygulama sayfası, kullanıcının uygulamayı indirmeden önce gördüğü tek şeydir: birkaç ekran görüntüsü, bir ad, bir alt başlık ve bir açıklama. Bu parçalar uygulamanın kodundan ayrı tutulur, çoğunlukla geliştirici panelinden elle yüklenir ve bu yüzden kodun denetimlerinden geçmez. Sayfa ile uygulama arasında bir uyumsuzluk çıktığında bunu ilk fark eden, çoğu zaman bir kullanıcıdır.

Kursun ölçü adı ayrımdır. Doğru sürüme ve kusurlu sürüme aynı denetimi uygularız; denetim iki sürümü ayırıyorsa ayıran, ikisini de geçiriyorsa kör, ikisini de kaldırıyorsa gürültülü, doğruyu kaldırıp kusurluyu geçiriyorsa terstir. Çıktıda bu dört ad ayiran, kor, gurultulu ve ters olarak yazılır. Bu ders de aynı çekirdek dosyayla ölçer.

// Separation.swift — bir denetimin dogru surumu kusurlu surumden ayirip ayirmadigini siniflandirir
struct Contrast<Output: CustomStringConvertible> {
    let label: String
    let correct: Output
    let faulty: Output
    let passesCorrect: Bool
    let passesFaulty: Bool

    var separation: String {
        switch (passesCorrect, passesFaulty) {
        case (true, false): return "ayiran"
        case (true, true): return "kor"
        case (false, false): return "gurultulu"
        case (false, true): return "ters"
        }
    }

    func describe() -> String {
        let onCorrect = passesCorrect ? "gecti" : "kaldi"
        let onFaulty = passesFaulty ? "gecti" : "kaldi"
        print("\(label) | dogru=\(correct)/\(onCorrect) kusurlu=\(faulty)/\(onFaulty) -> \(separation)")
        return separation
    }
}

func contrast<Output>(_ label: String, correct: Output, faulty: Output, check: (Output) -> Bool) -> Contrast<Output> {
    Contrast(label: label, correct: correct, faulty: faulty, passesCorrect: check(correct), passesFaulty: check(faulty))
}

func countSeparations(_ results: [String]) {
    for name in ["ayiran", "kor", "gurultulu", "ters"] {
        print("\(name): \(results.filter { $0 == name }.count)")
    }
}

Bu dersin kusuru sayfanın ekran görüntüsündedir: ekran görüntüsü yeni arayüzü değil eskisini gösterir. Uygulama yenilenmiş, sayfa yenilenmemiştir. Kullanıcı eski bir arayüz görür, indirir ve bambaşka bir uygulamayla karşılaşır. Alt başlık ise iki sürümde de aynıdır ve dersin koyduğu sınırın içindedir.

Listelemenin Modeli

Model, bir derlemeden iki şey çıkarır: ekran görüntüsünün hangi arayüzü gösterdiği ve alt başlığın metni. listing(of:) bu ikisini bir Listing değerinde toplar; Listing kendini tek satırda özetler, böylece çıktıda ekranın ne gösterdiği ve alt başlığın kaç karakter olduğu görülür.

Üç denetim vardır. matchesReference ekran görüntüsünü kayıtlı bir referansla karşılaştırır; ekiplerin görüntü karşılaştırmasıyla yaptığı eşitlik denetiminin sadeleştirilmiş biçimidir. subtitleFits alt başlığın karakter sayısının sınırı aşmadığına bakar. showsNewInterface ise ekran görüntüsünün yeni arayüzü gösterdiğini doğrudan sınar.

// Listing.swift — derlemeden listeleme, uc denetim
struct Build {
    let interface: String
    let subtitle: String
}

struct Listing: CustomStringConvertible {
    let screenshot: String
    let subtitle: String

    var description: String {
        "ekran=\(screenshot) alt-baslik=\(subtitle.count)"
    }
}

func listing(of build: Build) -> Listing {
    Listing(screenshot: "ekran-\(build.interface)", subtitle: build.subtitle)
}

func matchesReference(_ listing: Listing, reference: String) -> Bool {
    listing.screenshot == reference
}

func subtitleFits(_ listing: Listing, limit: Int) -> Bool {
    listing.subtitle.count <= limit
}

func showsNewInterface(_ listing: Listing) -> Bool {
    listing.screenshot == "ekran-yeni"
}

let subtitleLimit = 30
let correctBuild = Build(interface: "yeni", subtitle: "Siparisleri tek yerde izleyin")
let faultyBuild = Build(interface: "eski", subtitle: "Siparisleri tek yerde izleyin")

DG16. Alt başlık sınırı otuz karakterdir. Bu sayı dersin kuralıdır; mağazanın gerçek sınırı ölçülmedi ve ölçülen hiçbir şey ona dayanmaz. Ders yalnız şunu sorar: sınırı aşmadığına bakan bir denetim, bu kusuru görüyor mu.

Üç Denetim

Referans, sayfaya ilk kez ekran görüntüsü yüklendiğinde kaydedilir. Kaydı alan kişi o gün elindeki derlemeden görüntü almıştır. Bu ölçümde o derleme kusurludur: ekran görüntüsü ekran-eski olarak kaydedilmiştir. Eşitlik denetimi bu kayda göre çalışır.

// main.swift — kayitli referansla esitlik, alt baslik sinirlari, dogrudan sinama
let correctListing = listing(of: correctBuild)
let faultyListing = listing(of: faultyBuild)
let recordedFromFaulty = faultyListing.screenshot

let equality = contrast("ekran-referansa-esit", correct: correctListing, faulty: faultyListing) { matchesReference($0, reference: recordedFromFaulty) }.describe()
let subtitle = contrast("alt-baslik-sinir-icinde", correct: correctListing, faulty: faultyListing) { subtitleFits($0, limit: subtitleLimit) }.describe()
let direct = contrast("ekran-yeni-arayuzu-gosteriyor", correct: correctListing, faulty: faultyListing) { showsNewInterface($0) }.describe()

countSeparations([equality, subtitle, direct])
ekran-referansa-esit | dogru=ekran=ekran-yeni alt-baslik=29/kaldi kusurlu=ekran=ekran-eski alt-baslik=29/gecti -> ters
alt-baslik-sinir-icinde | dogru=ekran=ekran-yeni alt-baslik=29/gecti kusurlu=ekran=ekran-eski alt-baslik=29/gecti -> kor
ekran-yeni-arayuzu-gosteriyor | dogru=ekran=ekran-yeni alt-baslik=29/gecti kusurlu=ekran=ekran-eski alt-baslik=29/kaldi -> ayiran
ayiran: 1
kor: 1
gurultulu: 0
ters: 1

Eşitlik denetimi ters çıktı. Doğru sürüm kayıtlı görüntüden farklıdır ve denetim kalır. Kusurlu sürüm kayıtla birebir aynıdır ve denetim geçer. Denetim kendi içinde doğru çalışıyor: iki şeyin eşit olup olmadığına bakıyor. Yanlış olan, neyle eşit olması gerektiğidir. Referans kusurlu bir derlemeden kaydedildiği için denetim, kusurun korunduğunu doğruluyor.

Bu, ters olmanın en sinsi biçimidir. Gürültülü bir madde kırmızıya döner ve dikkat çeker; kör bir madde sessizce geçer. Ters madde ise kusurlu sürümde yeşildir ve ekip bu yeşili bir uyarıdan çok bir onay olarak okur: sayfayı denetledik, kayıtla birebir aynı. Doğru sürüm geldiğinde ise denetim kırmızıya döner ve ekip yeni, doğru görüntüyü hatalı sayıp eski kaydı korumaya çalışabilir.

Alt başlık denetimi kör kaldı. Alt başlık iki sürümde de aynıdır ve sınırın içindedir; denetim doğru bir şey ölçer, ama bu kusurun alt başlıkla ilgisi yoktur. Doğrudan sınama ise ayıran çıktı: ekran görüntüsünün yeni arayüzü gösterdiği, referansa değil içeriğe bağlanmıştır.

Referans Nereden Gelir

Eşitlik denetimlerinin ortak zayıflığı budur. Denetim, referansın doğru olduğunu varsayar ve referansı doğrulayan bir şey yoktur. Referans alınırken derleme kusurluysa, eşitlik denetimi kusuru kilitler. Kayıt doğru derlemeden alınmışsa aynı denetim ayıran olur; ölçümün ikinci bölümünde bu görülecek.

Dört durum ayırt edilir. Referans doğru derlemeden alınmışsa denetim ayırır. Referans kusurlu derlemeden alınmışsa denetim ters çalışır. Referans hiç alınmamışsa denetim her iki sürümde de kalır ve gürültülüdür. Referans sürümler arasında güncellenmiyorsa, doğru bir yeni arayüz bile eski kayda karşı kalır; bu da bir tür ters davranıştır.

Ekipler bu zayıflığı genelde fark etmez, çünkü referansı alan kişi ile denetimi yazan kişi farklıdır. Birincisi görüntüyü yükleyip geçer, ikincisi görüntünün karşılaştırılacağı bir dosya bulur ve eşitliği yazar. Referansın nereden geldiğini kimse yazmaz.

DG17. Bu ders mağaza sayfasının arama görünürlüğünü, indirme oranını ya da kullanıcının sayfada ne okuduğunu ölçmedi. Ekran görüntüsünün ve alt başlığın kullanıcıyı ne kadar etkilediği bu dersin konusu değildir; ders yalnız sayfa ile uygulamanın uyuşup uyuşmadığına bakan denetimlerin ayrımını ölçer.

Ekran Görüntüsü Güncelleme Zamanı

Referans sorunu bir kez çözüldüğünde ikinci bir soru ortaya çıkar: arayüz her değiştiğinde referans da değişmelidir. Bu iki değişiklik çoğu zaman ayrı kişilerin elinde ve ayrı günlerde gerçekleşir. Arayüzü değiştiren kişi uygulamanın kodunu gönderir; sayfayı güncelleyecek kişi ise bunu duymadan eski görüntülerle yoluna devam eder.

Eşitlik denetimi bu ayrılığı yakalayabilir, ama yalnızca referans da güncellenmişse. Referans güncellenmeden yeni arayüz gönderildiğinde denetim yeni arayüzü kaldırır; ekip bu ters davranışı arayüzün bozulduğu biçiminde değil, referansı yenileme hatırlatması olarak okumalıdır. Bu okuma ayrı bir disiplin ister: kırmızı denetimin sebebi iki yerden biri olabilir, ya görüntü yanlıştır ya da referans eskidir. Hangisi olduğunu söylemek için denetimin yanında doğrudan bir sınama bulunmalıdır.

Doğrudan sınama bu yüzden iki yönlü bir kanıt sağlar. Eşitlik denetimi kırmızı, doğrudan sınama yeşilse sorun referanstadır. Eşitlik denetimi yeşil, doğrudan sınama kırmızıysa sorun, eşitlik denetiminin dayandığı kayıttadır. İkisi birlikte kırmızıysa sorun görüntünün kendisindedir. Tek bir denetim bu üç durumu ayıramaz.

Alt Başlığın Yeri

Alt başlık denetimi bu derste kör çıktı ve kör çıkması doğaldı. Yine de silinmesi gerekmez. Alt başlık sınırı gerçek bir kusura bakar: sınırı aşan bir alt başlık mağazanın karakter kuralını çiğner. Bu kusur bu derste yoktu, bu yüzden denetim ayıramadı.

Kör bir denetimi tutup tutmamak, onun kollamak için yazıldığı kusurun hâlâ olası olup olmadığına bağlıdır. Alt başlığı elle yazan bir ekipte olasıdır; başka bir dilden otomatik çevrilen bir alt başlıkta daha da olasıdır, çünkü çeviri çoğu zaman özgün metinden uzun çıkar. Kör denetim ancak kolladığı kusur artık hiç oluşamıyorsa gürültüye dönüşür.

Bu ayrım, kör ile gürültülünün farkını da açıklar. Kör denetim bugün işe yaramıyor, yarın yarayabilir. Gürültülü denetim ise bugün de yarın da aynı yanıtı verir ve hiçbir kusurla bağı kalmamıştır. Alt başlık denetimi bu ölçümde kördür; eski boyut gibi gürültülü değildir.

Geliştirici Paneli

Listeleme bilgileri uygulamanın deposunda değil, mağazanın geliştirici panelinde durur. Panelde her dil için bir ad, bir alt başlık, bir açıklama ve ekran görüntüsü kümeleri vardır. Ekipler çoğu zaman bu bilgilerin bir kopyasını depoda yapılandırma dosyası olarak tutar; böylece değişiklik bir inceleme geçer ve panele tek adımda taşınır.

# listing.yaml — panele tasinan listeleme yapilandirmasi (KAYNAK, olculmez)
language: tr
subtitle: Siparisleri tek yerde izleyin
screenshots:
  - file: screens/home.png
  - file: screens/orders.png
reference:
  recorded_from: ""

Bu yapılandırma ölçülmedi; bir yaml örneğidir ve dersin çalıştırdığı hiçbir şey ona dayanmaz. Önemli olan recorded_from alanıdır. Referansın hangi derlemeden alındığını yazmak, eşitlik denetiminin zayıflığını görünür kılar. Alan boş bırakıldığında, referansın kaynağı kayıt altında değildir ve kimse onu denetleyemez.

DG18. Geliştirici paneli bu derste bir düzyazı ve bir yapılandırma örneğiyle anlatıldı. Panelin gerçek alanları, sınırları ve yükleme adımları ölçülmedi; paneldeki her şeyin sayfayı nasıl etkilediği de ölçülmedi.

Sınırlayıcı Ölçüm

Bu kez referans doğru derlemeden alınır. Aynı eşitlik denetimi ve aynı iki sürümle ayrım geri gelir. Yanına referansın hiç kaydedilmediği durum ve iki sürümde de aynı kalan alt başlık denetimi konur.

// main.swift — referansin kaynagi degisince ayni denetimler
let correctListing = listing(of: correctBuild)
let faultyListing = listing(of: faultyBuild)
let recordedFromCorrect = correctListing.screenshot

let fromCorrect = contrast("referans-dogru-derlemeden", correct: correctListing, faulty: faultyListing) { matchesReference($0, reference: recordedFromCorrect) }.describe()
let missing = contrast("referans-hic-kaydedilmedi", correct: correctListing, faulty: faultyListing) { matchesReference($0, reference: "") }.describe()
let withinLimit = contrast("alt-baslik-otuzda-icinde", correct: correctListing, faulty: faultyListing) { subtitleFits($0, limit: subtitleLimit) }.describe()
let seesNew = contrast("ekran-yeni-arayuz-dogrudan", correct: correctListing, faulty: faultyListing) { showsNewInterface($0) }.describe()

countSeparations([fromCorrect, missing, withinLimit, seesNew])
referans-dogru-derlemeden | dogru=ekran=ekran-yeni alt-baslik=29/gecti kusurlu=ekran=ekran-eski alt-baslik=29/kaldi -> ayiran
referans-hic-kaydedilmedi | dogru=ekran=ekran-yeni alt-baslik=29/kaldi kusurlu=ekran=ekran-eski alt-baslik=29/kaldi -> gurultulu
alt-baslik-otuzda-icinde | dogru=ekran=ekran-yeni alt-baslik=29/gecti kusurlu=ekran=ekran-eski alt-baslik=29/gecti -> kor
ekran-yeni-arayuz-dogrudan | dogru=ekran=ekran-yeni alt-baslik=29/gecti kusurlu=ekran=ekran-eski alt-baslik=29/kaldi -> ayiran
ayiran: 2
kor: 1
gurultulu: 1
ters: 0

Referans doğru derlemeden alınınca eşitlik denetimi ayıran olur; denetimin kodu hiç değişmedi, yalnız kaydın kaynağı değişti. Referans yokken denetim iki sürümde de kalır ve gürültülüdür. Alt başlık denetimi yine kördür; sayfanın alt başlığı bu kusurun taşıyıcısı değildir. Doğrudan sınama referansa ihtiyaç duymadığı için iki ölçümde de ayırandır.

Sınırlar açıktır. Bu ders sayfanın arama sonuçlarında ne kadar göründüğünü ölçmedi. Alt başlığın karakter sınırı dersin kuralıdır, mağazanın kuralı değil. Geliştirici paneli ise yalnız bir yapılandırma örneği ve düzyazıyla anlatıldı. Ölçülen şey, listelemeyi denetleyen kodun kusuru ayırıp ayırmadığıdır; kullanıcının sayfada ne gördüğü ya da ne anladığı bu ölçümün dışındadır.

Referansı Doğrulamak

Referanslı bir eşitlik denetimi ancak referans doğrulanmışsa ayıran olur. Üç alışkanlık bunu sağlar. Birincisi, referansı kaydederken kaydın hangi derlemeden alındığını yazmaktır; yapılandırma örneğindeki recorded_from alanı bunun içindir. İkincisi, kaydı alan kişinin ekranı kendi gözüyle uygulamayla karşılaştırmasıdır; insan onayı yalnız o kaydı kapsar ve referans her yenilendiğinde yinelenir. Üçüncüsü, eşitlik denetiminin yanına referans gerektirmeyen bir doğrudan sınama koymaktır. Doğrudan sınama ile eşitlik denetimi birbirinden ayrışırsa, ikisinden biri yanlış referansa dayanıyor demektir.

Bu üçüncü alışkanlık dersin en az maliyetli çıkarımıdır. showsNewInterface ile matchesReference aynı iki sürüme uygulandığında farklı yanıt verdiler: biri ayırdı, diğeri tersine çalıştı. İki denetim arasındaki bu ayrılık, ölçüm olmadan da bir uyarıdır.

Kapanış Düşüncesi

Dersin başında listelemenin kodun denetimlerinden geçmediği söylendi. Ölçüm bunun bir bedeli olduğunu gösterdi: denetimi yazan kişi, denetimin neye karşı çalıştığını kendisi seçer ve bu seçim yanlış olabilir. Kod denetimlerinde doğru sürüm test girdisinde yazılıdır. Listelemede doğru sürüm bir görüntüdür ve görüntü bir kere kaydedildikten sonra kimse ona geri dönüp bakmaz.

Özet

  • Mağaza sayfası uygulamanın kodundan ayrı durur; bu yüzden kodun denetimleri sayfayı kapsamaz.
  • Kayıtlı referansla eşitlik denetimi, referans kusurlu derlemeden alındığında doğru sürümü kaldırıp kusurlu sürümü geçirir; yani ters çalışır.
  • Alt başlığın sınırı aşmadığına bakan denetim iki sürümde de aynı yanıtı verir; bu kusurda kördür.
  • Referans doğru derlemeden alınınca aynı eşitlik denetimi ayıran olur; referans hiç yoksa gürültülü olur.
  • Referansın kaynağını yazmak ve eşitlik denetiminin yanına doğrudan bir sınama koymak ayrımı geri getirir.
  • Bu dersin ayrımı: ters.

Sonraki Adım

Sayfa ve gönderim hazır olduğunda geriye bir soru kalır: yayına çıkan sürüm kullanıcıda çöktüğünde bunu nasıl öğrenirsiniz? Sonraki derste Çökme Raporlama ve Analitik ele alınacak; yalnız bir dil yapılandırmasında çöken kusurun toplam sayaçla ve yapılandırma başına sayaçla ayrılıp ayrılmadığı ölçülecek.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ ↵ Esc gezin · aç · kapat