فعالیت های برنامه خود را آزمایش کنید

فعالیت‌ها به‌عنوان محفظه‌هایی برای هر تعامل کاربر در برنامه شما عمل می‌کنند، بنابراین مهم است که نحوه عملکرد فعالیت‌های برنامه‌تان را در طول رویدادهای سطح دستگاه مانند موارد زیر آزمایش کنید:

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

به ویژه، مهم است که اطمینان حاصل کنید که فعالیت شما در پاسخ به رویدادهای شرح داده شده در چرخه حیات فعالیت، به درستی رفتار می کند.

این راهنما نحوه ارزیابی توانایی برنامه شما برای حفظ یکپارچگی داده ها و تجربه کاربری خوب را در حین انتقال فعالیت های برنامه شما از طریق حالت های مختلف در چرخه عمرشان توضیح می دهد.

حالت یک فعالیت را هدایت کنید

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

ActivityScenario یک API بین پلتفرمی است که می‌توانید از آن در تست‌های واحد محلی و تست‌های یکپارچه‌سازی روی دستگاه استفاده کنید. در یک دستگاه واقعی یا مجازی، ActivityScenario ایمنی رشته را فراهم می کند، رویدادها را بین رشته ابزار دقیق تست شما و رشته ای که فعالیت شما را تحت آزمایش اجرا می کند، همگام می کند.

API به ویژه برای ارزیابی نحوه رفتار یک فعالیت تحت آزمایش در هنگام تخریب یا ایجاد آن مناسب است. این بخش رایج ترین موارد استفاده مرتبط با این API را ارائه می دهد.

یک فعالیت ایجاد کنید

برای ایجاد فعالیت تحت آزمایش، کد نشان داده شده در قطعه زیر را اضافه کنید:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEvent() {
       launchActivity<MyActivity>().use {
       }
    }
}

پس از ایجاد اکتیویتی، ActivityScenario اکتیویتی را به حالت RESUMED انتقال می دهد. این حالت نشان می دهد که فعالیت شما در حال اجرا است و برای کاربران قابل مشاهده است. در این حالت، می‌توانید با استفاده از تست‌های Espresso UI با عناصر View فعالیت خود تعامل داشته باشید.

Google توصیه می‌کند که پس از اتمام آزمایش، با فعالیت close بگیرید. این کار منابع مرتبط را پاک می کند و پایداری تست های شما را بهبود می بخشد. ActivityScenario Closeable را پیاده سازی می کند، بنابراین می توانید پسوند use یا try-with-resources در زبان برنامه نویسی جاوا اعمال کنید تا فعالیت به طور خودکار بسته شود.

از طرف دیگر، می‌توانید از ActivityScenarioRule برای فراخوانی خودکار ActivityScenario.launch قبل از هر آزمایش و ActivityScenario.close در زمان حذف آزمایشی استفاده کنید. مثال زیر نحوه تعریف یک قانون و گرفتن نمونه ای از یک سناریو را از آن نشان می دهد:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @get:Rule var activityScenarioRule = activityScenarioRule<MyActivity>()

    @Test fun testEvent() {
        val scenario = activityScenarioRule.scenario
    }
}

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

برای هدایت اکتیویتی به حالت دیگری، مانند CREATED یا STARTED ، با moveToState() تماس بگیرید. این عمل موقعیتی را شبیه‌سازی می‌کند که در آن فعالیت شما به ترتیب متوقف یا متوقف می‌شود، زیرا توسط یک برنامه دیگر یا یک عملکرد سیستم قطع شده است.

نمونه ای از استفاده از moveToState() در قطعه کد زیر ظاهر می شود:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEvent() {
        launchActivity<MyActivity>().use { scenario ->
            scenario.moveToState(State.CREATED)
        }
    }
}

وضعیت فعلی فعالیت را تعیین کنید

برای تعیین وضعیت فعلی یک اکتیویتی تحت آزمایش، مقدار فیلد state را در شی ActivityScenario خود بدست آورید. اگر فعالیت به فعالیت دیگری هدایت شود یا خودش تمام شود، همانطور که در قطعه کد زیر نشان داده شده است، بررسی وضعیت یک فعالیت تحت آزمایش بسیار مفید است:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEvent() {
        launchActivity<MyActivity>().use { scenario ->
            scenario.onActivity { activity ->
              startActivity(Intent(activity, MyOtherActivity::class.java))
            }

            val originalActivityState = scenario.state
        }
    }
}

فعالیت را دوباره ایجاد کنید

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

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEvent() {
        launchActivity<MyActivity>().use { scenario ->
            scenario.recreate()
        }
    }
}

کلاس ActivityScenario وضعیت نمونه ذخیره شده اکتیویتی و هر شیء حاشیه نویسی شده با استفاده از @NonConfigurationInstance را حفظ می کند. این اشیاء در نمونه جدید فعالیت تحت آزمایش شما بارگیری می شوند.

بازیابی نتایج فعالیت

برای دریافت کد نتیجه یا داده های مرتبط با یک فعالیت تمام شده، مقدار فیلد result را در شی ActivityScenario خود، همانطور که در قطعه کد زیر نشان داده شده است، دریافت کنید:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testResult() {
        launchActivity<MyActivity>().use {
            onView(withId(R.id.finish_button)).perform(click())

            // Activity under test is now finished.

            val resultCode = scenario.result.resultCode
            val resultData = scenario.result.resultData
        }
    }
}

فعال کردن اقدامات در فعالیت

همه روش‌های موجود در ActivityScenario تماس‌ها را مسدود می‌کنند، بنابراین API از شما می‌خواهد که آنها را در رشته ابزار دقیق اجرا کنید.

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

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEvent() {
        launchActivity<MyActivity>().use {
            onView(withId(R.id.refresh)).perform(click())
        }
    }
}

با این حال، اگر نیاز به فراخوانی متدی در خود اکتیویتی دارید، می‌توانید با اجرای ActivityAction این کار را با خیال راحت انجام دهید:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEvent() {
        launchActivity<MyActivity>().use { scenario ->
            scenario.onActivity { activity ->
              activity.handleSwipeToRefresh()
            }
        }
    }
}