พื้นฐานการทดสอบแอป Android

หน้านี้สรุปหลักการสำคัญของการทดสอบแอป Android ซึ่งรวมถึงแนวทางปฏิบัติแนะนำหลักและประโยชน์ของแนวทางดังกล่าว

สิทธิประโยชน์ของการทดสอบ

การทดสอบเป็นส่วนสำคัญของกระบวนการพัฒนาแอป การทดสอบแอปอย่างสม่ำเสมอช่วยยืนยันความถูกต้อง ลักษณะการทำงาน และความสามารถในการใช้งานของแอปก่อนที่จะเผยแพร่ต่อสาธารณะได้

คุณสามารถทดสอบแอปด้วยตนเองโดยการใช้งานแอป คุณอาจใช้อุปกรณ์และโปรแกรมจำลองอุปกรณ์ที่แตกต่างกัน เปลี่ยนภาษาของระบบ และพยายามสร้างข้อผิดพลาดของผู้ใช้ทุกข้อผิดพลาดหรือใช้งานทุกขั้นตอนของผู้ใช้

อย่างไรก็ตาม การทดสอบด้วยตนเองปรับขนาดได้ไม่ดี และอาจมองข้ามการถดถอยในลักษณะการทำงานของแอปได้ง่าย การทดสอบอัตโนมัติเกี่ยวข้องกับการใช้เครื่องมือที่ทำการทดสอบให้คุณ ซึ่งเร็วกว่า ทำซ้ำได้มากกว่า และโดยทั่วไปจะให้ความคิดเห็นที่นำไปใช้ได้จริงมากขึ้นเกี่ยวกับแอปของคุณในระยะแรกๆ ของกระบวนการพัฒนา

ประเภทของการทดสอบใน Android

แอปพลิเคชันบนอุปกรณ์เคลื่อนที่มีความซับซ้อนและต้องทำงานได้ดีในสภาพแวดล้อมที่หลากหลาย จึงมีการทดสอบหลายประเภท

เรื่อง

ตัวอย่างเช่น การทดสอบมีหลายประเภทขึ้นอยู่กับ เรื่อง ดังนี้

  • การทดสอบฟังก์ชันการทำงาน: แอปของฉันทำงานตามที่ควรจะเป็นหรือไม่
  • การทดสอบประสิทธิภาพ: แอปทำงานได้อย่างรวดเร็วและมีประสิทธิภาพหรือไม่
  • การทดสอบการช่วยเหลือพิเศษ: แอปทำงานได้ดีกับบริการการช่วยเหลือพิเศษหรือไม่
  • การทดสอบความเข้ากันได้: แอปทำงานได้ดีในอุปกรณ์ทุกเครื่องและระดับ API ทุกระดับหรือไม่

ขอบเขต

การทดสอบยังแตกต่างกันไปตาม ขนาด หรือ ระดับการแยก ดังนี้

  • การทดสอบหน่วย หรือการทดสอบขนาดเล็ก จะตรวจสอบเฉพาะส่วนเล็กๆ ของแอป เช่น เมธอดหรือคลาส
  • การทดสอบแบบครบวงจร หรือการทดสอบขนาดใหญ่ จะตรวจสอบแอปส่วนใหญ่พร้อมกัน เช่น ทั้งหน้าจอหรือขั้นตอนของผู้ใช้
  • การทดสอบขนาดกลาง จะอยู่ระหว่างการทดสอบขนาดเล็กและการทดสอบขนาดใหญ่ และจะตรวจสอบการผสานรวม ระหว่างหน่วย 2 หน่วยขึ้นไป
การทดสอบอาจมีขนาดเล็ก ปานกลาง หรือใหญ่ก็ได้
รูปที่ 1: ขอบเขตการทดสอบในแอปพลิเคชันทั่วไป

การทดสอบสามารถจำแนกได้หลายวิธี อย่างไรก็ตาม สิ่งที่สำคัญที่สุดสำหรับนักพัฒนาแอปคือตำแหน่งที่การทดสอบทำงาน

การทดสอบแบบมีเครื่องมือเทียบกับการทดสอบในเครื่อง

คุณสามารถทำการทดสอบในอุปกรณ์ Android หรือในคอมพิวเตอร์เครื่องอื่นได้

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

การทดสอบหน่วยบางรายการไม่ได้เป็นการทดสอบในเครื่อง และการทดสอบแบบครบวงจรบางรายการไม่ได้ทำงานในอุปกรณ์ ตัวอย่างเช่น

  • การทดสอบในเครื่องขนาดใหญ่: คุณสามารถใช้โปรแกรมจำลอง 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 การทดสอบ