พื้นฐานการทดสอบแอป 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()

ข้อมูลโค้ดนี้แสดงส่วนหนึ่งของการทดสอบหน่วยสำหรับ 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)

การกำหนดกลยุทธ์การทดสอบ

ในสถานการณ์ที่ดีที่สุด คุณจะต้องทดสอบโค้ดทุกบรรทัดในแอปของคุณบนอุปกรณ์ทุกชนิด ที่แอปของคุณใช้ร่วมกันได้ด้วย ขออภัย วิธีนี้ช้าเกินไป มีค่าใช้จ่ายสูงในทางปฏิบัติ

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

การทดสอบที่ไม่น่าเชื่อถือ

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

สถาปัตยกรรมที่ทดสอบได้

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

สถาปัตยกรรมที่ทดสอบไม่ได้จะสร้างสิ่งต่อไปนี้

  • การทดสอบขนาดใหญ่ขึ้น ช้าลง และไม่สม่ำเสมอมากขึ้น ชั้นเรียนที่ไม่สามารถทดสอบหน่วยได้อาจมี อยู่ในการทดสอบการผสานรวมหรือการทดสอบ UI ที่ใหญ่ขึ้น
  • มีโอกาสน้อยลงสำหรับการทดสอบสถานการณ์ต่างๆ การทดสอบขนาดใหญ่จะช้ากว่า ดังนั้นการทดสอบสถานะทั้งหมดที่เป็นไปได้ของแอปอาจไม่สมจริง

หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับหลักเกณฑ์ด้านสถาปัตยกรรม โปรดดูคู่มือสำหรับแอป สถาปัตยกรรม

แนวทางการแยกส่วน

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

เทคนิคการแยกแยะการเชื่อมต่อทั่วไปมีดังนี้

  • แยกแอปออกเป็นเลเยอร์ เช่น งานนำเสนอ โดเมน และข้อมูล คุณสามารถ แยกแอปออกเป็นโมดูลด้วย 1 รายการต่อฟีเจอร์
  • หลีกเลี่ยงการเพิ่มตรรกะในเอนทิตีที่มีทรัพยากร Dependency มาก เช่น กิจกรรมและส่วนย่อย ใช้คลาสเหล่านี้เป็นจุดแรกเข้าของเฟรมเวิร์กและ ย้ายตรรกะ UI และธุรกิจไปที่อื่น เช่น Composable, ViewModel หรือ
  • หลีกเลี่ยงการพึ่งพาเฟรมเวิร์กโดยตรงในชั้นเรียนที่มีตรรกะทางธุรกิจ ตัวอย่างเช่น อย่าใช้ Android Contexts ใน ViewModels
  • ทำให้แทนที่ทรัพยากร Dependency ได้ง่าย ตัวอย่างเช่น ให้ใช้ อินเทอร์เฟซแทนการนำไปใช้งานที่เป็นรูปธรรม ใช้ การแทรกการขึ้นต่อกันแม้ว่าคุณจะไม่ได้ใช้เฟรมเวิร์ก DI ก็ตาม

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

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

หรือถ้าคุณต้องการสร้างการทดสอบแรกแล้วเรียนรู้โดยทำ Testing Codelab