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

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

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

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

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

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

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

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

เรื่อง

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

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

ขอบเขต

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

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

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

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

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

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

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

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

// When the Continue button is clicked
composeTestRule.onNodeWithText("Continue").performClick()

// Then the Welcome screen is displayed
composeTestRule.onNodeWithText("Welcome").assertIsDisplayed()

ข้อมูลโค้ดนี้แสดงส่วนหนึ่งของการทดสอบ 1 หน่วยสําหรับ 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 แอปต่อฟีเจอร์
  • หลีกเลี่ยงการเพิ่มตรรกะในเอนทิตีที่มีทรัพยากร Dependency ขนาดใหญ่ เช่น กิจกรรมและส่วนย่อย ใช้คลาสเหล่านี้เป็นจุดแรกเข้าของเฟรมเวิร์ก และย้ายUI และตรรกะทางธุรกิจไปไว้ที่อื่น เช่น Composable, ViewModel หรือเลเยอร์โดเมน
  • หลีกเลี่ยงการพึ่งพาเฟรมเวิร์กโดยตรงในคลาสที่มีตรรกะทางธุรกิจ เช่น อย่าใช้บริบท Android ใน ViewModel
  • ทําให้แทนที่การอ้างอิงได้ง่าย เช่น ใช้อินเทอร์เฟซแทนการใช้งานที่เจาะจง ใช้การฉีดข้อมูล Dependency แม้ว่าคุณจะไม่ได้ใช้เฟรมเวิร์ก DI ก็ตาม

ขั้นตอนถัดไป

เมื่อทราบเหตุผลที่ควรทดสอบและการทดสอบ 2 ประเภทหลักแล้ว คุณสามารถอ่านสิ่งที่ควรทดสอบหรือดูข้อมูลเกี่ยวกับกลยุทธ์การทดสอบ

หรือหากต้องการสร้างการทดสอบแรกและเรียนรู้จากการทําจริง ให้ไปที่Codelab การทดสอบ