Yaygın kalıplar

Compose uygulamanızı, yerleşik yaklaşımlar ve kalıplarla test edebilirsiniz.

İzole olarak test etme

ComposeTestRule, herhangi bir composable'ı (uygulamanızın tamamı, tek bir ekran veya küçük bir öğe) gösteren bir etkinlik başlatmanıza olanak tanır. Ayrıca, composable'larınızın doğru şekilde kapsüllendiğinden ve bağımsız olarak çalıştığından emin olmak da iyi bir uygulamadır. Bu sayede daha kolay ve daha odaklı kullanıcı arayüzü testleri yapabilirsiniz.

Bu, yalnızca birim kullanıcı arayüzü testleri oluşturmanız gerektiği anlamına gelmez. Kullanıcı arayüzünüzün daha büyük bölümlerini kapsayan kullanıcı arayüzü testleri de çok önemlidir.

Kendi içeriğinizi ayarladıktan sonra etkinliğe ve kaynaklara erişme

Genellikle test edilen içeriği composeTestRule.setContent kullanarak ayarlamanız ve etkinlik kaynaklarına erişmeniz gerekir. Örneğin, görüntülenen bir metnin dize kaynağıyla eşleştiğini doğrulamak için. Ancak etkinlik, createAndroidComposeRule() ile oluşturulan bir kuralı zaten çağırıyorsa setContent yöntemini çağıramazsınız.

Bunu yapmanın yaygın bir yolu, ComponentActivity gibi boş bir etkinlik kullanarak AndroidComposeTestRule oluşturmaktır.

class MyComposeTest {

    @get:Rule
    val composeTestRule = createAndroidComposeRule<ComponentActivity>()

    @Test
    fun myTest() {
        // Start the app
        composeTestRule.setContent {
            MyAppTheme {
                MainScreen(uiState = exampleUiState, /*...*/)
            }
        }
        val continueLabel = composeTestRule.activity.getString(R.string.next)
        composeTestRule.onNodeWithText(continueLabel).performClick()
    }
}

ComponentActivity, uygulamanızın AndroidManifest.xml dosyasına eklenmelidir. Bu özelliği etkinleştirmek için modülünüze şu bağımlılığı ekleyin:

debugImplementation("androidx.compose.ui:ui-test-manifest:$compose_version")

Özel semantik özellikleri

Bilgileri testlere göstermek için özel semantik özellikleri oluşturabilirsiniz. Bunu yapmak için yeni bir SemanticsPropertyKey tanımlayın ve SemanticsPropertyReceiver kullanarak kullanılabilir hale getirin.

// Creates a semantics property of type Long.
val PickedDateKey = SemanticsPropertyKey<Long>("PickedDate")
var SemanticsPropertyReceiver.pickedDate by PickedDateKey

Şimdi bu özelliği semantics değiştiricisinde kullanın:

val datePickerValue by remember { mutableStateOf(0L) }
MyCustomDatePicker(
    modifier = Modifier.semantics { pickedDate = datePickerValue }
)

Testlerde, özelliğin değerini doğrulamak için SemanticsMatcher.expectValue kullanın:

composeTestRule
    .onNode(SemanticsMatcher.expectValue(PickedDateKey, 1445378400)) // 2015-10-21
    .assertExists()

Durum geri yüklemeyi doğrulama

Etkinlik veya işlem yeniden oluşturulduğunda Compose öğelerinizin durumunun doğru şekilde geri yüklendiğini doğrulayın. Bu tür kontrolleri, StateRestorationTester sınıfıyla etkinliğin yeniden oluşturulmasına gerek kalmadan yapın.

Bu sınıf, bir composable'ın yeniden oluşturulmasını simüle etmenize olanak tanır. Özellikle rememberSaveable uygulamasını doğrulamak için kullanışlıdır.


class MyStateRestorationTests {

    @get:Rule
    val composeTestRule = createComposeRule()

    @Test
    fun onRecreation_stateIsRestored() {
        val restorationTester = StateRestorationTester(composeTestRule)

        restorationTester.setContent { MainScreen() }

        // TODO: Run actions that modify the state

        // Trigger a recreation
        restorationTester.emulateSavedInstanceStateRestore()

        // TODO: Verify that state has been correctly restored.
    }
}

Farklı cihaz yapılandırmalarını test etme

Android uygulamalarının pencere boyutları, yerel ayarlar, yazı tipi boyutları, koyu ve açık temalar gibi değişen birçok koşula uyum sağlaması gerekir. Bu koşulların çoğu, kullanıcı tarafından kontrol edilen ve mevcut Configuration örneğiyle gösterilen cihaz düzeyindeki değerlerden türetilir. Testin cihaz düzeyindeki özellikleri yapılandırması gerektiğinden, farklı yapılandırmaları doğrudan testte test etmek zordur.

DeviceConfigurationOverride, test edilen @Composable içeriği için farklı cihaz yapılandırmalarını yerelleştirilmiş bir şekilde simüle etmenize olanak tanıyan, yalnızca test amaçlı bir API'dir.

DeviceConfigurationOverride öğesinin tamamlayıcı nesnesi, cihaz düzeyindeki yapılandırma özelliklerini geçersiz kılan aşağıdaki uzantı işlevlerine sahiptir:

Belirli bir geçersiz kılma işlemini uygulamak için test edilen içeriği DeviceConfigurationOverride() üst düzey işlevine yapılan bir çağrıyla sarmalayın ve uygulanacak geçersiz kılma işlemini parametre olarak iletin.

Örneğin, aşağıdaki kod, yoğunluğu yerel olarak değiştirmek için DeviceConfigurationOverride.ForcedSize() geçersiz kılma işlemini uygular ve testin çalıştığı cihaz bu pencere boyutunu doğrudan desteklemese bile MyScreen composable'ın büyük bir yatay pencerede oluşturulmasını zorunlu kılar:

composeTestRule.setContent {
    DeviceConfigurationOverride(
        DeviceConfigurationOverride.ForcedSize(DpSize(1280.dp, 800.dp))
    ) {
        MyScreen() // Will be rendered in the space for 1280dp by 800dp without clipping.
    }
}

Birden fazla geçersiz kılmayı birlikte uygulamak için DeviceConfigurationOverride.then() kullanın:

composeTestRule.setContent {
    DeviceConfigurationOverride(
        DeviceConfigurationOverride.FontScale(1.5f) then
            DeviceConfigurationOverride.FontWeightAdjustment(200)
    ) {
        Text(text = "text with increased scale and weight")
    }
}

Testlerde özel hata işleme

Kullanıcı arayüzü testlerinde hata ayıklama işlemi genellikle bir onaylama başarısız olduğunda ekran durumunun ve oluşturma hiyerarşisinin incelenmesini gerektirir.

Compose, teşhisleri kolaylaştırmak için yerel bir hata işleme ardışık düzeni sağlar. Hata durumunda ekran görüntülerini ve kullanıcı arayüzü hiyerarşilerini otomatik olarak yakalayabilir veya kilitlenme telemetrisini harici araçlara yönlendirmek için özel işleyiciler kaydedebilirsiniz.

Hata işlemeyi yapılandırma

Hata işlemeyi yapılandırmak için ComposeUiTestConfig yöntemine bir TestFailurePolicy nesnesi iletin.

Yerleşik hata yapılarını yakalama

Test başarısız olduğunda ekran görüntülerini ve kullanıcı arayüzü hiyerarşilerini yakalamak için TestFailurePolicy dosyasında screenshotCaptureMode ve uiHierarchyCaptureMode özelliklerini ayarlayın.

class MyComposeTest {
    private val customConfig = ComposeUiTestConfig(
        failurePolicy = TestFailurePolicy(
            screenshotCaptureMode = TestFailurePolicy.CaptureMode.Enabled,
            uiHierarchyCaptureMode = TestFailurePolicy.CaptureMode.Enabled
        )
    )

    @Test
    fun myFirstTest() = runComposeUiTest(config = customConfig) {
        // ...
    }
}

Özel hata işleyici kullanma

Test hataları için özel davranış tanımlamak istiyorsanız failureHandlers listesine bir TestFailureHandler ekleyin. Her işleyici, orijinal hatayı ve önceki ardışık düzen işleyiciler tarafından oluşturulan yapıların listesini içeren bir FailureContext nesnesi alır.

class MyComposeTestWithHandler {
    private val customConfig = ComposeUiTestConfig(
        failurePolicy = TestFailurePolicy(
            screenshotCaptureMode = TestFailurePolicy.CaptureMode.Enabled,
            failureHandlers = listOf(
                TestFailureHandler { context ->
                    val screenshot = context.artifacts.firstOrNull {
                        it.type == FailureArtifact.Type.Screenshot
                    }
                    // ...
                }
            )
        )
    )

    @get:Rule
    val rule = createComposeRule(config = customConfig)

    // ...
}

Tüm test paketi için yakalamaları yapılandırma

Modülünüzün build.gradle dosyasına araç çalıştırma bağımsız değişkenleri ileterek tüm test paketi için hata yapay öğesi yakalamayı etkinleştirebilirsiniz. Bu sayede, test dosyalarını tek tek güncellemeniz gerekmez.

// build.gradle.kts
android {
    defaultConfig {
        // ...
        testInstrumentationRunnerArguments["androidx.compose.ui.test.failure.isUiHierarchyCaptureEnabled"] = "true"
        testInstrumentationRunnerArguments["androidx.compose.ui.test.failure.isScreenshotCaptureEnabled"] = "true"
    }
}

Yapılandırma önceliği

Çerçeve, hem yerel TestFailurePolicy hem de paket düzeyindeki çalıştırıcı bağımsız değişkenlerini değerlendirir:

  • Testinizde failurePolicy bir modu açıkça CaptureMode.Enabled/Disabled olarak ayarlarsanız bu, çalıştırıcı bağımsız değişkenini geçersiz kılar.
  • Bir modu CaptureMode.Unspecified olarak ayarlarsanız (veya failurePolicy değerini null olarak bırakırsanız) çerçeve, çalıştırıcı bağımsız değişkenine geri döner.

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.