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

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

การแทนที่คอมโพเนนต์และการแทรกทรัพยากร Dependency

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

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

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

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

โรโบเลตริก

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

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