Android, farklı ekran ve pencere boyutları için testler oluşturmanıza yardımcı olabilecek çeşitli araçlar ve API'ler sunar.
DeviceConfigurationOverride
DeviceConfigurationOverride bileşeni, Compose düzenlerinde birden fazla ekran ve pencere boyutunu test etmek için yapılandırma özelliklerini geçersiz kılmanıza olanak tanır. ForcedSize geçersiz kılma, mevcut alandaki tüm düzenlere uyar. Bu sayede, herhangi bir ekran boyutunda herhangi bir kullanıcı arayüzü testi çalıştırabilirsiniz. Örneğin, büyük telefonlar, katlanabilir cihazlar ve tabletler için kullanıcı arayüzü testleri de dahil olmak üzere tüm kullanıcı arayüzü testlerinizi çalıştırmak için küçük bir telefon form faktörü kullanabilirsiniz.
DeviceConfigurationOverride(
DeviceConfigurationOverride.ForcedSize(DpSize(1280.dp, 800.dp))
) {
MyScreen() // Will be rendered in the space for 1280dp by 800dp without clipping.
}
Ayrıca, farklı pencere boyutlarında test etmek isteyebileceğiniz yazı tipi ölçeğini, temaları ve diğer özellikleri ayarlamak için bu composable'ı kullanabilirsiniz.
Robolectric
JVM'de Compose veya görünüm tabanlı kullanıcı arayüzü testlerini yerel olarak çalıştırmak için Robolectric'i kullanın. Cihaz veya emülatör gerekmez. Robolectric'i, diğer faydalı özelliklerin yanı sıra belirli ekran boyutlarını kullanacak şekilde yapılandırabilirsiniz.
Now in Android'deki aşağıdaki örnekte Robolectric, 480 dpi çözünürlükte 1000x1000 dp ekran boyutunu taklit edecek şekilde yapılandırılmıştır:
@RunWith(RobolectricTestRunner::class)
// Configure Robolectric to use a very large screen size that can fit all of the test sizes.
// This allows enough room to render the content under test without clipping or scaling.
@Config(qualifiers = "w1000dp-h1000dp-480dpi")
class NiaAppScreenSizesScreenshotTests { ... }
Niteleyicileri, Now in Android örneğindeki bu snippet'te yapıldığı gibi test gövdesinden de ayarlayabilirsiniz:
val (width, height, dpi) = ...
// Set qualifiers from specs.
RuntimeEnvironment.setQualifiers("w${width}dp-h${height}dp-${dpi}dpi")
RuntimeEnvironment.setQualifiers(), sistem ve uygulama kaynaklarını yeni yapılandırmayla günceller ancak etkin etkinliklerde veya diğer bileşenlerde herhangi bir işlemi tetiklemez.
Robolectric Cihaz Yapılandırması belgelerinden daha fazla bilgi edinebilirsiniz.
Gradle tarafından yönetilen cihazlar
Gradle tarafından yönetilen cihazlar (GMD) Android Gradle eklentisi, enstrümantasyon testlerinizin çalıştırıldığı emülatörlerin ve gerçek cihazların özelliklerini tanımlamanıza olanak tanır. Belirli testlerin belirli ekran boyutlarında çalıştırılması gereken bir test stratejisi uygulamak için farklı ekran boyutlarına sahip cihazlara yönelik spesifikasyonlar oluşturun. GMD'yi sürekli entegrasyon (CI) ile kullanarak uygun testlerin gerektiğinde çalıştırılmasını sağlayabilir, emülatörleri hazırlayıp başlatabilir ve CI kurulumunuzu basitleştirebilirsiniz.
android {
testOptions {
managedDevices {
devices {
// Run with ./gradlew nexusOneApi30DebugAndroidTest.
nexusOneApi30(com.android.build.api.dsl.ManagedVirtualDevice) {
device = "Nexus One"
apiLevel = 30
// Use the AOSP ATD image for better emulator performance
systemImageSource = "aosp-atd"
}
// Run with ./gradlew foldApi34DebugAndroidTest.
foldApi34(com.android.build.api.dsl.ManagedVirtualDevice) {
device = "Pixel Fold"
apiLevel = 34
systemImageSource = "aosp-atd"
}
}
}
}
}
testing-samples projesinde GMD ile ilgili birden fazla örnek bulabilirsiniz.
Firebase Test Lab
Erişiminiz olmayan belirli gerçek cihazlarda (ör. farklı boyutlardaki katlanabilir cihazlar veya tabletler) testlerinizi çalıştırmak için Firebase Test Lab (FTL) veya benzer bir cihaz grubu hizmetini kullanın. Firebase Test Lab, ücretsiz katmanı olan ücretli bir hizmettir. FTL, emülatörlerde test çalıştırmayı da destekler. Bu hizmetler, cihazları ve emülatörleri önceden hazırlayabildiği için enstrümantasyon testinin güvenilirliğini ve hızını artırır.
FTL'yi GMD ile kullanma hakkında bilgi edinmek için Gradle tarafından yönetilen cihazlarla testlerinizi ölçeklendirme başlıklı makaleyi inceleyin.
Test çalıştırıcı ile test filtreleme
En uygun test stratejisi aynı şeyi iki kez doğrulamamalıdır. Bu nedenle, kullanıcı arayüzü testlerinizin çoğunun birden fazla cihazda çalıştırılması gerekmez. Genellikle kullanıcı arayüzü testlerinizi, hepsini veya çoğunu bir telefon form faktöründe ve yalnızca bir alt kümesini farklı ekran boyutlarına sahip cihazlarda çalıştırarak filtrelersiniz.
Belirli testlere yalnızca belirli cihazlarla çalıştırılacak şekilde ek açıklama ekleyebilir ve ardından testleri çalıştıran komutu kullanarak AndroidJUnitRunner'a bir bağımsız değişken iletebilirsiniz.
Örneğin, farklı notlar oluşturabilirsiniz:
annotation class TestExpandedWidth
annotation class TestCompactWidth
Bunları farklı testlerde kullanın:
class MyTestClass {
@Test
@TestExpandedWidth
fun myExample_worksOnTablet() {
...
}
@Test
@TestCompactWidth
fun myExample_worksOnPortraitPhone() {
...
}
}
Ardından, testleri çalıştırırken belirli testleri filtrelemek için android.testInstrumentationRunnerArguments.annotation özelliğini kullanabilirsiniz. Örneğin, Gradle tarafından yönetilen cihazları kullanıyorsanız:
$ ./gradlew pixelTabletApi30DebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.annotation='com.sample.TestExpandedWidth'
GMD kullanmıyorsanız ve emülatörleri CI'da yönetiyorsanız öncelikle doğru emülatörün veya cihazın hazır ve bağlı olduğundan emin olun, ardından parametreyi Gradle komutlarından birine ileterek enstrümantasyon testlerini çalıştırın:
$ ./gradlew connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.annotation='com.sample.TestExpandedWidth'
Espresso Device'ın (sonraki bölüme bakın) testleri cihaz özelliklerini kullanarak da filtreleyebileceğini unutmayın.
Espresso Cihazı
Espresso, Compose veya UI Automator testleri de dahil olmak üzere her türlü enstrümantasyon testini kullanarak testlerde emülatörler üzerinde işlem yapmak için Espresso Device'ı kullanın. Bu işlemler arasında ekran boyutunu ayarlama veya katlanabilir durumlar ya da duruşlar arasında geçiş yapma yer alabilir. Örneğin, katlanabilir bir emülatörü kontrol edebilir ve masaüstü moduna ayarlayabilirsiniz. Espresso Device, belirli özellikleri gerektiren JUnit kuralları ve ek açıklamaları da içerir:
@RunWith(AndroidJUnit4::class)
class OnDeviceTest {
@get:Rule(order=1) val activityScenarioRule = activityScenarioRule<MainActivity>()
@get:Rule(order=2) val screenOrientationRule: ScreenOrientationRule =
ScreenOrientationRule(ScreenOrientation.PORTRAIT)
@Test
fun tabletopMode_playerIsDisplayed() {
// Set the device to tabletop mode.
onDevice().setTabletopMode()
onView(withId(R.id.player)).check(matches(isDisplayed()))
}
}
Espresso Device'ın hâlâ alfa aşamasında olduğunu ve aşağıdaki şartlara tabi olduğunu unutmayın:
- Android Gradle eklentisi 8.3 veya sonraki sürümler
- Android Emulator 33.1.10 veya sonraki sürümler
- API düzeyi 24 veya daha yüksek bir sürümü çalıştıran Android sanal cihazı
Testleri filtreleme
Espresso Device, bağlı cihazların özelliklerini okuyarak testleri notlar kullanarak filtrelemenize olanak tanır. Ek açıklamalı koşullar karşılanmazsa testler atlanır.
RequiresDeviceMode ek açıklaması
RequiresDeviceMode ek açıklaması, yalnızca cihazda DeviceMode değerlerinin tümü destekleniyorsa çalıştırılacak bir testi belirtmek için birden fazla kez kullanılabilir.
class OnDeviceTest {
...
@Test
@RequiresDeviceMode(TABLETOP)
@RequiresDeviceMode(BOOK)
fun tabletopMode_playerIdDisplayed() {
// Set the device to tabletop mode.
onDevice().setTabletopMode()
onView(withId(R.id.player)).check(matches(isDisplayed()))
}
}
RequiresDisplay ek açıklaması
RequiresDisplay ek açıklaması, resmi pencere boyutu sınıflarını izleyen boyut gruplarını tanımlayan boyut sınıflarını kullanarak cihaz ekranının genişliğini ve yüksekliğini belirtmenize olanak tanır.
class OnDeviceTest {
...
@Test
@RequiresDisplay(EXPANDED, COMPACT)
fun myScreen_expandedWidthCompactHeight() {
...
}
}
Ekranları yeniden boyutlandırma
Çalışma zamanında ekranın boyutlarını yeniden boyutlandırmak için setDisplaySize() yöntemini kullanın. Bu yöntemi, testler sırasında yapılan değişikliklerin bir sonraki testten önce geri alınmasını sağlayan DisplaySizeRule sınıfıyla birlikte kullanın.
@RunWith(AndroidJUnit4::class)
class ResizeDisplayTest {
@get:Rule(order = 1) val activityScenarioRule = activityScenarioRule<MainActivity>()
// Test rule for restoring device to its starting display size when a test case finishes.
@get:Rule(order = 2) val displaySizeRule: DisplaySizeRule = DisplaySizeRule()
@Test
fun resizeWindow_compact() {
onDevice().setDisplaySize(
widthSizeClass = WidthSizeClass.COMPACT,
heightSizeClass = HeightSizeClass.COMPACT
)
// Verify visual attributes or state restoration.
}
}
setDisplaySize() ile bir ekranı yeniden boyutlandırdığınızda cihazın yoğunluğunu etkilemezsiniz. Bu nedenle, bir boyut hedef cihaza sığmazsa test UnsupportedDeviceOperationException ile başarısız olur. Bu durumda testlerin çalıştırılmasını önlemek için RequiresDisplay ek açıklamasını kullanarak testleri filtreleyin:
@RunWith(AndroidJUnit4::class)
class ResizeDisplayTest {
@get:Rule(order = 1) var activityScenarioRule = activityScenarioRule<MainActivity>()
// Test rule for restoring device to its starting display size when a test case finishes.
@get:Rule(order = 2) var displaySizeRule: DisplaySizeRule = DisplaySizeRule()
/**
* Setting the display size to EXPANDED would fail in small devices, so the [RequiresDisplay]
* annotation prevents this test from being run on devices outside the EXPANDED buckets.
*/
@RequiresDisplay(
widthSizeClass = WidthSizeClassEnum.EXPANDED,
heightSizeClass = HeightSizeClassEnum.EXPANDED
)
@Test
fun resizeWindow_expanded() {
onDevice().setDisplaySize(
widthSizeClass = WidthSizeClass.EXPANDED,
heightSizeClass = HeightSizeClass.EXPANDED
)
// Verify visual attributes or state restoration.
}
}
StateRestorationTester
StateRestorationTester sınıfı, etkinlikleri yeniden oluşturmadan composable bileşenlerin durum geri yüklemesini test etmek için kullanılır. Bu sayede testler daha hızlı ve daha güvenilir hale gelir. Çünkü etkinliğin yeniden oluşturulması, birden fazla senkronizasyon mekanizması içeren karmaşık bir süreçtir:
@Test
fun compactDevice_selectedEmailEmailRetained_afterConfigChange() {
val stateRestorationTester = StateRestorationTester(composeTestRule)
// Set content through the StateRestorationTester object.
stateRestorationTester.setContent {
MyApp()
}
// Simulate a config change.
stateRestorationTester.emulateSavedInstanceStateRestore()
}
Window Testing kitaplığı
Pencere Testi kitaplığı, etkinlik yerleştirme veya katlanabilir özellikler gibi pencere yönetimiyle ilgili özelliklere dayalı ya da bu özellikleri doğrulayan testler yazmanıza yardımcı olan yardımcı programlar içerir. Yapı, Google'ın Maven deposu üzerinden kullanılabilir.
Örneğin, FoldingFeature() işlevini kullanarak özel bir FoldingFeature oluşturabilir ve bunu Compose önizlemelerinde kullanabilirsiniz. Java'da createFoldingFeature() işlevini kullanın.
Oluşturma önizlemesinde FoldingFeature öğesini şu şekilde uygulayabilirsiniz:
@Preview(showBackground = true, widthDp = 480, heightDp = 480)
@Composable private fun FoldablePreview() =
MyApplicationTheme {
ExampleScreen(
displayFeatures = listOf(FoldingFeature(Rect(0, 240, 480, 240)))
)
}
Ayrıca, TestWindowLayoutInfo() işlevini kullanarak kullanıcı arayüzü testlerinde ekran özelliklerini taklit edebilirsiniz.
Aşağıdaki örnekte, ekranın ortasında dikey menteşesi olan bir FoldingFeature simüle edilmekte ve ardından düzenin beklenen düzen olup olmadığı kontrol edilmektedir:
HALF_OPENED
Oluştur
import androidx.window.layout.FoldingFeature.Orientation.Companion.VERTICAL
import androidx.window.layout.FoldingFeature.State.Companion.HALF_OPENED
import androidx.window.testing.layout.FoldingFeature
import androidx.window.testing.layout.TestWindowLayoutInfo
import androidx.window.testing.layout.WindowLayoutInfoPublisherRule
@RunWith(AndroidJUnit4::class)
class MediaControlsFoldingFeatureTest {
@get:Rule(order=1)
val composeTestRule = createAndroidComposeRule<ComponentActivity>()
@get:Rule(order=2)
val windowLayoutInfoPublisherRule = WindowLayoutInfoPublisherRule()
@Test
fun foldedWithHinge_foldableUiDisplayed() {
composeTestRule.setContent {
MediaPlayerScreen()
}
val hinge = FoldingFeature(
activity = composeTestRule.activity,
state = HALF_OPENED,
orientation = VERTICAL,
size = 2
)
val expected = TestWindowLayoutInfo(listOf(hinge))
windowLayoutInfoPublisherRule.overrideWindowLayoutInfo(expected)
composeTestRule.waitForIdle()
// Verify that the folding feature is detected and media controls shown.
composeTestRule.onNodeWithTag("MEDIA_CONTROLS").assertExists()
}
}
Görüntüleme sayısı
import androidx.window.layout.FoldingFeature.Orientation
import androidx.window.layout.FoldingFeature.State
import androidx.window.testing.layout.FoldingFeature
import androidx.window.testing.layout.TestWindowLayoutInfo
import androidx.window.testing.layout.WindowLayoutInfoPublisherRule
@RunWith(AndroidJUnit4::class)
class MediaControlsFoldingFeatureTest {
@get:Rule(order=1)
val activityRule = ActivityScenarioRule(MediaPlayerActivity::class.java)
@get:Rule(order=2)
val windowLayoutInfoPublisherRule = WindowLayoutInfoPublisherRule()
@Test
fun foldedWithHinge_foldableUiDisplayed() {
activityRule.scenario.onActivity { activity ->
val feature = FoldingFeature(
activity = activity,
state = State.HALF_OPENED,
orientation = Orientation.VERTICAL)
val expected = TestWindowLayoutInfo(listOf(feature))
windowLayoutInfoPublisherRule.overrideWindowLayoutInfo(expected)
}
// Verify that the folding feature is detected and media controls shown.
onView(withId(R.id.media_controls)).check(matches(isDisplayed()))
}
}
WindowManager projesinde daha fazla örnek bulabilirsiniz.
Ek kaynaklar
Belgeler
- Büyük ekranlarda uygulama kalitesi yönergeleri
- Android'de uygulamaları test etme
- Compose düzeninizi test etme
Örnekler
- WindowManager örneği
- Espresso cihaz örnekleri
- Now In Android
- Farklı ekran boyutlarını doğrulamak için ekran görüntüsü testini kullanma
Codelab uygulamaları