หน้านี้สรุปหลักการสำคัญของการทดสอบแอป Android ซึ่งรวมถึง แนวทางปฏิบัติแนะนำจากส่วนกลาง และประโยชน์ที่มี
ประโยชน์ของการทดสอบ
การทดสอบเป็นส่วนสำคัญของกระบวนการพัฒนาแอป โดยการเรียกใช้การทดสอบ แอปของคุณอย่างสม่ำเสมอ คุณสามารถยืนยันความถูกต้อง การทำงานของแอป พฤติกรรม และความสามารถในการใช้งานของคุณก่อนเผยแพร่สู่สาธารณะ
คุณทดสอบแอปด้วยตนเองได้โดยการไปยังส่วนต่างๆ คุณอาจใช้ อุปกรณ์และโปรแกรมจำลองต่างๆ เปลี่ยนภาษาของระบบ และพยายามสร้าง ข้อผิดพลาดของผู้ใช้หรือข้ามผ่านโฟลว์ของผู้ใช้ได้ทั้งหมด
อย่างไรก็ตาม การทดสอบด้วยตนเองปรับขนาดได้ไม่ดี และอาจทำให้มองข้ามได้ง่าย การเกิดปัญหาซ้ำในลักษณะการทำงานของแอป การทดสอบอัตโนมัติเกี่ยวข้องกับการใช้เครื่องมือ ที่ทำการทดสอบให้คุณ ซึ่งเร็วกว่า ทำซ้ำได้มากขึ้น และโดยทั่วไป ให้ความคิดเห็นที่นําไปใช้ได้จริงมากขึ้นเกี่ยวกับแอปของคุณในช่วงต้นของการพัฒนา ขั้นตอนได้
ประเภทการทดสอบใน Android
แอปพลิเคชันบนอุปกรณ์เคลื่อนที่มีความซับซ้อนและต้องทำงานได้ดีในหลายสภาพแวดล้อม อาส ซึ่งทำให้การทดสอบมีหลายประเภท
เรื่อง
เช่น มีการทดสอบประเภทต่างๆ โดยขึ้นอยู่กับเรื่อง ดังนี้
- การทดสอบการทำงาน: แอปของฉันทำในสิ่งที่ระบบควรจะทำหรือไม่
- การทดสอบประสิทธิภาพ: ดำเนินการได้อย่างรวดเร็วและมีประสิทธิภาพไหม
- การทดสอบการช่วยเหลือพิเศษ: ทํางานได้ดีกับบริการการช่วยเหลือพิเศษไหม
- การทดสอบความเข้ากันได้: ทํางานได้ดีในอุปกรณ์ทุกเครื่องและระดับ API หรือไม่
ขอบเขต
การทดสอบยังแตกต่างกันไปตามขนาดหรือระดับการแยกส่วนดังนี้
- การทดสอบหน่วยหรือการทดสอบเล็กๆ จะยืนยันตัวแอปเพียงเล็กน้อยเท่านั้น เช่น เมธอดหรือชั้นเรียน
- การทดสอบแบบต้นทางถึงปลายทางหรือการทดสอบครั้งใหญ่จะตรวจสอบเรื่องขนาดใหญ่ของแอป ในเวลาเดียวกัน เช่น ทั้งหน้าจอหรือขั้นตอนการใช้งานของผู้ใช้
- การทดสอบขนาดกลางจะอยู่ระหว่าง และตรวจสอบการผสานรวมระหว่าง 2 หรือ หน่วยเพิ่มเติม
![การทดสอบอาจมีขนาดเล็ก กลาง หรือใหญ่ก็ได้](https://developer.android.com/static/training/testing/fundamentals/test-scopes.png?authuser=19&hl=th)
การแยกประเภทการทดสอบทำได้หลายวิธี อย่างไรก็ตาม ความแตกต่างที่สำคัญที่สุด สำหรับนักพัฒนาแอป คือพื้นที่ทำการทดสอบ
การทดสอบแบบมีเครื่องดนตรีเทียบกับการทดสอบในท้องถิ่น
คุณทำการทดสอบในอุปกรณ์ Android หรือคอมพิวเตอร์เครื่องอื่นก็ได้ โดยทำดังนี้
- การทดสอบด้วยเครื่องมือจะทำงานในอุปกรณ์ Android ไม่ว่าจะเป็นอุปกรณ์จริงหรือการจำลอง แอปสร้างและติดตั้งพร้อมกับแอปทดสอบที่แทรกคำสั่งและ อ่านรัฐ การทดสอบที่มีเครื่องมือมักจะเป็นการทดสอบ UI, การเปิดตัวแอปและ แล้วก็โต้ตอบกับสิ่งนั้น
- การทดสอบในเครื่อง จะดำเนินการบนเครื่องสำหรับการพัฒนาหรือเซิร์ฟเวอร์ ดังนั้นการทดสอบดังกล่าวจะ หรือเรียกว่าการทดสอบฝั่งโฮสต์ สัตว์ประเภทนี้มักมีขนาดเล็กและเร็วและอยู่โดดเดี่ยว เรื่องที่กำลังทดสอบจากส่วนที่เหลือของแอป
![การทดสอบจะทำงานเป็นการทดสอบแบบมีเครื่องวัดในอุปกรณ์ หรือจะใช้ทดสอบในเครื่องสำหรับพัฒนาก็ได้](https://developer.android.com/static/training/testing/fundamentals/instru-vs-local.png?authuser=19&hl=th)
การทดสอบ 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