Density, Devices and Flaky Tests

Kaan Enes KAPICI
IBTech
Published in
3 min readMar 17, 2023
Android Developers

Compose’da özel bir layout yazmak, uygulamanızın kullanıcı arayüzünün görünümüne ince ayar yapmanın harika bir yoludur ve göründüğü kadar göz korkutucu değildir. Özel mantığınızı yazdıktan sonra, bunun için testler de yazmalısınız! Bununla birlikte, bu testleri yazarken, çalıştırdığınız cihaza bağlı olarak, bu testlerin bazı garip davranışlarını bazen başarılı bazen başarısız olduğunu keşfedebilirsiniz.

Bir Compose Layout davranışını doğrulamak için basit (fakat flaky!) bir testi analiz etmeye başlayalım:

Flaky test, kaynak kodunda veya yürütme ortamında değişiklik olmasa bile başarılı veya başarısız gibi farklı sonuçlar sağlayan bir testtir

Bu testin amacı, her biri 10dp yüksekliğinde 6 Spacer içeren bir Column yapısının 60dp yüksekliğinde olup olmadığını kontrol etmektir.

Column koordinatları yerleşimini doğrulamak için Modifier.onPlaced ile alınır ve cihazın ekranının yoğunluğu da benzer şekilde LocalDensity.current’dan alınır.

Ortaya çıkan koordinatlar bir tam sayı piksel cinsinden ifade edilir, dolayısıyla beklenen 60dp’mizi, roundToPx() ile bir tamsayıya yuvarlamak için yoğunluğu kullanarak piksellere dönüştürürüz.

Tüm bu adımlar yeterince zararsız görünüyor, o yüzden testi yapalım. Başarı… ya da belki başarısızlık. Testi yaptığımız cihaza bağlı olarak bu test başarılı olabilir veya olmayabilir. Neler olduğuna daha yakından bakalım.

px vs dp vs sp

Farklı cihazların farklı fiziksel ekranları vardır (ve bazılarında birden fazla olabilir), bu da hem farklı fiziksel ekran boyutlarına hem de farklı ekran yoğunluklarına sahip olabilecekleri anlamına gelir. Birçok cihazda, kullanıcılar bir “Ekran boyutu” seçeneğini kullanarak etkin görüntü yoğunluğunu kendileri de değiştirebilir.

Bir tablette “Ekran” altındaki “Ekran boyutu” ayarı

Kullanıcı arayüzünün farklı cihazlarda tutarlı görünen bir boyuta sahip olduğundan emin olmak için yoğunluktan bağımsız pikseller veya dp kullanarak genel UI bileşenlerinin boyutlarını belirtmelisiniz. Metin için, kullanıcının tercih ettiği metin boyutunu hesaba katan ölçeklenebilir pikseller veya sp kullanmalısınız.

Jetpack Compose, bir Density nesnesi kullanarak dp ile alttaki pikseller arasına dönüştürme yöntemleri ekleyen yerleşik bir Dp türüne ve ilgili yöntemlere sahiptir.

Bu Density nesnesi (bir @Composable işlevinde LocalDensity.current ile alınabilir), kullanıcı arabiriminin üzerinde çalıştığı cihaz tarafından belirlenir. Density.density, dp değerlerine uygulanan değişken ölçeklendirme faktörüdür. 1.0'lık bir Density.density faktörü, 1dp’nin 1 piksele dönüştürüleceği anlamına gelirken, 2.0 olan bir Density.density faktörü, 1dp’nin 2 piksele dönüştürüleceği anlamına gelir.

Bazı gerçekçi değerler için: Pixel Watch’ın varsayılan density faktörü 2,0, Pixel 7 Pro’nun varsayılan density faktörü 2,625 ve 4K Android TV’nin varsayılan density faktörü 4,0'dır.

Density : Yoğunluk

Step-by-step layout

Bu bilgiyi göz önünde bulundurarak, testteki düzenin nasıl hesaplandığına adım adım bakalım.

Column, tüm childlarını birer birer dikey bir Column’a yerleştirecek ve bu nedenle boyutu, alt boyutlarının toplamı olacaktır.

Column’un 6 alt öğesinin her biri aynıdır: 10dp yüksekliğinde bir Seperator. Spacer ölçüldüğünde, belirtilen boyutu dps’den piksele dönüştürülür ve sonuç boyutu bir tamsayı piksel olacaktır.

Bu dönüştürme Density.density faktörü ile dp’den piksele yapılır ve ardından roundToPx kullanılarak en yakın tamsayıya yuvarlanır.

Bu, Spacer’ların her biri için yapılır ve her biri aynı olduğu için, Column’un piksel cinsinden ortaya çıkan yüksekliği, herhangi bir Spacer’ın yüksekliğinin 6 katı olacaktır.

Sonuç

Compose’da yazılan Dp değerleri, API’lerin doğru birimi kullanmasını sağlamaya yardımcı olur, ancak birimlerin nasıl kullanıldığına ve kullanıcıya bileşenleri göstermek için nasıl dönüştürüldüğüne ilişkin temel süreci değiştirmez.

Cihaza ve yoğunluk faktörüne bağlı olarak, ara yuvarlama, boyut değerlerinin iyi bir şekilde artmayabileceği anlamına gelir.

Her biri 10dp yüksekliğinde olan 6 Spacer’a sahip bir Column 60dp yüksekliğinde olmayabilir. Gerçek davranış, Column’un piksel cinsinden her Spacer’ın yuvarlatılmış yüksekliğinin 6 katı olması gerektiğidir:

Özel bir düzen yazıyor ve onu test ediyorsanız, farklı aygıt yoğunluklarının yuvarlamanın fark edilebilir bir şekilde nasıl birikeceğini nasıl etkileyebileceğine dikkat etmeniz gerekmektedir.

Ardından, ya bu davranışı açıklayan ve doğrulayan testler yazmalı ya da kesin ölçümlere bağlı olmadan belirli bir hata payına izin vermelisiniz.

Aksi takdirde, bu yuvarlama, farklı emulatörler veya fiziksel aygıtlar üzerinde çalıştırıldığında özel düzenler için yapılan testlerin sinir bozucu şekilde farklı davranışlar sergilemesine neden olabilir.

Keyifli Okumalar :)

--

--

Kaan Enes KAPICI
IBTech
Writer for

Hi everybody, I’m Kaan. Senior Application(Android) Engineer at @TurkTelekom/Innova - Ex @QnbFinansbank Love cats and dogs.🐶🐈. Writing whatever I want..