หน้านี้จะอธิบายหลักการสำคัญของการทดสอบแอป Android รวมถึง แนวทางปฏิบัติแนะนำหลักและประโยชน์ของแนวทางดังกล่าว
ประโยชน์ของการทดสอบ
การทดสอบเป็นส่วนสำคัญของกระบวนการพัฒนาแอป การทดสอบแอปอย่างสม่ำเสมอช่วยยืนยันความถูกต้อง ลักษณะการทำงาน และความสามารถในการใช้งานของแอปก่อนที่จะเผยแพร่ต่อสาธารณะได้
คุณสามารถทดสอบแอปด้วยตนเองโดยการไปยังส่วนต่างๆ ของแอป คุณอาจใช้อุปกรณ์และโปรแกรมจำลองที่แตกต่างกัน เปลี่ยนภาษาของระบบ และพยายามสร้างข้อผิดพลาดของผู้ใช้ทุกอย่างหรือสำรวจโฟลว์ของผู้ใช้ทุกโฟลว์
อย่างไรก็ตาม การทดสอบด้วยตนเองปรับขนาดได้ไม่ดี และอาจมองข้าม การถดถอยในลักษณะการทำงานของแอปได้ง่าย การทดสอบอัตโนมัติเกี่ยวข้องกับการใช้เครื่องมือ ที่ทำการทดสอบให้คุณ ซึ่งเร็วกว่า ทำซ้ำได้มากกว่า และโดยทั่วไป จะให้ความคิดเห็นที่นำไปใช้ได้จริงเกี่ยวกับแอปของคุณมากขึ้นในช่วงต้นๆ ของกระบวนการพัฒนา
ประเภทการทดสอบใน Android
แอปพลิเคชันบนอุปกรณ์เคลื่อนที่มีความซับซ้อนและต้องทำงานได้ดีในหลายสภาพแวดล้อม ดังนั้น การทดสอบจึงมีหลายประเภท
เรื่อง
เช่น มีการทดสอบหลายประเภทขึ้นอยู่กับวิชา
- การทดสอบฟังก์ชันการทำงาน: แอปของฉันทํางานตามที่ควรจะเป็นหรือไม่
- การทดสอบประสิทธิภาพ: ดำเนินการได้อย่างรวดเร็วและมีประสิทธิภาพหรือไม่
- การทดสอบการช่วยเหลือพิเศษ: ทำงานร่วมกับบริการช่วยเหลือพิเศษได้ดีหรือไม่
- การทดสอบความเข้ากันได้: แอปทำงานได้ดีในอุปกรณ์และ API ทุกระดับไหม
ขอบเขต
การทดสอบยังแตกต่างกันไปตามขนาดหรือระดับการแยกด้วย
- การทดสอบหน่วยหรือการทดสอบขนาดเล็กจะยืนยันเฉพาะส่วนเล็กๆ ของแอปเท่านั้น เช่น เมธอดหรือคลาส
- การทดสอบตั้งแต่ต้นจนจบหรือการทดสอบขนาดใหญ่จะยืนยันส่วนที่ใหญ่ขึ้นของแอปพร้อมกัน เช่น ทั้งหน้าจอหรือโฟลว์ของผู้ใช้
- การทดสอบระดับกลางอยู่ระหว่างการทดสอบหน่วยและการทดสอบการผสานรวม และจะตรวจสอบการผสานรวมระหว่างหน่วย 2 หน่วยขึ้นไป

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

การทดสอบหน่วยบางรายการไม่ได้อยู่ในเครื่อง และการทดสอบแบบครบวงจรบางรายการไม่ได้ทำงานบนอุปกรณ์ เช่น
- การทดสอบในเครื่องขนาดใหญ่: คุณสามารถใช้โปรแกรมจำลอง 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 โมดูลต่อ 1 ฟีเจอร์
- หลีกเลี่ยงการเพิ่มตรรกะไปยังเอนทิตีที่มีการอ้างอิงจำนวนมาก เช่น กิจกรรมและ Fragment ใช้คลาสเหล่านี้เป็นจุดแรกเข้าของเฟรมเวิร์กและย้ายตรรกะ UI และธุรกิจไปยังที่อื่น เช่น ไปยัง Composable, ViewModel หรือเลเยอร์โดเมน
- หลีกเลี่ยงการอ้างอิงเฟรมเวิร์กโดยตรงในคลาสที่มีตรรกะทางธุรกิจ เช่น อย่าใช้บริบทของ Android ใน ViewModel
- ทำให้การแทนที่การอ้างอิงเป็นเรื่องง่าย เช่น ใช้ อินเทอร์เฟซแทนการใช้งานจริง ใช้การแทรกการอ้างอิงแม้ว่าจะไม่ได้ใช้เฟรมเวิร์ก DI ก็ตาม
ขั้นตอนถัดไป
ตอนนี้คุณทราบแล้วว่าเหตุใดจึงควรทดสอบและประเภทการทดสอบหลัก 2 ประเภท คุณสามารถอ่านสิ่งที่จะทดสอบหรือดูข้อมูลเกี่ยวกับกลยุทธ์การทดสอบได้
หรือหากต้องการสร้างการทดสอบแรกและเรียนรู้จากการลงมือทำ โปรดดูCodelab การทดสอบ