বিভিন্ন স্ক্রীন মাপ পরীক্ষা করার জন্য লাইব্রেরি এবং টুল

Android বিভিন্ন ধরনের টুল এবং API প্রদান করে যা আপনাকে বিভিন্ন স্ক্রীন এবং উইন্ডো আকারের জন্য পরীক্ষা তৈরি করতে সাহায্য করতে পারে।

ডিভাইস কনফিগারেশন ওভাররাইড

DeviceConfigurationOverride composable আপনাকে কম্পোজ লেআউটে একাধিক স্ক্রীন এবং উইন্ডোর আকার পরীক্ষা করতে কনফিগারেশন বৈশিষ্ট্যগুলিকে ওভাররাইড করতে দেয়। ForcedSize ওভাররাইড উপলব্ধ স্থানের যেকোনো বিন্যাসের সাথে ফিট করে, যা আপনাকে যেকোনো স্ক্রীন আকারে যেকোনো UI পরীক্ষা চালাতে দেয়। উদাহরণস্বরূপ, বড় ফোন, ফোল্ডেবল এবং ট্যাবলেটগুলির জন্য UI পরীক্ষা সহ আপনার সমস্ত UI পরীক্ষা চালানোর জন্য আপনি একটি ছোট ফোন ফর্ম ফ্যাক্টর ব্যবহার করতে পারেন।

   DeviceConfigurationOverride(
        DeviceConfigurationOverride.ForcedSize(DpSize(1280.dp, 800.dp))
    ) {
        MyScreen() // Will be rendered in the space for 1280dp by 800dp without clipping.
    }
চিত্র 1. একটি ছোট ফর্ম ফ্যাক্টর ডিভাইসের ভিতরে একটি ট্যাবলেট লেআউট ফিট করতে DeviceConfigurationOverride ব্যবহার করে, যেমন \*Now Android-এ।

উপরন্তু, আপনি এই সংমিশ্রণযোগ্য ফন্ট স্কেল, থিম এবং অন্যান্য বৈশিষ্ট্য সেট করতে ব্যবহার করতে পারেন যা আপনি বিভিন্ন উইন্ডো আকারে পরীক্ষা করতে চান।

রোবোলেক্ট্রিক

স্থানীয়ভাবে JVM-এ রচনা বা ভিউ-ভিত্তিক UI পরীক্ষা চালানোর জন্য Robolectric ব্যবহার করুন—কোনও ডিভাইস বা এমুলেটরের প্রয়োজন নেই। আপনি অন্যান্য দরকারী বৈশিষ্ট্যগুলির মধ্যে নির্দিষ্ট স্ক্রিন আকারগুলি ব্যবহার করার জন্য Robolectric কনফিগার করতে পারেন।

Android-এ Now থেকে নিম্নলিখিত উদাহরণে , Robolectric 480 dpi এর রেজোলিউশনের সাথে 1000x1000 dp এর স্ক্রীন সাইজ অনুকরণ করতে কনফিগার করা হয়েছে:

@RunWith(RobolectricTestRunner::class)
// Configure Robolectric to use a very large screen size that can fit all of the test sizes.
// This allows enough room to render the content under test without clipping or scaling.
@Config(qualifiers = "w1000dp-h1000dp-480dpi")
class NiaAppScreenSizesScreenshotTests { ... }

এছাড়াও আপনি পরীক্ষার বডি থেকে কোয়ালিফায়ার সেট করতে পারেন যেমনটি করা হয়েছে এই স্নিপেটে নাও ইন অ্যান্ড্রয়েড উদাহরণ থেকে:

val (width, height, dpi) = ...

// Set qualifiers from specs.
RuntimeEnvironment.setQualifiers("w${width}dp-h${height}dp-${dpi}dpi")

মনে রাখবেন যে RuntimeEnvironment.setQualifiers() নতুন কনফিগারেশনের সাথে সিস্টেম এবং অ্যাপ্লিকেশন সংস্থানগুলিকে আপডেট করে কিন্তু সক্রিয় কার্যকলাপ বা অন্যান্য উপাদানগুলিতে কোনও ক্রিয়া ট্রিগার করে না।

আপনি রোবোলেক্ট্রিক ডিভাইস কনফিগারেশন ডকুমেন্টেশনে আরও পড়তে পারেন।

গ্রেডল-পরিচালিত ডিভাইস

Gradle-পরিচালিত ডিভাইসগুলি (GMD) Android Gradle প্লাগইন আপনাকে এমুলেটর এবং বাস্তব ডিভাইসগুলির স্পেসিফিকেশন সংজ্ঞায়িত করতে দেয় যেখানে আপনার ইন্সট্রুমেন্টেড পরীক্ষা চালানো হয়। একটি টেস্টিং কৌশল বাস্তবায়নের জন্য বিভিন্ন স্ক্রীন মাপের ডিভাইসগুলির জন্য স্পেসিফিকেশন তৈরি করুন যেখানে নির্দিষ্ট পরীক্ষাগুলি নির্দিষ্ট স্ক্রীন আকারে চালানো উচিত। কন্টিনিউয়াস ইন্টিগ্রেশন (CI) এর সাথে GMD ব্যবহার করে, আপনি নিশ্চিত করতে পারেন যে উপযুক্ত পরীক্ষাগুলি যখন প্রয়োজন হয়, প্রভিশন এবং এমুলেটর চালু করা এবং আপনার CI সেটআপকে সরল করা হয়।

android {
    testOptions {
        managedDevices {
            devices {
                // Run with ./gradlew nexusOneApi30DebugAndroidTest.
                nexusOneApi30(com.android.build.api.dsl.ManagedVirtualDevice) {
                    device = "Nexus One"
                    apiLevel = 30
                    // Use the AOSP ATD image for better emulator performance
                    systemImageSource = "aosp-atd"
                }
                // Run with ./gradlew  foldApi34DebugAndroidTest.
                foldApi34(com.android.build.api.dsl.ManagedVirtualDevice) {
                    device = "Pixel Fold"
                    apiLevel = 34
                    systemImageSource = "aosp-atd"
                }
            }
        }
    }
}

আপনি পরীক্ষা-নমুনা প্রকল্পে GMD এর একাধিক উদাহরণ খুঁজে পেতে পারেন।

ফায়ারবেস টেস্ট ল্যাব

ফায়ারবেস টেস্ট ল্যাব (FTL), বা অনুরূপ ডিভাইস ফার্ম পরিষেবা ব্যবহার করুন, নির্দিষ্ট বাস্তব ডিভাইসগুলিতে আপনার পরীক্ষা চালানোর জন্য যা আপনার অ্যাক্সেস নাও থাকতে পারে, যেমন ফোল্ডেবল বা বিভিন্ন আকারের ট্যাবলেট। Firebase Test Lab হল একটি বিনামূল্যের স্তর সহ একটি অর্থপ্রদানের পরিষেবা ৷ FTL এমুলেটরগুলিতে চলমান পরীক্ষাগুলিকেও সমর্থন করে। এই পরিষেবাগুলি যন্ত্রযুক্ত পরীক্ষার নির্ভরযোগ্যতা এবং গতিকে উন্নত করে কারণ তারা সময়ের আগেই ডিভাইস এবং এমুলেটর সরবরাহ করতে পারে।

GMD-এর সাথে FTL ব্যবহার সম্পর্কে তথ্যের জন্য, Gradle-পরিচালিত ডিভাইসগুলির সাথে আপনার পরীক্ষাগুলি স্কেল করুন দেখুন।

টেস্ট রানার দিয়ে পরীক্ষা ফিল্টারিং

একটি সর্বোত্তম পরীক্ষার কৌশল একই জিনিস দুইবার যাচাই করা উচিত নয়, তাই আপনার বেশিরভাগ UI পরীক্ষার একাধিক ডিভাইসে চালানোর প্রয়োজন নেই। সাধারণত, আপনি একটি ফোন ফর্ম ফ্যাক্টর এবং বিভিন্ন স্ক্রীন আকারের ডিভাইসে শুধুমাত্র একটি উপসেট চালানোর মাধ্যমে আপনার UI পরীক্ষাগুলি ফিল্টার করেন।

আপনি শুধুমাত্র নির্দিষ্ট ডিভাইসগুলির সাথে চালানোর জন্য নির্দিষ্ট পরীক্ষাগুলিকে টীকা করতে পারেন এবং তারপরে পরীক্ষাগুলি চালানোর কমান্ডটি ব্যবহার করে AndroidJUnitRunner এর কাছে একটি যুক্তি পাস করতে পারেন৷

উদাহরণস্বরূপ, আপনি বিভিন্ন টীকা তৈরি করতে পারেন:

annotation class TestExpandedWidth
annotation class TestCompactWidth

এবং বিভিন্ন পরীক্ষায় তাদের ব্যবহার করুন:

class MyTestClass {

    @Test
    @TestExpandedWidth
    fun myExample_worksOnTablet() {
        ...
    }

    @Test
    @TestCompactWidth
    fun myExample_worksOnPortraitPhone() {
        ...
    }

}

তারপর নির্দিষ্ট ফিল্টার করার জন্য পরীক্ষা চালানোর সময় আপনি android.testInstrumentationRunnerArguments.annotation বৈশিষ্ট্য ব্যবহার করতে পারেন। উদাহরণস্বরূপ, যদি আপনি Gradle-পরিচালিত ডিভাইসগুলি ব্যবহার করেন:

$ ./gradlew pixelTabletApi30DebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.annotation='com.sample.TestExpandedWidth'

আপনি যদি জিএমডি ব্যবহার না করেন এবং আপনি সিআই-তে এমুলেটরগুলি পরিচালনা করেন, প্রথমে নিশ্চিত করুন যে সঠিক এমুলেটর বা ডিভাইসটি প্রস্তুত এবং সংযুক্ত আছে এবং তারপরে ইন্সট্রুমেন্টেড পরীক্ষা চালানোর জন্য গ্রেডল কমান্ডগুলির একটিতে প্যারামিটারটি পাস করুন:

$ ./gradlew connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.annotation='com.sample.TestExpandedWidth'

মনে রাখবেন যে Espresso ডিভাইস (পরবর্তী বিভাগ দেখুন) ডিভাইস বৈশিষ্ট্য ব্যবহার করে পরীক্ষা ফিল্টার করতে পারে।

এসপ্রেসো ডিভাইস

এসপ্রেসো, কম্পোজ, বা UI অটোমেটর পরীক্ষা সহ যেকোন ধরণের ইন্সট্রুমেন্টেড পরীক্ষা ব্যবহার করে পরীক্ষায় এমুলেটরগুলিতে ক্রিয়া সম্পাদন করতে এসপ্রেসো ডিভাইস ব্যবহার করুন। এই ক্রিয়াগুলির মধ্যে স্ক্রিনের আকার সেট করা বা ভাঁজযোগ্য অবস্থা বা ভঙ্গি টগল করা অন্তর্ভুক্ত থাকতে পারে। উদাহরণস্বরূপ, আপনি একটি ভাঁজযোগ্য এমুলেটর নিয়ন্ত্রণ করতে পারেন এবং এটিকে ট্যাবলেটপ মোডে সেট করতে পারেন। এসপ্রেসো ডিভাইসে কিছু বৈশিষ্ট্যের প্রয়োজনের জন্য JUnit নিয়ম এবং টীকাও রয়েছে:

@RunWith(AndroidJUnit4::class)
class OnDeviceTest {

    @get:Rule(order=1) val activityScenarioRule = activityScenarioRule<MainActivity>()

    @get:Rule(order=2) val screenOrientationRule: ScreenOrientationRule =
        ScreenOrientationRule(ScreenOrientation.PORTRAIT)

    @Test
    fun tabletopMode_playerIsDisplayed() {
        // Set the device to tabletop mode.
        onDevice().setTabletopMode()
        onView(withId(R.id.player)).check(matches(isDisplayed()))
    }
}

মনে রাখবেন যে এসপ্রেসো ডিভাইস এখনও আলফা পর্যায়ে রয়েছে এবং এর নিম্নলিখিত প্রয়োজনীয়তা রয়েছে:

  • অ্যান্ড্রয়েড গ্রেডল প্লাগইন 8.3 বা উচ্চতর
  • Android এমুলেটর 33.1.10 বা উচ্চতর
  • Android ভার্চুয়াল ডিভাইস যা API স্তর 24 বা উচ্চতর চালায়

ফিল্টার পরীক্ষা

এসপ্রেসো ডিভাইস আপনাকে টীকা ব্যবহার করে পরীক্ষা ফিল্টার করতে সক্ষম করতে সংযুক্ত ডিভাইসের বৈশিষ্ট্যগুলি পড়তে পারে। টীকা করা প্রয়োজনীয়তা পূরণ না হলে, পরীক্ষাগুলি বাদ দেওয়া হয়।

ডিভাইসমোড টীকা প্রয়োজন

RequiresDeviceMode টীকাটি এমন একটি পরীক্ষা নির্দেশ করতে একাধিকবার ব্যবহার করা যেতে পারে যা ডিভাইসে সমস্ত DeviceMode মান সমর্থিত হলেই চলবে৷

class OnDeviceTest {
    ...
    @Test
    @RequiresDeviceMode(TABLETOP)
    @RequiresDeviceMode(BOOK)
    fun tabletopMode_playerIdDisplayed() {
        // Set the device to tabletop mode.
        onDevice().setTabletopMode()
        onView(withId(R.id.player)).check(matches(isDisplayed()))
    }
}

ডিসপ্লে টীকা প্রয়োজন

RequiresDisplay টীকা আপনাকে সাইজ ক্লাস ব্যবহার করে ডিভাইস স্ক্রিনের প্রস্থ এবং উচ্চতা নির্দিষ্ট করতে দেয়, যা অফিসিয়াল উইন্ডো সাইজ ক্লাসগুলি অনুসরণ করে ডাইমেনশন বাকেটগুলিকে সংজ্ঞায়িত করে৷

class OnDeviceTest {
    ...
    @Test
    @RequiresDisplay(EXPANDED, COMPACT)
    fun myScreen_expandedWidthCompactHeight() {
        ...
    }
}

প্রদর্শনের আকার পরিবর্তন করুন

রানটাইমে স্ক্রিনের মাত্রা পরিবর্তন করতে setDisplaySize() পদ্ধতি ব্যবহার করুন। DisplaySizeRule ক্লাসের সাথে একত্রে পদ্ধতিটি ব্যবহার করুন, যা নিশ্চিত করে যে পরীক্ষার সময় করা যেকোনো পরিবর্তন পরবর্তী পরীক্ষার আগে পূর্বাবস্থায় ফেরানো হয়েছে।

@RunWith(AndroidJUnit4::class)
class ResizeDisplayTest {

    @get:Rule(order = 1) val activityScenarioRule = activityScenarioRule<MainActivity>()

    // Test rule for restoring device to its starting display size when a test case finishes.
    @get:Rule(order = 2) val displaySizeRule: DisplaySizeRule = DisplaySizeRule()

    @Test
    fun resizeWindow_compact() {
        onDevice().setDisplaySize(
            widthSizeClass = WidthSizeClass.COMPACT,
            heightSizeClass = HeightSizeClass.COMPACT
        )
        // Verify visual attributes or state restoration.
    }
}

আপনি যখন setDisplaySize() দিয়ে একটি প্রদর্শনের আকার পরিবর্তন করেন, তখন আপনি ডিভাইসের ঘনত্বকে প্রভাবিত করেন না, তাই যদি একটি মাত্রা লক্ষ্য ডিভাইসে ফিট না হয়, তাহলে পরীক্ষাটি UnsupportedDeviceOperationException সাথে ব্যর্থ হয়। এই ক্ষেত্রে পরীক্ষাগুলি চালানো থেকে প্রতিরোধ করতে, সেগুলিকে ফিল্টার করতে RequiresDisplay টীকা ব্যবহার করুন:

@RunWith(AndroidJUnit4::class)
class ResizeDisplayTest {

    @get:Rule(order = 1) var activityScenarioRule = activityScenarioRule<MainActivity>()

    // Test rule for restoring device to its starting display size when a test case finishes.
    @get:Rule(order = 2) var displaySizeRule: DisplaySizeRule = DisplaySizeRule()

    /**
     * Setting the display size to EXPANDED would fail in small devices, so the [RequiresDisplay]
     * annotation prevents this test from being run on devices outside the EXPANDED buckets.
     */
    @RequiresDisplay(
        widthSizeClass = WidthSizeClassEnum.EXPANDED,
        heightSizeClass = HeightSizeClassEnum.EXPANDED
    )
    @Test
    fun resizeWindow_expanded() {
        onDevice().setDisplaySize(
            widthSizeClass = WidthSizeClass.EXPANDED,
            heightSizeClass = HeightSizeClass.EXPANDED
        )
        // Verify visual attributes or state restoration.
    }
}

স্টেট রিস্টোরেশন টেস্টার

StateRestorationTester ক্লাসটি ক্রিয়াকলাপগুলি পুনরায় তৈরি না করে কম্পোজযোগ্য উপাদানগুলির জন্য রাষ্ট্র পুনরুদ্ধার পরীক্ষা করতে ব্যবহৃত হয়। এটি পরীক্ষাগুলিকে দ্রুত এবং আরও নির্ভরযোগ্য করে তোলে, কারণ কার্যকলাপ বিনোদন হল একাধিক সিঙ্ক্রোনাইজেশন প্রক্রিয়া সহ একটি জটিল প্রক্রিয়া:

@Test
fun compactDevice_selectedEmailEmailRetained_afterConfigChange() {
    val stateRestorationTester = StateRestorationTester(composeTestRule)

    // Set content through the StateRestorationTester object.
    stateRestorationTester.setContent {
        MyApp()
    }

    // Simulate a config change.
    stateRestorationTester.emulateSavedInstanceStateRestore()
}

উইন্ডো টেস্টিং লাইব্রেরি

উইন্ডো টেস্টিং লাইব্রেরিতে আপনাকে পরীক্ষা লিখতে সাহায্য করার জন্য ইউটিলিটি রয়েছে যা উইন্ডো পরিচালনার সাথে সম্পর্কিত বৈশিষ্ট্যগুলির উপর নির্ভর করে বা যাচাই করে, যেমন অ্যাক্টিভিটি এমবেডিং বা ভাঁজযোগ্য বৈশিষ্ট্য। আর্টিফ্যাক্টটি গুগলের মাভেন রিপোজিটরির মাধ্যমে পাওয়া যায়।

উদাহরণস্বরূপ, আপনি একটি কাস্টম FoldingFeature তৈরি করতে FoldingFeature() ফাংশন ব্যবহার করতে পারেন, যা আপনি রচনা পূর্বরূপগুলিতে ব্যবহার করতে পারেন। জাভাতে, createFoldingFeature() ফাংশনটি ব্যবহার করুন।

একটি রচনা পূর্বরূপে, আপনি নিম্নলিখিত উপায়ে FoldingFeature প্রয়োগ করতে পারেন:

@Preview(showBackground = true, widthDp = 480, heightDp = 480)
@Composable private fun FoldablePreview() =
    MyApplicationTheme {
        ExampleScreen(
            displayFeatures = listOf(FoldingFeature(Rect(0, 240, 480, 240)))
        )
 }

এছাড়াও, আপনি TestWindowLayoutInfo() ফাংশন ব্যবহার করে UI পরীক্ষায় প্রদর্শন বৈশিষ্ট্যগুলি অনুকরণ করতে পারেন। নিম্নলিখিত উদাহরণটি স্ক্রিনের কেন্দ্রে একটি HALF_OPENED উল্লম্ব কব্জা সহ একটি FoldingFeature অনুকরণ করে, তারপর লেআউটটি প্রত্যাশিত কিনা তা পরীক্ষা করে:

রচনা করা

import androidx.window.layout.FoldingFeature.Orientation.Companion.VERTICAL
import androidx.window.layout.FoldingFeature.State.Companion.HALF_OPENED
import androidx.window.testing.layout.FoldingFeature
import androidx.window.testing.layout.TestWindowLayoutInfo
import androidx.window.testing.layout.WindowLayoutInfoPublisherRule

@RunWith(AndroidJUnit4::class)
class MediaControlsFoldingFeatureTest {

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

    @get:Rule(order=2)
    val windowLayoutInfoPublisherRule = WindowLayoutInfoPublisherRule()

    @Test
    fun foldedWithHinge_foldableUiDisplayed() {
        composeTestRule.setContent {
            MediaPlayerScreen()
        }

        val hinge = FoldingFeature(
            activity = composeTestRule.activity,
            state = HALF_OPENED,
            orientation = VERTICAL,
            size = 2
        )

        val expected = TestWindowLayoutInfo(listOf(hinge))
        windowLayoutInfoPublisherRule.overrideWindowLayoutInfo(expected)

        composeTestRule.waitForIdle()

        // Verify that the folding feature is detected and media controls shown.
        composeTestRule.onNodeWithTag("MEDIA_CONTROLS").assertExists()
    }
}

ভিউ

import androidx.window.layout.FoldingFeature.Orientation
import androidx.window.layout.FoldingFeature.State
import androidx.window.testing.layout.FoldingFeature
import androidx.window.testing.layout.TestWindowLayoutInfo
import androidx.window.testing.layout.WindowLayoutInfoPublisherRule

@RunWith(AndroidJUnit4::class)
class MediaControlsFoldingFeatureTest {

    @get:Rule(order=1)
    val activityRule = ActivityScenarioRule(MediaPlayerActivity::class.java)

    @get:Rule(order=2)
    val windowLayoutInfoPublisherRule = WindowLayoutInfoPublisherRule()

    @Test
    fun foldedWithHinge_foldableUiDisplayed() {
        activityRule.scenario.onActivity { activity ->
            val feature = FoldingFeature(
                activity = activity,
                state = State.HALF_OPENED,
                orientation = Orientation.VERTICAL)
            val expected = TestWindowLayoutInfo(listOf(feature))
            windowLayoutInfoPublisherRule.overrideWindowLayoutInfo(expected)
        }

        // Verify that the folding feature is detected and media controls shown.
        onView(withId(R.id.media_controls)).check(matches(isDisplayed()))
    }
}

আপনি WindowManager প্রকল্পে আরও নমুনা খুঁজে পেতে পারেন।

অতিরিক্ত সম্পদ

ডকুমেন্টেশন

নমুনা

কোডল্যাব