Android, farklı ekran ve pencere boyutları için testler oluşturmanıza yardımcı olabilecek çeşitli araçlar ve API'ler sağlar.
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. Böylece, herhangi bir kullanıcı arayüzü testini herhangi bir ekran boyutunda ç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 üzere 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, yazı tipi ölçeğini, temaları ve farklı pencere boyutlarında test etmek isteyebileceğiniz diğer özellikleri ayarlamak için bu bileşiği kullanabilirsiniz.
Robolectric
Robolectric'i kullanarak Compose veya görünüme dayalı kullanıcı arayüzü testlerini JVM'de yerel olarak çalıştırın. Cihaz veya emülatör gerekmez. Robolectric'i, diğer yararlı özelliklerin yanı sıra belirli ekran boyutlarını kullanacak şekilde yapılandırabilirsiniz.
Artık Android'de başlıklı makaledeki aşağıdaki örnekte, Robolectric 480 dpi çözünürlüğe sahip 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 { ... }
Ayrıca, Artık Android'de örneğindeki bu snippet'te yapıldığı gibi test gövdesinden de nitelikleri ayarlayabilirsiniz:
val (width, height, dpi) = ...
// Set qualifiers from specs.
RuntimeEnvironment.setQualifiers("w${width}dp-h${height}dp-${dpi}dpi")
RuntimeEnvironment.setQualifiers()
'ün sistemi ve uygulama kaynaklarını yeni yapılandırmaya güncellediğini ancak etkin etkinliklerde veya diğer bileşenlerde herhangi bir işlem tetiklemediğini unutmayın.
Daha fazla bilgiyi Robolectric Cihaz Yapılandırması dokümanlarında bulabilirsiniz.
Gradle tarafından yönetilen cihazlar
Gradle tarafından yönetilen cihazlar (GMD) Android Gradle eklentisi, enstrümante edilmiş 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 cihazlar için özellikler oluşturun. GMD'yi sürekli entegrasyon (CI) ile kullanarak, gerektiğinde uygun testlerin çalıştırılmasını sağlayabilir, emülatörleri hazırlayarak ve başlatarak 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'ye ait birden fazla örnek bulabilirsiniz.
Firebase Test Lab
Testlerinizi, erişiminiz olmayabilecek belirli gerçek cihazlarda (ör. katlanabilir cihazlar veya farklı boyutlarda tabletler) çalıştırmak için Firebase Test Lab'i (FTL) ya da benzer bir cihaz çiftliği hizmetini kullanın. Firebase Test Lab, ücretsiz katmanı olan ücretli bir hizmettir. FTL, testlerin emülatörlerde çalıştırılmasını da destekler. Bu hizmetler, cihazları ve emülatörleri önceden hazırlayarak araç destekli testin 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 filtrelemeyi test etme
Optimal bir 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ü testlerinizin tümünü veya çoğunu bir telefon form faktöründe, yalnızca bir alt kümesini ise farklı ekran boyutlarına sahip cihazlarda çalıştırarak filtrelersiniz.
Belirli testleri yalnızca belirli cihazlarla çalıştırılacak şekilde ek açıklamayla işaretleyebilir ve ardından testleri çalıştıran komutu kullanarak AndroidJUnitRunner'a bir bağımsız değişken iletebilirsiniz.
Örneğin, farklı ek açıklamalar oluşturabilirsiniz:
annotation class TestExpandedWidth
annotation class TestCompactWidth
Bunları farklı testlerde kullanabilirsiniz:
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
mülkünü 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 CI'de emülatörleri yönetiyorsanız önce doğru emülatör veya cihazın hazır ve bağlı olduğundan emin olun, ardından enstrümante edilmiş testleri çalıştırmak için parametreyi Gradle komutlarından birine iletin:
$ ./gradlew connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.annotation='com.sample.TestExpandedWidth'
Espresso cihazının (sonraki bölüme bakın) cihaz özelliklerini kullanarak testleri filtreleyebileceğini unutmayın.
Espresso Cihazı
Espresso, Compose veya UI Automator testleri dahil olmak üzere her tür enstrümante edilmiş testleri kullanarak testlerde emülatörlerde işlem yapmak için Espresso Device'ı kullanın. Ekran boyutunu ayarlama veya katlanabilir durumları ya da duruşları değiştirme bu işlemler arasında yer alabilir. Örneğin, katlanabilir bir emülatör kontrol edebilir ve masaüstü moduna ayarlayabilirsiniz. Espresso Device, belirli özellikleri zorunlu kılmak için 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 cihazının hâlâ alfa aşamasında olduğunu ve aşağıdaki koşulları karşıladığını unutmayın:
- Android Gradle eklentisi 8.3 veya sonraki sürümler
- Android Emulator 33.1.10 veya sonraki sürümler
- API seviyesi 24 veya daha yeni sürümleri çalıştıran Android sanal cihaz
Testleri filtreleme
Espresso Device, notlar kullanarak testleri filtrelemenize olanak tanımak için bağlı cihazların özelliklerini okuyabilir. Notlandırılmış koşullar karşılanmazsa testler atlanır.
RequiresDeviceMode ek açıklaması
RequiresDeviceMode
ek açıklama, yalnızca cihazda DeviceMode
değerlerinin tümü destekleniyorsa çalışacak bir testi belirtmek için birden çok 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ına uygun olarak 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. Yöntemi DisplaySizeRule
sınıfıyla birlikte kullanın. Bu sınıf, testler sırasında yapılan değişikliklerin bir sonraki testten önce geri alınmasını sağlar.
@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ın boyutunu değiştirdiğinizde 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 birleştirilebilir bileşenler için durum geri yüklemeyi test etmek amacıyla kullanılır. Etkinlik yeniden oluşturma işlemi birden fazla senkronizasyon mekanizması içeren karmaşık bir süreç olduğundan bu, testleri daha hızlı ve daha güvenilir hale getirir:
@Test
fun compactDevice_selectedEmailEmailRetained_afterConfigChange() {
val stateRestorationTester = StateRestorationTester(composeTestRule)
// Set content through the StateRestorationTester object.
stateRestorationTester.setContent {
MyApp()
}
// Simulate a config change.
stateRestorationTester.emulateSavedInstanceStateRestore()
}
Pencere Testi kitaplığı
Pencere Testi kitaplığı, etkinlik yerleştirme veya katlanabilir özellikler gibi pencere yönetimiyle ilgili özellikleri kullanan ya da doğrulayan testler yazmanıza yardımcı olacak yardımcı programlar içerir. Öğe, Google'ın Maven deposundan edinilebilir.
Örneğin, FoldingFeature()
işlevini kullanarak özel bir FoldingFeature
oluşturabilir ve bu özel FoldingFeature
'i Oluştur önizlemelerinde kullanabilirsiniz. Java'da createFoldingFeature()
işlevini kullanın.
Oluştur önizlemesinde FoldingFeature
öğesini aşağıdaki ş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 HALF_OPENED
dikey menteşe bulunan bir FoldingFeature
simüle edilerek düzenin beklenen düzen olup olmadığı kontrol edilir:
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()))
}
}
Daha fazla örnek için WindowManager projesine göz atın.
Ek kaynaklar
Belgeler
- Büyük ekran uygulama kalitesi yönergeleri
- Android'de uygulamaları test etme
- Oluşturma düzeninizi test etme
Örnekler
- WindowManager örneği
- Espresso cihazı örnekleri
- Android'de kullanıma sunuldu
- Farklı ekran boyutlarını doğrulamak için ekran görüntüsü testini kullanır
Codelab uygulamaları