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

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

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

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

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

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

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

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

เรื่อง

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

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

ขอบเขต

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

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

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

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

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

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

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

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