กิจกรรมทำหน้าที่เป็นคอนเทนเนอร์สำหรับการโต้ตอบของผู้ใช้ทุกครั้งภายในแอป ดังนั้นจึงควรทดสอบลักษณะการทำงานของกิจกรรมในแอประหว่างเหตุการณ์ระดับอุปกรณ์ เช่น เหตุการณ์ต่อไปนี้
- แอปอื่น เช่น แอปโทรศัพท์ของอุปกรณ์ ขัดจังหวะกิจกรรมของแอป
- ระบบทำลายและสร้างกิจกรรมของคุณขึ้นมาใหม่
- ผู้ใช้วางกิจกรรมของคุณไว้ในสภาพแวดล้อมการแสดงผลแบบใหม่ เช่น การแสดงภาพซ้อนภาพ (PIP) หรือหลายหน้าต่าง
โดยเฉพาะอย่างยิ่ง คุณควรตรวจสอบว่ากิจกรรมทำงานอย่างถูกต้องเพื่อตอบสนองต่อเหตุการณ์ที่อธิบายไว้ใน วงจรกิจกรรม
คู่มือนี้อธิบายวิธีประเมินความสามารถของแอปในการรักษาความสมบูรณ์ของข้อมูลและประสบการณ์ของผู้ใช้ที่ดีเมื่อกิจกรรมของแอปเปลี่ยนสถานะต่างๆ ในวงจรการทำงาน
การทดสอบกิจกรรมใน Compose
เมื่อทดสอบแอปที่สร้างด้วย Jetpack Compose โดยปกติแล้วคุณจะใช้
createAndroidComposeRule เพื่อเปิดใช้กิจกรรมและโต้ตอบกับคอมโพเนนต์ UI
อย่างไรก็ตาม การทดสอบเหตุการณ์ระดับอุปกรณ์ เช่น การเปลี่ยนแปลงการกำหนดค่า หรือการที่ระบบนำกิจกรรมไปไว้เบื้องหลังหรือทำลายกิจกรรมนั้น คุณจะต้องจัดการวงจรการทำงานของกิจกรรมโดยตรง ซึ่งทำได้โดยใช้
เฟรมเวิร์ก ActivityScenario ที่อยู่เบื้องหลัง
กฎการทดสอบ Compose จะรวมและจัดการสถานการณ์นี้ให้คุณโดยอัตโนมัติ ตลอดทั้งคู่มือนี้ คุณจะเห็นรูปแบบต่อไปนี้ที่ใช้เพื่อเชื่อมช่องว่างระหว่างการทดสอบ UI ที่ทันสมัยกับการจัดการวงจรการทำงานมาตรฐาน
@get:Rule
val composeTestRule = createAndroidComposeRule<MyActivity>()
@Test fun testEvent() {
val scenario = composeTestRule.activityRule.scenario
// ...
}
ควบคุมสถานะของกิจกรรม
ลักษณะสำคัญอย่างหนึ่งของการทดสอบกิจกรรมของแอปคือการกำหนดสถานะของกิจกรรมในแอป หากต้องการกำหนดส่วน "given" ของการทดสอบ ให้ใช้
อินสแตนซ์ของ ActivityScenario ซึ่งเป็นส่วนหนึ่งของ ไลบรารี
AndroidX Test การใช้คลาสนี้จะช่วยให้คุณกำหนดสถานะของกิจกรรมเพื่อจำลองเหตุการณ์ระดับอุปกรณ์ได้
ActivityScenario เป็น API ข้ามแพลตฟอร์มที่คุณใช้ได้ทั้งในการทดสอบหน่วยภายในเครื่องและการทดสอบการผสานรวมในอุปกรณ์ ActivityScenario มีความปลอดภัยของเธรดในอุปกรณ์จริงหรืออุปกรณ์เสมือนจริง โดยจะซิงค์เหตุการณ์ระหว่างเธรดการวัดประสิทธิภาพของการทดสอบกับเธรดที่เรียกใช้กิจกรรมภายใต้การทดสอบ
API นี้เหมาะอย่างยิ่งสำหรับการประเมินลักษณะการทำงานของกิจกรรมภายใต้การทดสอบเมื่อกิจกรรมถูกทำลายหรือสร้างขึ้น ส่วนนี้จะแสดงกรณีการใช้งานที่พบบ่อยที่สุดที่เกี่ยวข้องกับ API นี้
สร้างกิจกรรม
หากต้องการสร้างกิจกรรมภายใต้การทดสอบ ให้เพิ่มโค้ดที่แสดงในข้อมูลโค้ดต่อไปนี้
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEvent() {
launchActivity<MyActivity>().use {
}
}
}
หลังจากสร้างกิจกรรมแล้ว ActivityScenario จะเปลี่ยนกิจกรรมไปเป็นสถานะ RESUMED สถานะนี้บ่งบอกว่ากิจกรรมกำลังทำงานและผู้ใช้มองเห็นได้ ในสถานะนี้ คุณสามารถโต้ตอบกับคอมโพสได้ของกิจกรรมโดยใช้ Compose Testing API
Google ขอแนะนำให้คุณเรียกใช้ close ในกิจกรรมเมื่อการทดสอบเสร็จสมบูรณ์
ซึ่งจะล้างทรัพยากรที่เชื่อมโยงและปรับปรุงความเสถียรของการทดสอบ ActivityScenario ใช้ Closeable ดังนั้นคุณจึงใช้ส่วนขยาย use เพื่อให้กิจกรรมปิดโดยอัตโนมัติได้
หรือคุณจะใช้ createAndroidComposeRule เพื่อเปิดใช้กิจกรรมโดยอัตโนมัติ
ก่อนการทดสอบแต่ละครั้ง จัดการการล้างข้อมูล และให้สิทธิ์เข้าถึง
ทั้งเมธอดการทดสอบ UI ของ Compose และ ActivityScenario ที่อยู่เบื้องหลัง ตัวอย่างต่อไปนี้แสดงวิธีสร้างกฎและรับอินสแตนซ์ของสถานการณ์จากกฎ
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@get:Rule
val composeTestRule = createAndroidComposeRule<MyActivity>()
@Test fun testEvent() {
val scenario = composeTestRule.activityRule.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 การใช้ createAndroidComposeRule จะช่วยให้คุณทริกเกอร์การดำเนินการ UI ที่ทำให้กิจกรรมเสร็จสมบูรณ์ได้อย่างง่ายดาย ดังที่แสดงในข้อมูลโค้ดต่อไปนี้
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@get:Rule
val composeTestRule = createAndroidComposeRule<MyActivity>()
@Test fun testResult() {
composeTestRule.onNodeWithTag("finish_button").performClick()
val scenario = composeTestRule.activityRule.scenario
val resultCode = scenario.result.resultCode
val resultData = scenario.result.resultData
}
}
ทริกเกอร์การดำเนินการในกิจกรรม
เมธอดทั้งหมดภายใน ActivityScenario เป็นการเรียกที่บล็อก ดังนั้น API จึงกำหนดให้คุณเรียกใช้เมธอดเหล่านี้ในเธรดการวัดคุม
หากต้องการทริกเกอร์การดำเนินการในกิจกรรมภายใต้การทดสอบ ให้ใช้ Compose Testing API เพื่อโต้ตอบกับคอมโพสได้
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@get:Rule
val composeTestRule = createAndroidComposeRule<MyActivity>()
@Test fun testEvent() {
composeTestRule.onNodeWithText("Refresh").performClick()
}
}
อย่างไรก็ตาม หากคุณต้องการเรียกใช้เมธอดในกิจกรรมเอง คุณสามารถทำได้อย่างปลอดภัยโดยใช้ onActivity
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEvent() {
launchActivity<MyActivity>().use { scenario ->
scenario.onActivity { activity ->
activity.handleSwipeToRefresh()
}
}
}
}
แหล่งข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับการทดสอบได้จากแหล่งข้อมูลเพิ่มเติมต่อไปนี้