รูปแบบทั่วไป

คุณสามารถทดสอบแอป Compose ด้วยแนวทางและรูปแบบที่ได้รับการยอมรับอย่างกว้างขวาง

ทดสอบแบบแยก

ComposeTestRule ช่วยให้คุณเริ่มกิจกรรมที่แสดงคอมโพสได้ทุกประเภท ไม่ว่าจะเป็นแอปพลิเคชันทั้งหมด หน้าจอเดียว หรือองค์ประกอบขนาดเล็ก นอกจากนี้ การตรวจสอบว่าคอมโพสของคุณได้รับการห่อหุ้มอย่างถูกต้องและทำงานได้อย่างอิสระยังเป็นแนวทางปฏิบัติที่ดี ซึ่งจะช่วยให้การทดสอบ UI ง่ายขึ้นและตรงจุดมากขึ้น

ทั้งนี้ไม่ได้หมายความว่าคุณควรสร้างการทดสอบ UI ระดับหน่วย เท่านั้น การทดสอบ UI ที่ครอบคลุม UI ส่วนใหญ่ก็มีความสำคัญเช่นกัน

เข้าถึงกิจกรรมและทรัพยากรหลังจากตั้งค่าเนื้อหาของคุณเอง

ในหลายๆ ครั้ง คุณต้องตั้งค่าเนื้อหาที่อยู่ระหว่างการทดสอบโดยใช้ composeTestRule.setContent และยังต้องเข้าถึงทรัพยากรของกิจกรรมด้วย เช่น เพื่อยืนยันว่าข้อความที่แสดงตรงกับทรัพยากรสตริง อย่างไรก็ตาม คุณไม่สามารถเรียก setContent ในกฎที่สร้างด้วย createAndroidComposeRule() ได้หากกิจกรรมเรียกกฎดังกล่าวอยู่แล้ว

รูปแบบทั่วไปในการดำเนินการนี้คือการสร้าง AndroidComposeTestRule โดยใช้ กิจกรรมที่ว่างเปล่า เช่น ComponentActivity

class MyComposeTest {

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

    @Test
    fun myTest() {
        // Start the app
        composeTestRule.setContent {
            MyAppTheme {
                MainScreen(uiState = exampleUiState, /*...*/)
            }
        }
        val continueLabel = composeTestRule.activity.getString(R.string.next)
        composeTestRule.onNodeWithText(continueLabel).performClick()
    }
}

โปรดทราบว่าคุณต้องเพิ่ม ComponentActivity ลงในไฟล์ AndroidManifest.xml ของแอป โดยเปิดใช้ด้วยการเพิ่มทรัพยากร Dependency นี้ลงในโมดูล

debugImplementation("androidx.compose.ui:ui-test-manifest:$compose_version")

พร็อพเพอร์ตี้ความหมายที่กำหนดเอง

คุณสามารถสร้างพร็อพเพอร์ตี้ความหมายที่กำหนดเองเพื่อเปิดเผยข้อมูลสำหรับการทดสอบ โดยกำหนด SemanticsPropertyKey ใหม่และทำให้พร้อมใช้งานโดยใช้ SemanticsPropertyReceiver

// Creates a semantics property of type Long.
val PickedDateKey = SemanticsPropertyKey<Long>("PickedDate")
var SemanticsPropertyReceiver.pickedDate by PickedDateKey

จากนั้นใช้พร็อพเพอร์ตี้นั้นในตัวปรับแต่ง semantics

val datePickerValue by remember { mutableStateOf(0L) }
MyCustomDatePicker(
    modifier = Modifier.semantics { pickedDate = datePickerValue }
)

จากการทดสอบ ให้ใช้ SemanticsMatcher.expectValue เพื่อยืนยันค่าของพร็อพเพอร์ตี้

composeTestRule
    .onNode(SemanticsMatcher.expectValue(PickedDateKey, 1445378400)) // 2015-10-21
    .assertExists()

ยืนยันการกู้คืนสถานะ

ยืนยันว่าสถานะขององค์ประกอบ Compose ได้รับการกู้คืนอย่างถูกต้องเมื่อมีการสร้างกิจกรรมหรือกระบวนการขึ้นใหม่ ทำการตรวจสอบดังกล่าวโดยไม่จำเป็นต้องสร้างกิจกรรมขึ้นใหม่ด้วย คลาส StateRestorationTester

คลาสนี้ช่วยให้คุณจำลองการสร้างคอมโพสขึ้นใหม่ได้ ซึ่งมีประโยชน์อย่างยิ่งในการยืนยันการติดตั้งใช้งาน rememberSaveable


class MyStateRestorationTests {

    @get:Rule
    val composeTestRule = createComposeRule()

    @Test
    fun onRecreation_stateIsRestored() {
        val restorationTester = StateRestorationTester(composeTestRule)

        restorationTester.setContent { MainScreen() }

        // TODO: Run actions that modify the state

        // Trigger a recreation
        restorationTester.emulateSavedInstanceStateRestore()

        // TODO: Verify that state has been correctly restored.
    }
}

ทดสอบการกำหนดค่าอุปกรณ์ต่างๆ

แอป Android ต้องปรับให้เข้ากับเงื่อนไขที่เปลี่ยนแปลงไปมากมาย ไม่ว่าจะเป็นขนาดหน้าต่าง ภาษา ขนาดตัวอักษร ธีมมืดและธีมสว่าง และอื่นๆ เงื่อนไขส่วนใหญ่ได้มาจากค่าระดับอุปกรณ์ที่ผู้ใช้ควบคุมและเปิดเผยด้วยอินสแตนซ์ปัจจุบันConfiguration การทดสอบการกำหนดค่าต่างๆ โดยตรงในการทดสอบเป็นเรื่องยากเนื่องจากการทดสอบต้องกำหนดค่าพร็อพเพอร์ตี้ระดับอุปกรณ์

DeviceConfigurationOverride เป็น API ที่ใช้สำหรับการทดสอบเท่านั้น ซึ่งช่วยให้คุณจำลองการกำหนดค่าอุปกรณ์ต่างๆ ในลักษณะที่แปลเป็นภาษาท้องถิ่นสำหรับเนื้อหา @Composable ที่อยู่ระหว่างการทดสอบ

ออบเจ็กต์คู่ของ DeviceConfigurationOverride มีฟังก์ชันส่วนขยายต่อไปนี้ ซึ่งจะลบล้างพร็อพเพอร์ตี้การกำหนดค่าระดับอุปกรณ์

หากต้องการใช้การลบล้างที่เฉพาะเจาะจง ให้ใส่เนื้อหาที่อยู่ระหว่างการทดสอบไว้ในการเรียกใช้ฟังก์ชันระดับบนสุด DeviceConfigurationOverride() โดยส่งการลบล้าง ที่จะใช้เป็นพารามิเตอร์

ตัวอย่างเช่น โค้ดต่อไปนี้ใช้การลบล้าง DeviceConfigurationOverride.ForcedSize() เพื่อเปลี่ยนความหนาแน่นในเครื่อง ซึ่งบังคับให้คอมโพส MyScreen แสดงผลในหน้าต่างแนวนอนขนาดใหญ่ แม้ว่าอุปกรณ์ที่ใช้ทดสอบจะไม่รองรับขนาดหน้าต่างนั้นโดยตรงก็ตาม

composeTestRule.setContent {
    DeviceConfigurationOverride(
        DeviceConfigurationOverride.ForcedSize(DpSize(1280.dp, 800.dp))
    ) {
        MyScreen() // Will be rendered in the space for 1280dp by 800dp without clipping.
    }
}

หากต้องการใช้การลบล้างหลายรายการพร้อมกัน ให้ใช้ DeviceConfigurationOverride.then()

composeTestRule.setContent {
    DeviceConfigurationOverride(
        DeviceConfigurationOverride.FontScale(1.5f) then
            DeviceConfigurationOverride.FontWeightAdjustment(200)
    ) {
        Text(text = "text with increased scale and weight")
    }
}

แหล่งข้อมูลเพิ่มเติม