Parçalarınızı test etme

Bu konuda, her bir parçanın davranışını değerlendiren testlere çerçeve tarafından sağlanan API'lerin nasıl dahil edileceği açıklanmaktadır.

Parçalar, uygulamanızda yeniden kullanılabilir kapsayıcılar görevi görür. Böylece, çeşitli etkinlikler ve düzen yapılandırmalarında aynı kullanıcı arayüzü düzenini sunabilirsiniz. Parçaların çok yönlülüğü göz önünde bulundurulduğunda, tutarlı ve kaynak verimliliği yüksek bir deneyim sağladıklarını doğrulamak önemlidir. Aşağıdakileri göz önünde bulundurun:

  • Parçanız, belirli bir üst etkinliğe veya parçaya bağlı olmamalıdır.
  • Parça kullanıcı tarafından görülmediği sürece parçanın görünüm hiyerarşisini oluşturmamalısınız.

Bu testlerin yürütülmesi için koşulların ayarlanmasına yardımcı olmak amacıyla AndroidX fragment-testing kitaplığı, parça oluşturma ve Lifecycle.State değiştirme işlemlerini yapabileceğiniz FragmentScenario sınıfını sağlar.

Bağımlılıkları bildirme

FragmentScenario öğesini kullanmak için uygulamanızın build.gradle dosyasında fragment-testing-manifest yapısını debugImplementation kullanarak, fragment-testing yapısını ise aşağıdaki örnekte gösterildiği gibi androidTestImplementation kullanarak tanımlayın:

Modern

dependencies {
    def fragment_version = "1.8.1"

    debugImplementation "androidx.fragment:fragment-testing-manifest:$fragment_version"

    androidTestImplementation "androidx.fragment:fragment-testing:$fragment_version"
}

Kotlin

dependencies {
    val fragment_version = "1.8.1"

    debugImplementation("androidx.fragment:fragment-testing-manifest:$fragment_version")

    androidTestImplementation("androidx.fragment:fragment-testing:$fragment_version")
}

Bu sayfadaki örnekleri test etmek için Espresso ve Truth kitaplıklarındaki onaylar kullanılır. Kullanabileceğiniz diğer test ve onay kitaplıkları hakkında bilgi edinmek için AndroidX Test için proje oluşturma bölümüne bakın.

Parça oluşturma

FragmentScenario, parçaları testlerde başlatmak için aşağıdaki yöntemleri içerir:

  • Bir parçanın kullanıcı arayüzünü test etmek için launchInContainer(). FragmentScenario, parçayı bir etkinliğin kök görünüm denetleyicisine ekler. Aksi takdirde bu içeren etkinlik boş olur.
  • launch(), parçanın kullanıcı arayüzü olmadan test edilmesi için kullanılır. FragmentScenario, bu parçayı kök görünümüne sahip olmayan bir boş etkinliğe ekler.

FragmentScenario, bu parça türlerinden birini başlattıktan sonra test edilen parçayı belirtilen bir duruma yönlendirir. Bu durum varsayılan olarak RESUMED şeklindedir ancak initialState bağımsız değişkeniyle bunu geçersiz kılabilirsiniz. RESUMED durumu, parçanın çalıştığını ve kullanıcı tarafından görülebildiğini belirtir. Espresso kullanıcı arayüzü testlerini kullanarak kullanıcı arayüzü öğeleriyle ilgili bilgileri değerlendirebilirsiniz.

Aşağıdaki kod örnekleri, her bir yöntemi kullanarak parçanızı nasıl başlatacağınızı gösterir:

launchInContainer() örneği

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEventFragment() {
        // The "fragmentArgs" argument is optional.
        val fragmentArgs = bundleOf(“selectedListItem” to 0)
        val scenario = launchFragmentInContainer<EventFragment>(fragmentArgs)
        ...
    }
}

launch() örneği

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEventFragment() {
        // The "fragmentArgs" arguments are optional.
        val fragmentArgs = bundleOf("numElements" to 0)
        val scenario = launchFragment<EventFragment>(fragmentArgs)
        ...
    }
}

Bağımlılıkları belirtme

Parçalarınızın bağımlılıkları varsa launchInContainer() veya launch() yöntemlerine özel bir FragmentFactory sağlayarak bu bağımlılıkların test sürümlerini sağlayabilirsiniz.

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEventFragment() {
        val someDependency = TestDependency()
        launchFragmentInContainer {
            EventFragment(someDependency)
        }
        ...
    }
}

Parçalara bağımlılık sağlamak üzere FragmentFactory kullanımı hakkında daha fazla bilgi için Parça yöneticisi'ne bakın.

Parçayı yeni bir duruma sürün

Uygulamanızın kullanıcı arayüzü testlerinde, genellikle test altındaki parçayı başlatmak ve RESUMED durumundan test etmeye başlamak yeterlidir. Bununla birlikte, daha ayrıntılı birim testlerinde parçanın bir yaşam döngüsü durumundan diğerine geçiş yaparken sergilediği davranışı da değerlendirebilirsiniz. Başlangıç durumunu, initialState bağımsız değişkenini launchFragment*() işlevlerinden herhangi birine geçirerek belirtebilirsiniz.

Parçayı farklı bir yaşam döngüsü durumuna getirmek için moveToState() çağrısı yapın. Bu yöntem, bağımsız değişken olarak şu durumları destekler: CREATED, STARTED, RESUMED ve DESTROYED. Bu yöntem, parçanızı içeren parçanın veya etkinliğin herhangi bir nedenle durumunu değiştirdiği durumu simüle eder.

Aşağıdaki örnek, bir test parçasını INITIALIZED durumunda başlatır ve ardından RESUMED durumuna taşır:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEventFragment() {
        val scenario = launchFragmentInContainer<EventFragment>(
            initialState = Lifecycle.State.INITIALIZED
        )
        // EventFragment has gone through onAttach(), but not onCreate().
        // Verify the initial state.
        scenario.moveToState(Lifecycle.State.RESUMED)
        // EventFragment moves to CREATED -> STARTED -> RESUMED.
        ...
    }
}

Parçayı yeniden oluştur

Uygulamanız kaynakları az olan bir cihazda çalışıyorsa sistem, parçanızı içeren etkinliği kaldırabilir. Bu durum, kullanıcı parçaya geri döndüğünde uygulamanızın parçayı yeniden oluşturmasını gerektirir. Bu durumu simüle etmek için recreate() çağırın:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEventFragment() {
        val scenario = launchFragmentInContainer<EventFragment>()
        scenario.recreate()
        ...
    }
}

FragmentScenario.recreate(), parçayı ve ana makinesini kaldırır ve ardından yeniden oluşturur. FragmentScenario sınıfı test edilen parçayı yeniden oluşturduğunda, parça imha edilmeden önceki yaşam döngüsü durumuna geri döner.

Kullanıcı arayüzü parçalarıyla etkileşim

Test altındaki parçanızda kullanıcı arayüzü işlemlerini tetiklemek için Espresso görünüm eşleştiricilerini kullanarak görünümünüzdeki öğelerle etkileşimde bulunun:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEventFragment() {
        val scenario = launchFragmentInContainer<EventFragment>()
        onView(withId(R.id.refresh)).perform(click())
        // Assert some expected behavior
        ...
    }
}

Seçenekler menüsündeki bir seçime yanıt vermek gibi parçanın kendi üzerinde bir yöntem çağırmanız gerekirse bunu FragmentScenario.onFragment() kullanarak parçaya referans alıp bir FragmentAction ileterek güvenli bir şekilde yapabilirsiniz:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEventFragment() {
        val scenario = launchFragmentInContainer<EventFragment>()
        scenario.onFragment { fragment ->
            fragment.myInstanceMethod()
        }
    }
}

İletişim kutusu işlemlerini test etme

FragmentScenario, iletişim parçalarının test edilmesini de destekler. İletişim kutusu parçalarında kullanıcı arayüzü öğeleri bulunsa da, bunların düzeni etkinliğin kendisi yerine ayrı bir pencerede doldurulur. Bu nedenle, iletişim kutusu parçalarını test etmek için FragmentScenario.launch() kullanın.

Aşağıdaki örnekte iletişim kutusu kapatma işlemi test edilmektedir:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testDismissDialogFragment() {
        // Assumes that "MyDialogFragment" extends the DialogFragment class.
        with(launchFragment<MyDialogFragment>()) {
            onFragment { fragment ->
                assertThat(fragment.dialog).isNotNull()
                assertThat(fragment.requireDialog().isShowing).isTrue()
                fragment.dismiss()
                fragment.parentFragmentManager.executePendingTransactions()
                assertThat(fragment.dialog).isNull()
            }
        }

        // Assumes that the dialog had a button
        // containing the text "Cancel".
        onView(withText("Cancel")).check(doesNotExist())
    }
}