Birlikte çalışabilirlik

Compose, yaygın test çerçeveleriyle entegre olur.

Espresso ile birlikte çalışabilirlik

Karma bir uygulamada, görünüm hiyerarşilerinde Compose bileşenlerini ve Compose bileşenlerinde görünümleri (AndroidView bileşeni aracılığıyla) bulabilirsiniz.

Her iki türü de eşleştirmek için özel bir adım gerekmez. Görünümleri Espresso'nun onView, Oluşturma öğ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ı semantik ekleme

Compose aramalarını belirli görünümlerle sınırlama

Karmaşık kullanıcı arayüzlerini Compose'a taşırken birden fazla geleneksel Android görünümünün (ör. RecyclerView veya ViewPager) içine yerleştirilmiş aynı Compose öğeleriyle karşılaşabilirsiniz. Bu senaryolarda, onNodeWithText("Save") gibi standart bir Compose araması "Birden fazla düğüm bulundu" hatasıyla başarısız olabilir.

Bu öğeleri ayırt etmek için dinamik test etiketleri eklemek üzere üretim kodunuzu değiştirmek yerine, Oluşturma testinizin kapsamını doğrudan belirli bir Android Görünümü olarak belirleyebilirsiniz.

Test kuralınızda onRootWithViewInteraction API'sini kullanın. Bu işlev, Espresso ViewInteraction kabul eder. Bu sayede, Espresso'yu kullanarak belirli bir kapsayıcı görünümü izole edebilir ve Oluşturma etkileşimlerini yalnızca bu kapsamlı hiyerarşi içinde gerçekleştirebilirsiniz.

Liste öğesiyle etkileşim kurma

Belirli bir RecyclerView satırındaki Compose öğesiyle etkileşim kurmanız gerekiyorsa satırı bulmak için Espresso'yu kullanın, ardından Compose etkileşiminizi bu satırla sınırlayın. Bu işlem, diğer tüm satırlardaki aynı Oluşturma öğelerini yok sayar.

@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'lardaki belirsizliği giderme

Aynı Oluşturma düzenlerine sahip birden fazla parça aynı anda bellekte olduğunda, eşleşme belirsizliğini önlemek için aramayı belirli parçanın kök görünüm 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

Varsayılan olarak, composable'lara UiAutomator'dan yalnızca uygun tanımlayıcıları (görüntülenen metin, içerik açıklaması vb.) aracılığıyla 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 bileşenler (ör. LazyColumn) gibi başka benzersiz herkese açık kullanıcı adı olmayan bileşenler 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 hiyerarşinizin üst kısımlarında yalnızca bir kez 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) içeren 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ı, testle ilgili temel bilgiler ve teknikler hakkında daha geniş bir bakış açısı sunar.
  • Testlerle ilgili temel bilgiler: Android uygulamalarını test etmenin temel kavramları hakkında daha fazla bilgi edinin.
  • Yerel testler: Bazı testleri yerel olarak, kendi iş istasyonunuzda çalıştırabilirsiniz.
  • Enstrümantasyon testleri: Enstrümantasyon testleri 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 kullanabileceği çok sayıda cihaz olduğundan farklı ekran boyutlarını test etmeniz gerekir.
  • Espresso: Görünüm tabanlı kullanıcı arayüzleri için tasarlanmış olsa da Espresso bilgisi, Compose testinin bazı yönleri için yine de faydalı olabilir.