การทดสอบในเครื่องจะดำเนินการในเวิร์กสเตชันของคุณเองโดยตรง ไม่ใช่ใน Android อุปกรณ์หรือโปรแกรมจำลอง ด้วยเหตุนี้ ระบบจึงใช้ Java Virtual Machine (JVM) ในเครื่องของคุณ แทนที่จะใช้อุปกรณ์ Android เพื่อทำการทดสอบ การทดสอบในเครื่องจะช่วยให้คุณสามารถประเมิน ตรรกะของแอปคุณได้เร็วยิ่งขึ้น อย่างไรก็ตาม ไม่สามารถโต้ตอบกับ เฟรมเวิร์ก Android สร้างข้อจำกัดประเภทการทดสอบที่คุณจะทำได้
การทดสอบ unit จะยืนยันลักษณะการทำงานของส่วนเล็กๆ ของโค้ด หน่วยที่อยู่ใต้ test โดยการเรียกใช้โค้ดและตรวจสอบผลลัพธ์
การทดสอบ 1 หน่วยมักจะทำได้ง่าย แต่การตั้งค่าอาจทำให้เกิดปัญหาเมื่อหน่วย อยู่ระหว่างทดสอบไม่ได้ออกแบบโดยคำนึงถึงความสามารถในการทดสอบ
- รหัสที่คุณต้องการยืนยันต้องเข้าถึงได้จากการทดสอบ สำหรับ เช่น คุณจะทดสอบเมธอดส่วนตัวโดยตรงไม่ได้ แต่คุณจะทดสอบชั้นเรียน โดยใช้ API สาธารณะ
- ในการเรียกใช้การทดสอบหน่วยในการแยก ทรัพยากร Dependency ของหน่วย ที่อยู่ในการทดสอบต้องแทนที่ด้วยคอมโพเนนต์ที่คุณควบคุม เช่น ปลอม หรือ คู่ทดลองอื่นๆ โดยเฉพาะอย่างยิ่งหากโค้ดของคุณขึ้นอยู่กับ เฟรมเวิร์กของ Android
หากต้องการเรียนรู้เกี่ยวกับกลยุทธ์การทดสอบ 1 หน่วยที่พบบ่อยใน Android โปรดอ่านสิ่งที่ต้องทำ test
ตำแหน่งการทดสอบในพื้นที่
โดยค่าเริ่มต้น ไฟล์ต้นฉบับสำหรับการทดสอบหน่วยในเครื่องจะอยู่ใน
module-name/src/test/
มีไดเรกทอรีนี้อยู่แล้วเมื่อคุณสร้าง
โดยใช้ Android Studio
การเพิ่มทรัพยากร Dependency ทดสอบ
นอกจากนี้ คุณยังต้องกำหนดค่าทรัพยากร Dependency ของการทดสอบสำหรับโปรเจ็กต์ของคุณเพื่อใช้โอเปอเรเตอร์ API มาตรฐานที่ให้บริการโดยเฟรมเวิร์กการทดสอบ JUnit
โดยเปิดไฟล์ build.gradle
ของโมดูลแอปและระบุข้อมูลต่อไปนี้
เป็นทรัพยากร Dependency ได้ ใช้ฟังก์ชัน testImplementation
เพื่อระบุ
ที่ใช้กับชุดแหล่งที่มาทดสอบในเครื่อง ไม่ใช่แอปพลิเคชัน
dependencies {
// Required -- JUnit 4 framework
testImplementation "junit:junit:$jUnitVersion"
// Optional -- Robolectric environment
testImplementation "androidx.test:core:$androidXTestVersion"
// Optional -- Mockito framework
testImplementation "org.mockito:mockito-core:$mockitoVersion"
// Optional -- mockito-kotlin
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion"
// Optional -- Mockk framework
testImplementation "io.mockk:mockk:$mockkVersion"
}
สร้างชั้นเรียนการทดสอบหน่วยท้องถิ่น
คุณเขียนชั้นเรียนการทดสอบหน่วยท้องถิ่นเป็นชั้นเรียนการทดสอบ JUnit 4
โดยให้คุณสร้างชั้นเรียนที่มีวิธีการทดสอบอย่างน้อย 1 วิธี ซึ่งโดยปกติแล้วจะอยู่ใน
module-name/src/test/
วิธีการทดสอบเริ่มต้นด้วยคำอธิบายประกอบ @Test
และ
มีโค้ดสำหรับใช้งานและตรวจสอบองค์ประกอบด้านเดียวที่
ที่คุณต้องการทดสอบ
ตัวอย่างต่อไปนี้สาธิตวิธีใช้คลาสการทดสอบ 1 หน่วยในเครื่อง
วิธีการทดสอบemailValidator_correctEmailSimple_returnsTrue()
ความพยายามเพื่อยืนยัน
isValidEmail()
ซึ่งเป็นเมธอดภายในแอป ฟังก์ชันทดสอบจะแสดงผล
"จริง" หากisValidEmail()
แสดงผลเป็น "จริง" ด้วย
Kotlin
import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test class EmailValidatorTest { @Test fun emailValidator_CorrectEmailSimple_ReturnsTrue() { assertTrue(EmailValidator.isValidEmail("name@email.com")) } }
Java
import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; class EmailValidatorTest { @Test public void emailValidator_CorrectEmailSimple_ReturnsTrue() { assertTrue(EmailValidator.isValidEmail("name@email.com")); } }
คุณควรสร้างการทดสอบที่อ่านได้เพื่อประเมินว่าองค์ประกอบใน
แอปจะแสดงผลลัพธ์ที่คาดหวัง เราขอแนะนำให้คุณใช้ไลบรารีการยืนยัน
เป็น junit.Assert, Hamcrest หรือ
ความจริง ตัวอย่างด้านบนเป็นตัวอย่างวิธีใช้
junit.Assert
ไลบรารี Android ที่จำลองได้
เมื่อคุณดำเนินการทดสอบหน่วยในเครื่อง ปลั๊กอิน Android Gradle จะมี ที่มี API ทั้งหมดของเฟรมเวิร์ก Android ให้แก้ไข เวอร์ชันที่ใช้ในโปรเจ็กต์ ห้องสมุดเก็บวิธีการสาธารณะทั้งหมด ของ API เหล่านั้น แต่โค้ดภายในเมธอดถูกนำออกไปแล้ว หากมี เมธอดที่มีการเข้าถึง การทดสอบจะแสดงข้อยกเว้น
ซึ่งจะทำให้ระบบสร้างการทดสอบในเครื่องเมื่ออ้างอิงชั้นเรียนใน Android
เช่น Context
ยิ่งไปกว่านั้น โมเดลนี้ยังช่วยให้คุณใช้การล้อเลียน
เฟรมเวิร์กของ Android ได้
การจำลองทรัพยากร Dependency ของ Android
ปัญหาทั่วไปคือเมื่อชั้นเรียนใช้ทรัพยากรสตริง คุณสามารถ
รับทรัพยากรสตริงโดยเรียกใช้เมธอด getString()
ใน Context
แต่การทดสอบในเครื่องจะใช้ Context
หรือวิธีการใดๆ ของการทดสอบไม่ได้ เนื่องจาก
อยู่ในเฟรมเวิร์กของ Android โดยหลักการแล้ว การเรียกไปยัง getString()
จะเป็น
ถูกย้ายออกจากชั้นเรียน แต่มักจะเป็นไปในทางปฏิบัติไม่ได้เสมอไป วิธีแก้ไขคือ
สร้างแบบจำลองหรือสตั๊นของ Context
ที่จะแสดงผลค่าเดียวกันเสมอเมื่อ
มีการเรียกใช้เมธอด getString()
มีไลบรารี Android ที่จำลองได้และเฟรมเวิร์กที่จำลอง เช่น Mockito หรือ MockK คุณสามารถตั้งโปรแกรม พฤติกรรมการลอกเลียนชั้นเรียน Android ในแบบทดสอบแต่ละหน่วย
วิธีเพิ่มออบเจ็กต์จำลองไปยังการทดสอบ 1 หน่วยในเครื่องโดยใช้ Mockito มีดังนี้ โมเดลการเขียนโปรแกรม:
- รวมทรัพยากร Dependency ของไลบรารี Mockito ไว้ในไฟล์
build.gradle
เป็น ตามที่อธิบายไว้ในหัวข้อตั้งค่าสภาพแวดล้อมการทดสอบของคุณ - ในช่วงต้นของคําจํากัดความของคลาสการทดสอบหน่วย ให้เพิ่มเมธอด
คำอธิบายประกอบ
@RunWith(MockitoJUnitRunner.class)
รายการ คำอธิบายประกอบนี้จะบอก ตัวดำเนินการทดสอบ Mockito เพื่อตรวจสอบว่าการใช้เฟรมเวิร์กของคุณถูกต้องและ ทำให้การเริ่มต้นออบเจ็กต์จำลองง่ายขึ้น - หากต้องการสร้างออบเจ็กต์จำลองสำหรับทรัพยากร Dependency ของ Android ให้เพิ่มคำอธิบายประกอบ
@Mock
ก่อนการประกาศช่อง - หากต้องการสร้างลักษณะการทำงานของทรัพยากร Dependency คุณสามารถระบุเงื่อนไขและ
จะแสดงผลค่าเมื่อตรงตามเงื่อนไขโดยใช้
when()
และthenReturn()
ตัวอย่างต่อไปนี้แสดงวิธีสร้างการทดสอบ 1 หน่วยที่ใช้การจำลอง
ออบเจ็กต์ Context
ใน Kotlin ที่สร้างด้วย Mockito-Kotlin สร้าง
import android.content.Context
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.junit.MockitoJUnitRunner
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
private const val FAKE_STRING = "HELLO WORLD"
@RunWith(MockitoJUnitRunner::class)
class MockedContextTest {
@Mock
private lateinit var mockContext: Context
@Test
fun readStringFromContext_LocalizedString() {
// Given a mocked Context injected into the object under test...
val mockContext = mock<Context> {
on { getString(R.string.name_label) } doReturn FAKE_STRING
}
val myObjectUnderTest = ClassUnderTest(mockContext)
// ...when the string is returned from the object under test...
val result: String = myObjectUnderTest.getName()
// ...then the result should be the expected one.
assertEquals(result, FAKE_STRING)
}
}
ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้เฟรมเวิร์กของ Mockito ได้ที่ Mockito API
การอ้างอิง และคลาส SharedPreferencesHelperTest
ใน
ตัวอย่างโค้ด หรือลองใช้ Android Testing Codelab
ข้อผิดพลาด: "เมธอด ... ไม่ได้มีการเลียนแบบ"
ไลบรารี Android ที่จำลองขึ้นมาจะให้การยกเว้น หากคุณพยายามเข้าถึง
ด้วยข้อความ Error: "Method ... not mocked
หากข้อยกเว้นที่ใส่ก่อให้เกิดปัญหาต่อการทดสอบของคุณ คุณสามารถเปลี่ยน
เพื่อให้เมธอดแสดงผลเป็น null หรือ 0 แทน ทั้งนี้ขึ้นอยู่กับ
ประเภทการแสดงผล ในการดำเนินการนี้ ให้เพิ่มการกำหนดค่าต่อไปนี้ในส่วน
ไฟล์ build.gradle
ระดับบนสุดใน Groovy:
android {
...
testOptions {
unitTests.returnDefaultValues = true
}