หน้านี้สรุปหลักการสำคัญของการทดสอบแอป Android ซึ่งรวมถึงแนวทางปฏิบัติแนะนำหลักและประโยชน์ของแนวทางดังกล่าว
ทักษะ Android
ดูใน GitHubสร้างกลยุทธ์การทดสอบ
android skills add testing-setupสิทธิประโยชน์ของการทดสอบ
การทดสอบเป็นส่วนสำคัญของกระบวนการพัฒนาแอป การทดสอบแอปอย่างสม่ำเสมอช่วยยืนยันความถูกต้อง ลักษณะการทำงาน และความสามารถในการใช้งานของแอปก่อนที่จะเผยแพร่ต่อสาธารณะได้
คุณสามารถทดสอบแอปด้วย ตนเอง ได้โดยการไปยังส่วนต่างๆ ของแอป คุณอาจใช้อุปกรณ์และโปรแกรมจำลองต่างๆ เปลี่ยนภาษาของระบบ และพยายามสร้างข้อผิดพลาดของผู้ใช้ทุกรายการหรือสำรวจทุกขั้นตอนของผู้ใช้
อย่างไรก็ตาม การทดสอบด้วยตนเองปรับขนาดได้ไม่ดี และอาจมองข้ามการถดถอยในลักษณะการทำงานของแอปได้ง่าย การทดสอบอัตโนมัติเกี่ยวข้องกับการใช้เครื่องมือที่ทำการทดสอบให้คุณ ซึ่งเร็วกว่า ทำซ้ำได้มากกว่า และโดยทั่วไปจะให้ความคิดเห็นที่นำไปใช้ได้จริงมากขึ้นเกี่ยวกับแอปของคุณในช่วงต้นของกระบวนการพัฒนา
ประเภทของการทดสอบใน Android
แอปพลิเคชันบนอุปกรณ์เคลื่อนที่มีความซับซ้อนและต้องทำงานได้ดีในสภาพแวดล้อมที่หลากหลาย จึงมีการทดสอบหลายประเภท
เรื่อง
เช่น มีการทดสอบหลายประเภทขึ้นอยู่กับ เรื่อง ดังนี้
- การทดสอบฟังก์ชันการทำงาน: แอปของฉันทำงานตามที่ควรจะเป็นหรือไม่
- การทดสอบประสิทธิภาพ: แอปทำงานได้อย่างรวดเร็วและมีประสิทธิภาพหรือไม่
- การทดสอบการช่วยเหลือพิเศษ: แอปทำงานได้ดีกับบริการการช่วยเหลือพิเศษหรือไม่
- การทดสอบความเข้ากันได้: แอปทำงานได้ดีในอุปกรณ์ทุกเครื่องและระดับ API ทุกระดับหรือไม่
ขอบเขต
การทดสอบยังแตกต่างกันไปตาม ขนาด หรือ ระดับการแยก ดังนี้
- Unit Test หรือ การทดสอบขนาดเล็ก จะตรวจสอบเฉพาะส่วนเล็กๆ ของแอป เช่น เมธอดหรือคลาส
- การทดสอบแบบ End-to-End หรือ การทดสอบขนาดใหญ่ จะตรวจสอบส่วนที่ใหญ่ขึ้นของแอปในเวลาเดียวกัน เช่น ทั้งหน้าจอหรือขั้นตอนของผู้ใช้
- การทดสอบขนาดกลาง จะอยู่ระหว่างการทดสอบขนาดเล็กและขนาดใหญ่ และตรวจสอบการผสานรวม ระหว่างหน่วย 2 หน่วยขึ้นไป
การทดสอบสามารถจำแนกได้หลายวิธี อย่างไรก็ตาม สิ่งที่สำคัญที่สุดสำหรับนักพัฒนาแอปคือตำแหน่งที่การทดสอบทำงาน
การทดสอบแบบมีเครื่องมือเทียบกับการทดสอบในเครื่อง
คุณสามารถทำการทดสอบในอุปกรณ์ Android หรือในคอมพิวเตอร์เครื่องอื่นได้ ดังนี้
- การทดสอบแบบมีเครื่องมือ จะทำงานในอุปกรณ์ Android ไม่ว่าจะเป็นอุปกรณ์จริงหรืออุปกรณ์จำลอง ระบบจะสร้างและติดตั้งแอปควบคู่ไปกับ แอปทดสอบ ที่แทรกคำสั่งและอ่านสถานะ โดยปกติแล้วการทดสอบแบบมีเครื่องมือจะเป็นการทดสอบ UI ซึ่งจะเปิดแอปแล้วโต้ตอบกับแอป
- การทดสอบในเครื่อง จะทำงานในคอมพิวเตอร์สำหรับการพัฒนาซอฟต์แวร์หรือเซิร์ฟเวอร์ จึงเรียกอีกอย่างว่า การทดสอบฝั่งโฮสต์ โดยปกติแล้วการทดสอบเหล่านี้จะมีขนาดเล็กและรวดเร็ว ซึ่งจะแยกเรื่องที่ทดสอบออกจากส่วนอื่นๆ ของแอป
ไม่ใช่ว่า Unit Test ทั้งหมดจะเป็นการทดสอบในเครื่อง และไม่ใช่ว่าการทดสอบแบบ End-to-End ทั้งหมดจะทำงานในอุปกรณ์ ตัวอย่างเช่น
- การทดสอบขนาดใหญ่ในเครื่อง: คุณสามารถใช้โปรแกรมจำลอง 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()
ข้อมูลโค้ดนี้แสดงส่วนหนึ่งของ Unit Test สำหรับ 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 การทดสอบ