หน้านี้จะกล่าวถึงหลักการหลักๆ ของการทดสอบแอป Android รวมถึงแนวทางปฏิบัติแนะนำหลักและประโยชน์ของแนวทางปฏิบัติเหล่านั้น
ประโยชน์ของการทดสอบ
การทดสอบเป็นส่วนสำคัญของกระบวนการพัฒนาแอป การทดสอบแอปอย่างสม่ำเสมอช่วยยืนยันความถูกต้อง ลักษณะการทำงาน และความสามารถในการใช้งานของแอปก่อนที่จะเผยแพร่ต่อสาธารณะได้
คุณทดสอบแอปด้วยตนเองได้โดยการไปยังส่วนต่างๆ คุณอาจใช้อุปกรณ์และโปรแกรมจำลองที่แตกต่างกัน เปลี่ยนภาษาของระบบ และพยายามสร้างข้อผิดพลาดของผู้ใช้ทุกข้อหรือไปยังทุกขั้นตอนของผู้ใช้
อย่างไรก็ตาม การทดสอบด้วยตนเองปรับค่าได้ไม่ดีและคุณอาจมองข้ามความถดถอยในลักษณะการทำงานของแอปไปได้ง่ายๆ การทดสอบอัตโนมัติเกี่ยวข้องกับการใช้เครื่องมือที่ทำการทดสอบให้คุณ ซึ่งจะเร็วกว่า ทำซ้ำได้มากขึ้น และโดยทั่วไปจะให้ความคิดเห็นที่นำไปใช้ได้จริงเกี่ยวกับแอปของคุณได้เร็วขึ้นในกระบวนการพัฒนา
ประเภทการทดสอบใน Android
แอปพลิเคชันบนอุปกรณ์เคลื่อนที่มีความซับซ้อนและต้องทำงานได้ดีในหลายสภาพแวดล้อม ด้วยเหตุนี้ การทดสอบจึงมีหลายประเภท
เรื่อง
ตัวอย่างเช่น การทดสอบมีด้วยกันหลายประเภท โดยขึ้นอยู่กับเรื่อง
- การทดสอบฟังก์ชันการทำงาน: แอปทํางานตามที่ควรจะเป็นไหม
- การทดสอบประสิทธิภาพ: ทำงานได้อย่างรวดเร็วและมีประสิทธิภาพหรือไม่
- การทดสอบการช่วยเหลือพิเศษ: เนื้อหาทำงานร่วมกับบริการการช่วยเหลือพิเศษได้ดีไหม
- การทดสอบความเข้ากันได้: แอปทำงานได้ดีในอุปกรณ์และ API ทุกระดับหรือไม่
ขอบเขต
การทดสอบยังแตกต่างกันไปตามขนาดหรือระดับการแยกส่วนดังนี้
- การทดสอบหน่วยหรือการทดสอบเล็กๆ จะยืนยันของแอปเพียงส่วนน้อยมาก เช่น เมธอดหรือชั้นเรียน
- การทดสอบจากต้นทางถึงปลายทางหรือการทดสอบแบบรวมจะยืนยันส่วนต่างๆ ของแอปในคราวเดียวกัน เช่น หน้าจอทั้งหน้าจอหรือขั้นตอนของผู้ใช้
- การทดสอบระดับกลางจะอยู่ตรงกลางและตรวจสอบการผสานรวมระหว่างหน่วย 2 หน่วยขึ้นไป
การแยกประเภทการทดสอบทำได้หลายวิธี อย่างไรก็ตาม สิ่งที่แตกต่างที่สำคัญที่สุดสำหรับนักพัฒนาแอปคือการทดสอบที่ดำเนินการ
การทดสอบที่มีเครื่องควบคุมกับการทดสอบในเครื่อง
คุณทำการทดสอบในอุปกรณ์ Android หรือในคอมพิวเตอร์เครื่องอื่นได้ โดยทำดังนี้
- การทดสอบที่มีเครื่องมือวัดจะทำงานบนอุปกรณ์ Android ไม่ว่าจะเป็นอุปกรณ์จริงหรืออุปกรณ์จำลอง ระบบจะสร้างและติดตั้งแอปควบคู่ไปกับแอปทดสอบที่แทรกคําสั่งและอ่านสถานะ การทดสอบที่มีเครื่องมือวัดมักจะเป็นการทดสอบ UI ซึ่งจะเปิดแอปแล้วโต้ตอบกับแอป
- การทดสอบในเครื่องจะดำเนินการในเครื่องสำหรับพัฒนาซอฟต์แวร์หรือเซิร์ฟเวอร์ จึงเรียกอีกอย่างว่าการทดสอบฝั่งโฮสต์ มักจะมีขนาดเล็กและรวดเร็ว โดยแยกหัวข้อที่อยู่ระหว่างการทดสอบออกจากส่วนอื่นๆ ของแอป
การทดสอบ 1 หน่วยบางรายการไม่ได้ทำในเครื่อง และการทดสอบจากต้นทางถึงปลายทางบางรายการไม่ได้ทําในอุปกรณ์ เช่น
- การทดสอบในเครื่องแบบเป็นกลุ่ม: คุณสามารถใช้โปรแกรมจำลอง Android ที่ทำงานในเครื่อง เช่น Robolectric
- การทดสอบการวัดคุมขนาดเล็ก: คุณยืนยันได้ว่าโค้ดทำงานได้ดีกับฟีเจอร์เฟรมเวิร์ก เช่น ฐานข้อมูล SQLite คุณอาจทำการทดสอบนี้ในอุปกรณ์หลายเครื่องเพื่อตรวจสอบการผสานรวมกับ SQLite หลายเวอร์ชัน
ตัวอย่าง
ข้อมูลโค้ดต่อไปนี้แสดงวิธีโต้ตอบกับ UI ในการทดสอบ UI ที่มีเครื่องมือวัดซึ่งคลิกองค์ประกอบและยืนยันว่าองค์ประกอบอื่นแสดงขึ้น
เอสเพรสโซ
// When the Continue button is clicked
onView(withText("Continue"))
.perform(click())
// Then the Welcome screen is displayed
onView(withText("Welcome"))
.check(matches(isDisplayed()))
UI ของ Compose
// When the Continue button is clicked
composeTestRule.onNodeWithText("Continue").performClick()
// Then the Welcome screen is displayed
composeTestRule.onNodeWithText("Welcome").assertIsDisplayed()
ข้อมูลโค้ดนี้แสดงส่วนหนึ่งของการทดสอบหน่วยสำหรับ ViewModel (การทดสอบฝั่งโฮสต์) ดังนี้
// Given an instance of MyViewModel
val viewModel = MyViewModel(myFakeDataRepository)
// When data is loaded
viewModel.loadData()
// Then it should be exposing data
assertTrue(viewModel.data != null)
สถาปัตยกรรมที่ทดสอบได้
เมื่อใช้สถาปัตยกรรมแอปที่ทดสอบได้ โค้ดจะเป็นไปตามโครงสร้างที่ช่วยให้คุณทดสอบส่วนต่างๆ แยกกันได้ง่ายๆ สถาปัตยกรรมที่ทดสอบได้มีข้อดีอื่นๆ เช่น ความสามารถในการอ่าน ความสามารถในการบำรุงรักษา ความสามารถในการปรับขนาด และความสามารถในการนํากลับมาใช้ใหม่ได้ดีขึ้น
สถาปัตยกรรมที่ทดสอบไม่ได้จะทำให้เกิดผลลัพธ์ต่อไปนี้
- การทดสอบที่ใหญ่ขึ้น ช้าลง และไม่น่าเชื่อถือมากขึ้น ชั้นเรียนที่ทำการทดสอบหน่วยไม่ได้อาจต้องอยู่ภายใต้การทดสอบการผสานรวมหรือการทดสอบ UI ที่ใหญ่ขึ้น
- มีโอกาสน้อยลงในการทดสอบสถานการณ์ต่างๆ การทดสอบขนาดใหญ่จะช้ากว่า การทดสอบสถานะทั้งหมดที่เป็นไปได้ของแอปจึงอาจไม่สมจริง
ดูข้อมูลเพิ่มเติมเกี่ยวกับหลักเกณฑ์ด้านสถาปัตยกรรมได้ในคู่มือเกี่ยวกับสถาปัตยกรรมของแอป
แนวทางการแยก
หากดึงข้อมูลฟังก์ชัน คลาส หรือโมดูลบางส่วนออกจากส่วนที่เหลือได้ การทดสอบจะง่ายและมีประสิทธิภาพมากขึ้น แนวทางนี้เรียกว่าการแยกส่วน และเป็นแนวคิดที่สำคัญที่สุดสำหรับสถาปัตยกรรมที่ทดสอบได้
เทคนิคการแยกที่พบบ่อยมีดังนี้
- แบ่งแอปออกเป็นเลเยอร์ เช่น การแสดงผล โดเมน และข้อมูล นอกจากนี้ คุณยังแบ่งแอปออกเป็นโมดูลได้ โดยแบ่ง 1 โมดูลต่อฟีเจอร์
- หลีกเลี่ยงการเพิ่มตรรกะในเอนทิตีที่มีทรัพยากร Dependency ขนาดใหญ่ เช่น กิจกรรมและส่วนย่อย ใช้คลาสเหล่านี้เป็นจุดแรกเข้าของเฟรมเวิร์กและย้ายตรรกะ UI และธุรกิจไปที่อื่น เช่น ไปยังเลเยอร์ Composable, ViewModel หรือโดเมน
- หลีกเลี่ยงการพึ่งพาเฟรมเวิร์กโดยตรงในชั้นเรียนที่มีตรรกะทางธุรกิจ เช่น อย่าใช้บริบท Android ใน ViewModel
- ทำให้แทนที่ทรัพยากร Dependency ได้ง่าย เช่น ใช้อินเทอร์เฟซแทนการใช้งานที่เจาะจง ใช้การฉีดข้อมูล Dependency แม้ว่าคุณจะไม่ได้ใช้เฟรมเวิร์ก DI ก็ตาม
ขั้นตอนถัดไป
ตอนนี้คุณก็รู้เหตุผลที่ควรทดสอบและการทดสอบ 2 ประเภทหลักๆ แล้ว คุณอ่านสิ่งที่ต้องทดสอบหรือเรียนรู้เกี่ยวกับกลยุทธ์การทดสอบได้
หรือหากต้องการสร้างการทดสอบแรกและเรียนรู้จากการทําจริง ให้ไปที่Codelab การทดสอบ