ใช้การทดสอบแบบทวีคูณใน Android

เมื่อทดสอบองค์ประกอบหรือระบบขององค์ประกอบ คุณจะทําในการแยก เช่น หากต้องการทดสอบ ViewModel คุณไม่จําเป็นต้องเริ่มโปรแกรมจําลองและเปิด UI เนื่องจาก ViewModel ไม่ได้ (หรือไม่ควร) ขึ้นอยู่กับเฟรมเวิร์ก Android

อย่างไรก็ตาม ผู้เข้าร่วมทดสอบอาจขึ้นอยู่กับคุณสมบัติอื่นๆ ของการทดสอบ ตัวอย่างเช่น ViewModel อาจต้องใช้ที่เก็บข้อมูลจึงจะทํางานได้

เมื่อต้องระบุการพึ่งพาให้กับเรื่องที่อยู่ภายใต้การทดสอบ แนวทางปฏิบัติทั่วไปคือการสร้าง test double (หรือ test object) Test Doubles คือออบเจ็กต์ที่มีลักษณะและทํางานเหมือนคอมโพเนนต์ในแอป แต่สร้างขึ้นในการทดสอบเพื่อให้ลักษณะการทํางานหรือข้อมูลหนึ่งๆ ข้อดีหลักๆ คือช่วยให้การทดสอบเร็วและง่ายขึ้น

ประเภทของ Test Double

คู่ทดสอบมีหลายประเภท ได้แก่

ปลอม Test Double ที่มีการใช้งานคลาสที่ "ทํางาน" แต่ติดตั้งใช้งานในลักษณะที่เหมาะสําหรับการทดสอบแต่ไม่เหมาะสําหรับเวอร์ชันที่ใช้งานจริง

ตัวอย่างเช่น ฐานข้อมูลที่เก็บไว้ในหน่วยความจำ

ข้อมูลจำลองไม่จําเป็นต้องใช้เฟรมเวิร์กการจําลองและเป็นแบบเบา แนะนำ

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

ตัวอย่างเช่น ยืนยันว่ามีการเรียกใช้เมธอดในฐานข้อมูลเพียงครั้งเดียว

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

ตัวอย่าง: ฟังก์ชันว่างที่ส่งผ่านเป็น Callback ที่มีการคลิก

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

ตัวอย่างการใช้

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

object FakeUserRepository : UserRepository {
    fun getUsers() = listOf(UserAlice, UserBob)
}

val const UserAlice = User("Alice")
val const UserBob = User("Bob")

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

Dependency ปลอมสามารถแสดงข้อมูลที่ทราบโดยไม่ต้องอาศัยแหล่งข้อมูลระยะไกล
รูปที่ 1: ทรัพยากร Dependency ปลอมในการทดสอบ 1 หน่วย

การทดสอบต่อไปนี้ยืนยันว่า 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 ที่มีเครื่องมือวัดผลซึ่งไปยังส่วนต่างๆ ของเส้นทางผู้ใช้ทั้งหมดในแอป ในกรณีนี้ คุณอาจต้องทำให้การทดสอบปิดตาย การทดสอบที่แยกต่างหากจะหลีกเลี่ยงการพึ่งพิงภายนอกทั้งหมด เช่น การดึงข้อมูลจากอินเทอร์เน็ต ซึ่งจะช่วยเพิ่มความน่าเชื่อถือและประสิทธิภาพ

รูปที่ 2: การทดสอบครั้งใหญ่ที่ครอบคลุมแอปส่วนใหญ่และข้อมูลระยะไกลจำลอง

คุณสามารถออกแบบแอปเพื่อให้มีความยืดหยุ่นนี้ด้วยตนเองได้ แต่เราขอแนะนำให้ใช้เฟรมเวิร์กการฉีดข้อมูล Dependency เช่น Hilt เพื่อแทนที่คอมโพเนนต์ในแอปของคุณเมื่อถึงเวลาทดสอบ ดูคู่มือการทดสอบ Hit

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

หน้ากลยุทธ์การทดสอบจะแสดงวิธีปรับปรุงประสิทธิภาพโดยใช้การทดสอบประเภทต่างๆ