Compose, yaygın test çerçeveleriyle entegre olur.
Espresso ile birlikte çalışabilirlik
Karma uygulamalarda, görünüm hiyerarşileri içinde Compose bileşenlerini ve Compose composable'ları içinde görünümleri (AndroidView composable'ı aracılığıyla) bulabilirsiniz.
Her iki türün eşleştirilmesi için özel bir adım gerekmez. Görünümleri Espresso'nun onView ile, Compose öğelerini ise ComposeTestRule ile eşleştirirsiniz.
@Test
fun androidViewInteropTest() {
// Check the initial state of a TextView that depends on a Compose state.
Espresso.onView(withText("Hello Views")).check(matches(isDisplayed()))
// Click on the Compose button that changes the state.
composeTestRule.onNodeWithText("Click here").performClick()
// Check the new value.
Espresso.onView(withText("Hello Compose")).check(matches(isDisplayed()))
}
Compose birlikte çalışabilirlik testi için görünüm kapsamlı anlamsal yapı ekleme
Oluşturma aramalarını belirli görünümlerle sınırlama
Karmaşık kullanıcı arayüzlerini Compose'a geçirirken, birden fazla geleneksel Android görünümünün (ör. RecyclerView veya ViewPager içinde) içine yerleştirilmiş aynı Compose öğeleriyle karşılaşabilirsiniz. Bu senaryolarda, onNodeWithText("Save") gibi standart bir Oluşturma araması "Birden çok düğüm bulundu" hatasıyla başarısız olabilir.
Bu öğeleri ayırt etmek için üretim kodunuzu değiştirip dinamik test etiketleri yerleştirmek yerine, Compose testinizi doğrudan belirli bir Android View ile sınırlayabilirsiniz.
Test kuralınızda onRootWithViewInteraction API'sini kullanın. Bu işlev, Espresso ViewInteraction kabul eder. Böylece, belirli bir kapsayıcı görünümü yalıtmak ve Compose etkileşimlerini yalnızca bu kapsamlı hiyerarşi içinde gerçekleştirmek için Espresso'dan yararlanabilirsiniz.
Liste öğesiyle etkileşimde bulunma
Belirli bir RecyclerViewsatırın içindeki bir Compose öğesiyle etkileşimde bulunmanız gerekiyorsa satırı bulmak için Espresso'yu kullanın, ardından Compose etkileşiminizi bu satırla sınırlayın.
Bu, diğer tüm satırlardaki aynı Oluşturma öğelerini yoksayar.
@Test fun testComposeButtonInsideRecyclerViewItem() = runComposeUiTest { // Scroll to the desired position using Espresso Espresso.onView(withId(recyclerViewId)) .perform(RecyclerViewActions.scrollToPosition<MyViewHolder>(3)) // Define an Espresso ViewInteraction that uniquely identifies the row val rowView = Espresso.onView( allOf( withId(rootViewId), hasDescendant(withText("Item #3")) ) ) // Scope the Compose search strictly to that specific row View onRootWithViewInteraction(rowView) .onNode(hasText("Like")) .performClick() }
ViewPager'larda belirsizliği giderme
Bellekte aynı anda aynı Compose düzenine sahip birden fazla parça olduğunda, eşleşme belirsizliğini önlemek için aramayı belirli parçanın kök View kimliğiyle sınırlayabilirsiniz.
@Test fun testComposeButtonInsideViewPagerItem() = runComposeUiTest { // Swipe to the desired page using Espresso Espresso.onView(withId(viewPagerViewId)).perform(swipeLeft()) // Identify the specific container view using Espresso val fragmentB = Espresso.onView(withId(fragmentRootViewId)) // The generic text "Save" is now unique within this view scope onRootWithViewInteraction(fragmentB) .onNode(hasText("Save")) .assertIsDisplayed() }
UiAutomator ile birlikte çalışabilirlik
Composable'lar varsayılan olarak UiAutomator'dan yalnızca uygun tanımlayıcılarıyla (görüntülenen metin, içerik açıklaması vb.) erişilebilir. Modifier.testTag kullanan bir composable'a erişmek istiyorsanız ilgili composable'ın alt ağacı için testTagsAsResourceId semantik özelliğini etkinleştirmeniz gerekir. Bu davranışı etkinleştirmek, kaydırılabilir composable'lar (ör. LazyColumn) gibi başka benzersiz tutma yeri olmayan composable'lar için kullanışlıdır.
Modifier.testTag içeren tüm iç içe yerleştirilmiş composable'lara UiAutomator'dan erişilebilmesi için semantik özelliği composable'lar hiyerarşinizde yalnızca bir kez yüksekte etkinleştirin.
Scaffold(
// Enables for all composables in the hierarchy.
modifier = Modifier.semantics {
testTagsAsResourceId = true
}
){
// Modifier.testTag is accessible from UiAutomator for composables nested here.
LazyColumn(
modifier = Modifier.testTag("myLazyColumn")
){
// Content
}
}
Modifier.testTag(tag) ile oluşturulan tüm composable'lara, resourceName ile aynı tag kullanılarak By.res(resourceName) ile erişilebilir.
val device = UiDevice.getInstance(getInstrumentation())
val lazyColumn: UiObject2 = device.findObject(By.res("myLazyColumn"))
// Some interaction with the lazyColumn.
Ek Kaynaklar
- Android'de uygulamaları test etme: Android testleriyle ilgili ana açılış sayfası, test temelleri ve teknikleri hakkında daha geniş bir bakış açısı sunar.
- Testin temelleri: Android uygulaması test etmenin temel kavramları hakkında daha fazla bilgi edinin.
- Yerel testler: Bazı testleri kendi iş istasyonunuzda yerel olarak çalıştırabilirsiniz.
- Araçlı testler: Araçlı testler de çalıştırmak iyi bir uygulamadır. Yani doğrudan cihaz üzerinde çalışan testler.
- Sürekli entegrasyon: Sürekli entegrasyon, testlerinizi dağıtım ardışık düzeninize entegre etmenize olanak tanır.
- Farklı ekran boyutlarını test edin: Kullanıcıların erişebileceği çok sayıda cihaz olduğundan farklı ekran boyutlarını test etmeniz gerekir.
- Espresso: Görüntüleme tabanlı kullanıcı arayüzleri için tasarlanmış olsa da Espresso bilgisi, Compose testinin bazı yönlerinde faydalı olabilir.