این مبحث نحوه گنجاندن 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 در قطعه تحت آزمایش خود، از تطبیقکنندگان نمای اسپرسو برای تعامل با عناصر موجود در نمای خود استفاده کنید:
@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())
}
}