เมื่อออกแบบกลยุทธ์การทดสอบ องค์ประกอบหรือระบบ จะมี 3 ปัจจัย ลักษณะการทดสอบที่เกี่ยวข้อง:
- ขอบเขต: การทดสอบจะทดสอบโค้ดมากน้อยแค่ไหน การทดสอบสามารถยืนยัน ทั้งแอปพลิเคชัน หรือในระหว่างนั้น ขอบเขตที่ทดสอบอยู่ในระหว่างการทดสอบ และโดยทั่วไปเรียกขอบเขตนี้ว่าเรื่องภายใต้ ทดสอบ รวมถึงระบบภายใต้การทดสอบหรือหน่วยที่อยู่ภายใต้การทดสอบด้วย
- ความเร็ว: การทดสอบเร็วเพียงใด ความเร็วในการทดสอบอาจแตกต่างกันไปจากมิลลิวินาที หลายนาที
- ความสอดคล้อง: "โลกแห่งความเป็นจริง" คือการทดสอบ ตัวอย่างเช่น หากส่วนของโค้ด ที่คุณกำลังทดสอบต้องส่งคำขอเครือข่าย โค้ดทดสอบนั้น คำขอเครือข่ายนี้ หรือผลลัพธ์ปลอม หากการทดสอบพูดจริงๆ กับเครือข่าย หมายความว่าเครือข่ายจะมีความแม่นยำสูงกว่า ข้อดีคือ อาจใช้เวลานานกว่านี้ อาจทำให้เกิดข้อผิดพลาดหากเครือข่ายไม่พร้อมให้บริการ หรือ อาจมีค่าใช้จ่ายในการใช้งานสูง
ดูสิ่งที่ควรทดสอบเพื่อดูวิธีเริ่มต้นกำหนดกลยุทธ์การทดสอบ
การแยกและทรัพยากร Dependency
เมื่อทดสอบองค์ประกอบเดียวหรือระบบขององค์ประกอบ คุณจะทดสอบได้ในการแยก สำหรับ ตัวอย่างเช่น ในการทดสอบ ViewModel คุณไม่จำเป็นต้องเริ่มโปรแกรมจำลองและเปิดใช้ UI (หรือไม่ควร) ขึ้นอยู่กับเฟรมเวิร์กของ Android
อย่างไรก็ตาม ผู้เข้าร่วมทดสอบอาจขึ้นอยู่กับคุณสมบัติอื่นๆ ของการทดสอบ สำหรับ ViewModel อาจต้องอาศัยที่เก็บข้อมูลในการทำงาน
เมื่อคุณต้องพึ่งพาสิ่งที่อยู่ในการทดสอบ แนวทางปฏิบัติทั่วไป คือการสร้าง Test Double (หรือ test Object) Test Double คือออบเจ็กต์ที่ มองและทำหน้าที่เป็นคอมโพเนนต์ในแอป แต่สร้างขึ้นในการทดสอบ ระบุลักษณะการทำงานหรือข้อมูลเฉพาะ ข้อดีหลักๆ คือ ทดสอบได้เร็วและง่ายขึ้น
ประเภทของการทดสอบคู่
คู่ทดสอบมีหลายประเภท ได้แก่
ปลอม | การทดสอบ 2 เท่าที่แสดงว่า "ทำงานได้" แต่เป็นการติดตั้งใช้งานในลักษณะที่ส่งผลดีต่อการทดสอบ แต่ไม่เหมาะสําหรับการใช้งานจริง
ตัวอย่าง: ฐานข้อมูลในหน่วยความจำ ส่วนปลอมไม่จำเป็นต้องใช้เฟรมเวิร์กการจำลองและมีขนาดเล็ก แนะนําให้แนะนํา |
---|---|
จำลอง | การทดสอบแบบ 2 เท่าเกี่ยวกับลักษณะการทำงานที่ตั้งโปรแกรมไว้และมีความคาดหวังเกี่ยวกับการโต้ตอบ การจำลองจะไม่ผ่านการทดสอบหากการโต้ตอบของตัวละครไม่ตรงกับข้อกำหนดที่คุณกำหนดไว้ การจำลองมักจะสร้างขึ้นด้วยกรอบการทำงานจำลองเพื่อให้บรรลุเป้าหมายทั้งหมดนี้
ตัวอย่าง: ยืนยันว่ามีการเรียกเมธอดในฐานข้อมูลเพียงครั้งเดียว |
สิ่งทดแทนชั่วคราว | การทดสอบแบบ 2 เท่าที่จะกำหนดลักษณะการทำงานของโปรแกรมดังกล่าว แต่ไม่มีความคาดหวังเกี่ยวกับการโต้ตอบของชิ้นงาน โดยปกติแล้วจะสร้างด้วยกรอบการทำงานจำลอง ส่วนเรื่องปลอมๆ จะแนะนำให้ใช้มากกว่าต้นขั้วเพื่อความง่าย |
Dummy | การทดสอบ 2 ส่วนที่จะส่งต่อแต่ไม่ได้นำไปใช้ เช่น ในกรณีที่คุณแค่ต้องระบุเป็นพารามิเตอร์
ตัวอย่าง: ฟังก์ชันว่างที่ส่งผ่านเป็น Callback ที่มีการคลิก |
สายลับ | กระดาษห่อคลุมวัตถุจริงซึ่งจะติดตามข้อมูลเพิ่มเติมบางอย่างด้วย ซึ่งคล้ายกับการจำลอง แต่มักหลีกเลี่ยงในกรณีที่เพิ่มความซับซ้อน ดังนั้น การปลอมหรือล้อเลียนจึงเหมาะสำหรับสายลับมากกว่า |
เงา | ของปลอมที่ใช้ในโรโมเลคตริกซ์ |
ตัวอย่างการใช้ไฟล์ปลอม
สมมติว่าคุณต้องการทดสอบ 1 หน่วยของ ViewModel ที่ขึ้นอยู่กับอินเทอร์เฟซ
ชื่อ UserRepository
และแสดงชื่อของผู้ใช้รายแรกใน UI คุณสามารถ
สร้างการทดสอบปลอมโดยใช้อินเทอร์เฟซและแสดงผล
object FakeUserRepository : UserRepository {
fun getUsers() = listOf(UserAlice, UserBob)
}
val const UserAlice = User("Alice")
val const UserBob = User("Bob")
UserRepository
ปลอมนี้ไม่จำเป็นต้องอ้างอิงข้อมูลในเครื่องและระยะไกล
ที่เวอร์ชันที่ใช้งานจริงจะใช้ ไฟล์อยู่ในแหล่งที่มาทดสอบ
และจะไม่จัดส่งไปกับแอปเวอร์ชันที่ใช้งานจริง
![ทรัพยากร Dependency ปลอมอาจแสดงข้อมูลที่รู้จักได้โดยไม่ต้องใช้แหล่งข้อมูลระยะไกล](https://developer.android.com/static/training/testing/fundamentals/fake-deps.png?authuser=2&hl=th)
การทดสอบต่อไปนี้ยืนยันว่า 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
ด้วย ปลอมนั้นทำได้ง่ายในการทดสอบ 1 หน่วย เนื่องจาก
ViewModel สร้างขึ้นโดยผู้ทดสอบ แต่อาจเป็นงานที่ท้าทาย
องค์ประกอบที่กำหนดเองในการทดสอบที่ใหญ่ขึ้น
การแทนที่คอมโพเนนต์และการแทรกทรัพยากร Dependency
เมื่อการทดสอบไม่มีสิทธิ์ควบคุมการสร้างระบบที่อยู่ระหว่างการทดสอบ การแทนที่คอมโพเนนต์ทดสอบซ้ำซ้อนมากขึ้นและต้องใช้ สถาปัตยกรรมของแอปให้เป็นไปตามการออกแบบที่ทดสอบได้
แม้แต่การทดสอบในภาพรวมขนาดใหญ่ก็ได้ประโยชน์จากการใช้การทดสอบแบบคู่ เช่น การทดสอบ UI แบบมีเครื่องควบคุมที่นำทางผู้ใช้ผ่านขั้นตอนทั้งหมดในแอป ใน คุณอาจต้องการทำการทดสอบแบบรวม การทดสอบที่สุญญากาศหลีกเลี่ยง ทรัพยากร Dependency ภายนอกทั้งหมด เช่น การดึงข้อมูลจากอินเทอร์เน็ต ช่วงเวลานี้ ช่วยเพิ่มความเสถียรและประสิทธิภาพ
![](https://developer.android.com/static/training/testing/fundamentals/bigtest.png?authuser=2&hl=th)
คุณสามารถออกแบบแอปเพื่อให้มีความยืดหยุ่นนี้ด้วยตนเอง แต่เราขอแนะนำให้ โดยใช้เฟรมเวิร์ก Dependency Injection เช่น Hilt เพื่อแทนที่คอมโพเนนต์ ในแอปของคุณในช่วงเวลาทดสอบ โปรดดูคู่มือการทดสอบ Hit
โรโบเลตริก
ใน Android คุณสามารถใช้เฟรมเวิร์ก Robolectric ซึ่ง จะระบุประเภทการทดสอบพิเศษแบบทวีคูณ Robolectric ช่วยให้คุณทดสอบกับ เวิร์กสเตชัน หรือในสภาพแวดล้อมการผสานรวมอย่างต่อเนื่อง โดยใช้ JVM ปกติ โดยไม่มีโปรแกรมจำลองหรืออุปกรณ์ โดยเป็นการจำลองจำนวนการดูให้สูงเกินจริง การโหลดทรัพยากร และส่วนอื่นๆ ของเฟรมเวิร์ก Android ที่มีการทดสอบเพิ่มขึ้นเป็นสองเท่า ที่เรียกว่าเงา
Robolectric เป็นโปรแกรมจำลอง จึงไม่ควรแทนที่การทดสอบ 1 หน่วยอย่างง่าย หรือใช้ ทำการทดสอบความเข้ากันได้ ให้ความเร็วและลดต้นทุนโดยเสียค่าใช้จ่าย จะมีรายละเอียดเสมือนจริงน้อยกว่าในบางกรณี วิธีที่ดีสำหรับการทดสอบ UI คือการสร้าง ใช้ได้กับทั้งการทดสอบแบบ Robolectric และการทดสอบแบบมีเครื่องวัด และตัดสินใจว่าจะเรียกใช้เมื่อใด ทั้งนี้ขึ้นอยู่กับความจำเป็นในการทดสอบฟังก์ชันการทำงานหรือความเข้ากันได้ ทั้งเอสเปรสโซ และการทดสอบ Compose จะเรียกใช้ได้ใน Robolectric