หน้านี้สรุปหลักการสำคัญของการทดสอบแอป Android ซึ่งรวมถึงแนวทางปฏิบัติแนะนำหลักและประโยชน์ของแนวทางดังกล่าว
สิทธิประโยชน์ของการทดสอบ
การทดสอบเป็นส่วนสำคัญของกระบวนการพัฒนาแอป การทดสอบแอปอย่างสม่ำเสมอช่วยยืนยันความถูกต้อง ลักษณะการทำงาน และความสามารถในการใช้งานของแอปก่อนที่จะเผยแพร่ต่อสาธารณะได้
คุณสามารถทดสอบแอปด้วยตนเองโดยการใช้งานแอป คุณอาจใช้อุปกรณ์และโปรแกรมจำลองอุปกรณ์ที่แตกต่างกัน เปลี่ยนภาษาของระบบ และพยายามสร้างข้อผิดพลาดของผู้ใช้ทุกข้อผิดพลาดหรือใช้งานทุกขั้นตอนของผู้ใช้
อย่างไรก็ตาม การทดสอบด้วยตนเองปรับขนาดได้ไม่ดี และอาจมองข้ามการถดถอยในลักษณะการทำงานของแอปได้ง่าย การทดสอบอัตโนมัติเกี่ยวข้องกับการใช้เครื่องมือที่ทำการทดสอบให้คุณ ซึ่งเร็วกว่า ทำซ้ำได้มากกว่า และโดยทั่วไปจะให้ความคิดเห็นที่นำไปใช้ได้จริงมากขึ้นเกี่ยวกับแอปของคุณในระยะแรกๆ ของกระบวนการพัฒนา
ประเภทของการทดสอบใน Android
แอปพลิเคชันบนอุปกรณ์เคลื่อนที่มีความซับซ้อนและต้องทำงานได้ดีในสภาพแวดล้อมที่หลากหลาย จึงมีการทดสอบหลายประเภท
เรื่อง
ตัวอย่างเช่น การทดสอบมีหลายประเภทขึ้นอยู่กับ เรื่อง ดังนี้
- การทดสอบฟังก์ชันการทำงาน: แอปของฉันทำงานตามที่ควรจะเป็นหรือไม่
- การทดสอบประสิทธิภาพ: แอปทำงานได้อย่างรวดเร็วและมีประสิทธิภาพหรือไม่
- การทดสอบการช่วยเหลือพิเศษ: แอปทำงานได้ดีกับบริการการช่วยเหลือพิเศษหรือไม่
- การทดสอบความเข้ากันได้: แอปทำงานได้ดีในอุปกรณ์ทุกเครื่องและระดับ API ทุกระดับหรือไม่
ขอบเขต
การทดสอบยังแตกต่างกันไปตาม ขนาด หรือ ระดับการแยก ดังนี้
- การทดสอบหน่วย หรือการทดสอบขนาดเล็ก จะตรวจสอบเฉพาะส่วนเล็กๆ ของแอป เช่น เมธอดหรือคลาส
- การทดสอบแบบครบวงจร หรือการทดสอบขนาดใหญ่ จะตรวจสอบแอปส่วนใหญ่พร้อมกัน เช่น ทั้งหน้าจอหรือขั้นตอนของผู้ใช้
- การทดสอบขนาดกลาง จะอยู่ระหว่างการทดสอบขนาดเล็กและการทดสอบขนาดใหญ่ และจะตรวจสอบการผสานรวม ระหว่างหน่วย 2 หน่วยขึ้นไป
การทดสอบสามารถจำแนกได้หลายวิธี อย่างไรก็ตาม สิ่งที่สำคัญที่สุดสำหรับนักพัฒนาแอปคือตำแหน่งที่การทดสอบทำงาน
การทดสอบแบบมีเครื่องมือเทียบกับการทดสอบในเครื่อง
คุณสามารถทำการทดสอบในอุปกรณ์ Android หรือในคอมพิวเตอร์เครื่องอื่นได้
- การทดสอบแบบมีเครื่องมือ จะทำงานในอุปกรณ์ Android ไม่ว่าจะเป็นอุปกรณ์จริงหรืออุปกรณ์จำลอง ระบบจะสร้างและติดตั้งแอปควบคู่ไปกับ แอปทดสอบ ที่แทรกคำสั่งและอ่านสถานะ การทดสอบแบบมีเครื่องมือมักเป็นการทดสอบ UI ซึ่งจะเปิดแอปแล้วโต้ตอบกับแอป
- การทดสอบในเครื่อง จะทำงานในเครื่องพัฒนาซอฟต์แวร์หรือเซิร์ฟเวอร์ จึงเรียกอีกอย่างว่า การทดสอบฝั่งโฮสต์ โดยปกติแล้วการทดสอบเหล่านี้จะมีขนาดเล็กและรวดเร็ว ซึ่งจะแยกหัวข้อที่ทดสอบออกจากส่วนอื่นๆ ของแอป
การทดสอบหน่วยบางรายการไม่ได้เป็นการทดสอบในเครื่อง และการทดสอบแบบครบวงจรบางรายการไม่ได้ทำงานในอุปกรณ์ ตัวอย่างเช่น
- การทดสอบในเครื่องขนาดใหญ่: คุณสามารถใช้โปรแกรมจำลอง Android ที่ทำงานในเครื่อง เช่น Robolectric
- การทดสอบแบบมีเครื่องมือขนาดเล็ก: คุณสามารถยืนยันว่าโค้ดทำงานได้ดีกับ ฟีเจอร์ของเฟรมเวิร์ก เช่น ฐานข้อมูล SQLite คุณอาจทำการทดสอบนี้ในอุปกรณ์หลายเครื่องเพื่อตรวจสอบการผสานรวมกับ SQLite หลายเวอร์ชัน
ตัวอย่าง
ข้อมูลโค้ดต่อไปนี้แสดงวิธีโต้ตอบกับ UI ใน การทดสอบ UI แบบมีเครื่องมือ ซึ่งจะคลิกองค์ประกอบหนึ่งและยืนยันว่ามีการแสดงองค์ประกอบอื่น
Espresso
// When the Continue button is clicked
onView(withText("Continue"))
.perform(click())
// Then the Welcome screen is displayed
onView(withText("Welcome"))
.check(matches(isDisplayed()))
Compose UI
// 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 ที่ใหญ่ขึ้น
- โอกาสในการทดสอบสถานการณ์ต่างๆ น้อยลง การทดสอบที่ใหญ่ขึ้นจะช้าลง ดังนั้นการทดสอบสถานะที่เป็นไปได้ทั้งหมดของแอปจึงอาจเป็นไปได้ยาก
ดูข้อมูลเพิ่มเติมเกี่ยวกับหลักเกณฑ์ด้านสถาปัตยกรรมได้ที่คู่มือเกี่ยวกับสถาปัตยกรรมของแอป
แนวทางในการแยกส่วนประกอบ
หากแยกส่วนหนึ่งของฟังก์ชัน คลาส หรือโมดูลออกจากส่วนอื่นๆ ได้ การทดสอบส่วนนั้นจะง่ายขึ้นและมีประสิทธิภาพมากขึ้น แนวทางปฏิบัตินี้เรียกว่าการแยกส่วนประกอบ และเป็นแนวคิดที่สำคัญที่สุดสำหรับสถาปัตยกรรมที่ทดสอบได้
เทคนิคการแยกส่วนประกอบที่ใช้กันโดยทั่วไปมีดังนี้
- แบ่งแอปออกเป็น เลเยอร์ เช่น การนำเสนอ โดเมน และข้อมูล นอกจากนี้ คุณยังแบ่งแอปออกเป็น โมดูล ได้ด้วย โดยโมดูลหนึ่งโมดูลต่อฟีเจอร์
- หลีกเลี่ยงการเพิ่มตรรกะลงในเอนทิตีที่มีการพึ่งพาจำนวนมาก เช่น กิจกรรมและ Fragment ใช้คลาสเหล่านี้เป็นจุดเริ่มต้นของเฟรมเวิร์ก และย้าย UI และตรรกะทางธุรกิจ ไปยังที่อื่น เช่น ไปยัง Composable, ViewModel หรือเลเยอร์โดเมน
- หลีกเลี่ยง การพึ่งพาเฟรมเวิร์ก โดยตรงในคลาสที่มีตรรกะทางธุรกิจ เช่น อย่าใช้บริบท Android ใน ViewModel
- ทำให้ การแทนที่ การพึ่งพาง่ายขึ้น เช่น ใช้ อินเทอร์เฟซแทนการติดตั้งใช้งานที่เฉพาะเจาะจง ใช้ การแทรกทรัพยากร Dependencyแม้ว่าคุณจะไม่ได้ใช้เฟรมเวิร์ก DI ก็ตาม
ขั้นตอนถัดไป
ตอนนี้คุณทราบแล้วว่าทำไมจึงควรทดสอบและทราบประเภทการทดสอบหลัก 2 ประเภทแล้ว คุณสามารถอ่านสิ่งที่จะทดสอบหรือดูข้อมูลเกี่ยวกับกลยุทธ์การทดสอบได้
หรือหากต้องการสร้างการทดสอบแรกและเรียนรู้จากการลงมือทำ โปรดดู Codelab การทดสอบ