قطعات خود را تست کنید

این مبحث نحوه گنجاندن API های ارائه شده توسط چارچوب را در تست هایی که رفتار هر قطعه را ارزیابی می کند، توضیح می دهد.

قطعات به‌عنوان محفظه‌های قابل استفاده مجدد در برنامه شما عمل می‌کنند و به شما امکان می‌دهند طرح‌بندی رابط کاربری مشابهی را در انواع فعالیت‌ها و پیکربندی‌های طرح‌بندی ارائه کنید. با توجه به تطبیق پذیری قطعات، مهم است که تأیید کنیم که آنها یک تجربه ثابت و کارآمد از نظر منابع را ارائه می دهند. به موارد زیر توجه کنید:

  • قطعه شما نباید به فعالیت یا قطعه خاصی وابسته باشد.
  • شما نباید سلسله مراتب نمای یک قطعه را ایجاد کنید مگر اینکه قطعه برای کاربر قابل مشاهده باشد.

برای کمک به تنظیم شرایط برای انجام این آزمایش‌ها، کتابخانه fragment-testing AndroidX کلاس FragmentScenario را برای ایجاد قطعات و تغییر Lifecycle.State آنها ارائه می‌کند.

اعلام وابستگی ها

برای استفاده از FragmentScenario آرتیفکت fragment-testing-manifest را در فایل build.gradle برنامه خود با استفاده از debugImplementation و مصنوع fragment-testing با استفاده از androidTestImplementation تعریف کنید، همانطور که در مثال زیر نشان داده شده است:

شیار
dependencies {
    def fragment_version = "1.8.3"

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

    androidTestImplementation "androidx.fragment:fragment-testing:$fragment_version"
}
کاتلین
dependencies {
    val fragment_version = "1.8.3"

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

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

نمونه‌های آزمایشی در این صفحه از اظهارات موجود در کتابخانه‌های اسپرسو و حقیقت استفاده می‌کنند. برای اطلاعات در مورد دیگر کتابخانه‌های آزمایشی و ادعایی موجود، به راه‌اندازی پروژه برای AndroidX Test مراجعه کنید.

یک قطعه ایجاد کنید

FragmentScenario شامل روش‌های زیر برای راه‌اندازی قطعات در آزمایش‌ها است:

  • launchInContainer() برای آزمایش رابط کاربری یک قطعه. FragmentScenario قطعه را به کنترل کننده نمای ریشه یک اکتیویتی متصل می کند. این فعالیت حاوی در غیر این صورت خالی است.
  • launch() برای آزمایش بدون رابط کاربری قطعه. FragmentScenario این نوع قطعه را به یک اکتیویتی خالی متصل می کند، فعالیتی که نمای ریشه ندارد.

پس از راه‌اندازی یکی از این نوع قطعات، FragmentScenario قطعه مورد آزمایش را به وضعیت مشخصی هدایت می‌کند. به طور پیش‌فرض این حالت RESUMED است، اما می‌توانید با آرگومان initialState آن را لغو کنید. حالت RESUMED نشان می دهد که قطعه در حال اجرا است و برای کاربر قابل مشاهده است. می توانید اطلاعات مربوط به عناصر UI آن را با استفاده از تست های Espresso UI ارزیابی کنید.

مثال‌های کد زیر نحوه راه‌اندازی قطعه خود را با استفاده از هر روش نشان می‌دهند:

نمونه () launchInContainer

@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

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEventFragment() {
        // The "fragmentArgs" arguments are optional.
        val fragmentArgs = bundleOf("numElements" to 0)
        val scenario = launchFragment<EventFragment>(fragmentArgs)
        ...
    }
}
وابستگی ها را فراهم کنید

اگر فرگمنت‌های شما وابستگی دارند، می‌توانید نسخه‌های آزمایشی این وابستگی‌ها را با ارائه یک FragmentFactory سفارشی به متدهای launchInContainer() یا launch() ارائه دهید.

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

برای اطلاعات بیشتر در مورد استفاده از FragmentFactory برای ارائه وابستگی به قطعات، به مدیر بخش مراجعه کنید.

قطعه را به حالت جدیدی هدایت کنید

در آزمایش‌های رابط کاربری برنامه‌تان، معمولاً کافی است قطعه مورد آزمایش را راه‌اندازی کنید و آزمایش آن را از حالت RESUMED شروع کنید. با این حال، در آزمایش‌های واحد با دانه‌ریزی، ممکن است رفتار قطعه را در هنگام انتقال از یک حالت چرخه حیات به حالت دیگر ارزیابی کنید. می توانید با ارسال آرگومان initialState به هر یک از توابع launchFragment*() وضعیت اولیه را مشخص کنید.

برای هدایت قطعه به حالت چرخه حیات متفاوت، moveToState() را فراخوانی کنید. این روش از حالت های زیر به عنوان آرگومان پشتیبانی می کند: CREATED ، STARTED ، RESUMED و DESTROYED . این روش موقعیتی را شبیه سازی می کند که قطعه یا اکتیویتی حاوی قطعه شما به هر دلیلی حالت خود را تغییر می دهد.

مثال زیر یک قطعه تست را در حالت INITIALIZED راه اندازی می کند و سپس آن را به حالت RESUMED منتقل می کند:

@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.
        ...
    }
}
قطعه را دوباره بسازید

اگر برنامه شما روی دستگاهی اجرا می شود که منابع کمی دارد، سیستم ممکن است فعالیت حاوی قطعه شما را از بین ببرد. این وضعیت به برنامه شما نیاز دارد که وقتی کاربر به آن برمی‌گردد قطعه را دوباره ایجاد کند. برای شبیه سازی این وضعیت، recreate() فراخوانی کنید:

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

FragmentScenario.recreate() قطعه و میزبان آن را از بین می برد و سپس آنها را دوباره ایجاد می کند. هنگامی که کلاس FragmentScenario قطعه مورد آزمایش را دوباره ایجاد می کند، قطعه به حالت چرخه حیاتی که قبل از نابودی در آن قرار داشت، برمی گردد.

تعامل با قطعات UI

برای فعال کردن عملکردهای UI در قطعه تحت آزمایش خود، از تطبیق‌کنندگان نمای اسپرسو برای تعامل با عناصر موجود در نمای خود استفاده کنید:

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

اگر نیاز به فراخوانی متدی در خود قطعه دارید، مانند پاسخ دادن به یک انتخاب در منوی گزینه‌ها، می‌توانید با استفاده از FragmentScenario.onFragment() و ارسال در یک FragmentAction ، این کار را با خیال راحت انجام دهید:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEventFragment() {
        val scenario = launchFragmentInContainer<EventFragment>()
        scenario.onFragment { fragment ->
            fragment.myInstanceMethod()
        }
    }
}
آزمایش اقدامات گفتگو

FragmentScenario همچنین از تست قطعات گفتگو پشتیبانی می کند. اگرچه قطعات گفتگو دارای عناصر UI هستند، طرح آنها به جای خود فعالیت در یک پنجره جداگانه پر می شود. به همین دلیل، از FragmentScenario.launch() برای تست قطعات گفتگو استفاده کنید.

مثال زیر فرآیند حذف گفتگو را آزمایش می کند:

@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())
    }
}