เมื่อทดสอบองค์ประกอบหรือระบบขององค์ประกอบ คุณจะทําในการแยก เช่น หากต้องการทดสอบ ViewModel คุณไม่จําเป็นต้องเริ่มโปรแกรมจําลองและเปิด UI เนื่องจาก ViewModel ไม่ได้ (หรือไม่ควร) ขึ้นอยู่กับเฟรมเวิร์ก Android
อย่างไรก็ตาม หัวข้อทดสอบอาจขึ้นอยู่กับหัวข้ออื่นๆ จึงจะทํางานได้ ตัวอย่างเช่น ViewModel อาจต้องใช้ที่เก็บข้อมูลจึงจะทํางานได้
เมื่อต้องระบุการพึ่งพาให้กับเรื่องที่อยู่ภายใต้การทดสอบ แนวทางปฏิบัติทั่วไปคือการสร้าง test double (หรือ test object) Test Doubles คือออบเจ็กต์ที่มีลักษณะและทํางานเหมือนคอมโพเนนต์ในแอป แต่สร้างขึ้นในการทดสอบเพื่อให้ลักษณะการทํางานหรือข้อมูลหนึ่งๆ ข้อดีหลักๆ คือช่วยให้การทดสอบเร็วและง่ายขึ้น
ประเภทของ Test Double
Test Double มีหลายประเภท ได้แก่
ปลอม | Test Double ที่มีการใช้งานคลาสที่ "ทํางาน" แต่ติดตั้งใช้งานในลักษณะที่เหมาะสําหรับการทดสอบแต่ไม่เหมาะสําหรับเวอร์ชันที่ใช้งานจริง
ตัวอย่างเช่น ฐานข้อมูลที่เก็บไว้ในหน่วยความจำ ข้อมูลจำลองไม่จําเป็นต้องใช้เฟรมเวิร์กการจําลองและเป็นแบบเบา แนะนำ |
---|---|
จำลอง | Test Double ที่ทํางานตามที่คุณตั้งโปรแกรมไว้และคาดหวังถึงการโต้ตอบ การจำลองจะทดสอบไม่ผ่านหากการโต้ตอบไม่ตรงกับข้อกำหนดที่คุณกำหนด โดยปกติแล้วการสร้างการจําลองจะใช้เฟรมเวิร์กการจําลองเพื่อให้บรรลุเป้าหมายทั้งหมดนี้
ตัวอย่างเช่น ยืนยันว่ามีการเรียกใช้เมธอดในฐานข้อมูลเพียงครั้งเดียว |
สิ่งทดแทนชั่วคราว | Test Double ที่ทํางานตามที่คุณตั้งโปรแกรมไว้ แต่ไม่มีการคาดหวังเกี่ยวกับการโต้ตอบ มักจะสร้างด้วยเฟรมเวิร์กการจำลอง เราขอแนะนำให้ใช้การจำลองแทนสแต็บเพื่อความสะดวก |
Dummy | Test Double ที่ส่งผ่านแต่ไม่ได้ใช้งาน เช่น ในกรณีที่คุณเพียงต้องระบุเป็นพารามิเตอร์
ตัวอย่าง: ฟังก์ชันว่างที่ส่งเป็น Callback การคลิก |
สายลับ | Wrapper ของออบเจ็กต์จริงซึ่งจะติดตามข้อมูลเพิ่มเติมบางอย่างด้วย ซึ่งคล้ายกับ Mock โดยปกติแล้วระบบจะหลีกเลี่ยงการใช้เงื่อนไขย่อยเนื่องจากเพิ่มความซับซ้อน ดังนั้นจึงควรใช้ข้อมูลจำลองหรือข้อมูลจำลองแทนข้อมูลสอดแนม |
เงา | ใช้ปลอมใน Robolectric |
ตัวอย่างการใช้
สมมติว่าคุณต้องการทดสอบหน่วย ViewModel ที่ขึ้นอยู่กับอินเทอร์เฟซที่ชื่อ UserRepository
และแสดงชื่อผู้ใช้รายแรกต่อ UI คุณสามารถสร้างการทดสอบจำลองปลอมได้โดยใช้อินเทอร์เฟซและแสดงข้อมูลที่ทราบ
object FakeUserRepository : UserRepository {
fun getUsers() = listOf(UserAlice, UserBob)
}
val const UserAlice = User("Alice")
val const UserBob = User("Bob")
UserRepository
จำลองนี้ไม่จำเป็นต้องใช้แหล่งข้อมูลในเครื่องและระยะไกลที่เวอร์ชันที่ใช้งานจริงจะใช้ ไฟล์จะอยู่ในชุดแหล่งที่มาทดสอบและจะไม่มาพร้อมกับแอปเวอร์ชันที่ใช้งานจริง
การทดสอบต่อไปนี้จะยืนยันว่า ViewModel แสดงชื่อผู้ใช้แรกต่อมุมมองอย่างถูกต้อง
@Test
fun viewModelA_loadsUsers_showsFirstUser() {
// Given a VM using fake data
val viewModel = ViewModelA(FakeUserRepository) // Kicks off data load on init
// Verify that the exposed data is correct
assertEquals(viewModel.firstUserName, UserAlice.name)
}
การแทนที่ UserRepository
ด้วยค่าจำลองนั้นทำได้ง่ายในการทดสอบหน่วย เนื่องจากผู้ทดสอบเป็นผู้สร้าง ViewModel อย่างไรก็ตาม การแทนที่องค์ประกอบที่กำหนดเองในการทดสอบขนาดใหญ่อาจเป็นเรื่องยาก
การเปลี่ยนคอมโพเนนต์และการฉีด Dependency
เมื่อการทดสอบไม่สามารถควบคุมการสร้างระบบที่ทดสอบได้ การเปลี่ยนคอมโพเนนต์สําหรับการทดสอบจำลองจึงมีความซับซ้อนมากขึ้น และสถาปัตยกรรมของแอปต้องเป็นไปตามการออกแบบที่ทดสอบได้
แม้แต่การทดสอบจากต้นจนจบขนาดใหญ่ก็อาจได้รับประโยชน์จากการใช้ Test Doubles เช่น การทดสอบ UI ที่มีเครื่องมือวัดผลซึ่งไปยังส่วนต่างๆ ของเส้นทางผู้ใช้ทั้งหมดในแอป ในกรณีนี้ คุณอาจต้องทำให้การทดสอบปิดตาย การทดสอบแบบปิดผนึกจะหลีกเลี่ยงการพึ่งพาภายนอกทั้งหมด เช่น การดึงข้อมูลจากอินเทอร์เน็ต ซึ่งจะช่วยปรับปรุงความน่าเชื่อถือและประสิทธิภาพ
คุณสามารถออกแบบแอปเพื่อให้มีความยืดหยุ่นนี้ด้วยตนเองได้ แต่เราขอแนะนำให้ใช้เฟรมเวิร์กการฉีดข้อมูล Dependency เช่น Hilt เพื่อแทนที่คอมโพเนนต์ในแอปของคุณเมื่อถึงเวลาทดสอบ โปรดดูคู่มือการทดสอบ Hilt
ขั้นตอนถัดไป
หน้ากลยุทธ์การทดสอบจะแสดงวิธีปรับปรุงประสิทธิภาพโดยใช้การทดสอบประเภทต่างๆ