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