เมื่อเริ่มการทดสอบการวัดคุม ระบบจะรีสตาร์ทแพ็กเกจเป้าหมาย
โดยมีการแทรกโค้ดการวัดคุมและเริ่มต้นการดำเนินการ ข้อยกเว้นอย่างหนึ่งคือแพ็กเกจเป้าหมายที่นี่ต้องไม่ใช่เฟรมเวิร์กแอปพลิเคชัน Android เอง เช่น แพ็กเกจ android เนื่องจากจะทำให้เกิดสถานการณ์ที่ขัดแย้งกันซึ่งเฟรมเวิร์ก Android จะต้องรีสตาร์ท ซึ่งเป็นสิ่งที่รองรับฟังก์ชันของระบบ รวมถึงการตรวจสอบเอง
ซึ่งหมายความว่าการทดสอบการวัดคุมไม่สามารถแทรกตัวเองลงในเฟรมเวิร์ก Android หรือที่เรียกว่าเซิร์ฟเวอร์ระบบเพื่อดำเนินการได้ ในการทดสอบเฟรมเวิร์ก Android
โค้ดทดสอบจะเรียกใช้ได้เฉพาะพื้นผิว API สาธารณะ หรือพื้นผิวที่เปิดเผยโดยใช้ Android Interface Definition Language
AIDL
ที่มีอยู่ในโครงสร้างแหล่งที่มาของแพลตฟอร์ม สําหรับการทดสอบหมวดหมู่นี้ การกำหนดเป้าหมายไปยังแพ็กเกจใดแพ็กเกจหนึ่งไม่มีความหมาย ดังนั้นจึงเป็นธรรมเนียมที่การวัดคุมดังกล่าว
จะต้องประกาศเพื่อกำหนดเป้าหมายแพ็กเกจแอปพลิเคชันทดสอบของตัวเอง ตามที่
กำหนดไว้ในแท็ก <manifest> ของ AndroidManifest.xml
ทั้งนี้แพ็กเกจแอปพลิเคชันทดสอบในหมวดหมู่นี้อาจมีลักษณะดังต่อไปนี้ด้วย
- กิจกรรมในชุดที่จำเป็นสำหรับการทดสอบ
- แชร์รหัสผู้ใช้กับระบบ
- ต้องลงนามด้วยคีย์แพลตฟอร์ม
- คอมไพล์กับแหล่งที่มาของเฟรมเวิร์กแทน SDK สาธารณะ
บางครั้งเราเรียกการทดสอบเครื่องมือในหมวดหมู่นี้ว่า การวัดผลด้วยตนเอง ตัวอย่างการทดสอบด้วยเครื่องมือของตัวเองใน แหล่งที่มาของแพลตฟอร์มมีดังนี้
ตัวอย่างที่กล่าวถึงที่นี่คือการเขียนการทดสอบการวัดคุมใหม่โดยตั้งค่าแพ็กเกจเป้าหมายที่แพ็กเกจแอปพลิเคชันทดสอบของตัวเอง คู่มือนี้ใช้การทดสอบต่อไปนี้ เพื่อเป็นตัวอย่าง
เราขอแนะนำให้คุณเรียกดูโค้ดก่อนเพื่อดูภาพรวมคร่าวๆ ก่อนดำเนินการต่อ
กำหนดตำแหน่งต้นทาง
โดยปกติแล้ว ทีมของคุณจะมีรูปแบบที่กำหนดไว้แล้วสำหรับตำแหน่งที่จะเช็คอินโค้ดและตำแหน่งที่จะเพิ่มการทดสอบ ทีมส่วนใหญ่เป็นเจ้าของที่เก็บ Git เดียว หรือแชร์ที่เก็บกับทีมอื่นๆ แต่มีไดเรกทอรีย่อยเฉพาะที่มีซอร์สโค้ดของคอมโพเนนต์
สมมติว่าตำแหน่งรากของแหล่งที่มาของคอมโพเนนต์อยู่ที่ <component source
root> คอมโพเนนต์ส่วนใหญ่จะมีโฟลเดอร์ src และ tests อยู่ภายใต้โฟลเดอร์นี้ และไฟล์เพิ่มเติมบางไฟล์ เช่น Android.mk (หรือแยกเป็นไฟล์ .mk เพิ่มเติม) ไฟล์ Manifest AndroidManifest.xml และไฟล์การกำหนดค่าการทดสอบ "AndroidTest.xml"
เนื่องจากคุณกำลังเพิ่มการทดสอบใหม่เอี่ยม คุณอาจต้องสร้างtestsไดเรกทอรีข้างคอมโพเนนต์src แล้วป้อนเนื้อหาลงในไดเรกทอรีนั้น
ในบางกรณี ทีมของคุณอาจมีโครงสร้างไดเรกทอรีเพิ่มเติมภายใต้ tests
เนื่องจากจำเป็นต้องแพ็กเกจชุดการทดสอบต่างๆ ลงใน APK แต่ละรายการ และในกรณีนี้ คุณจะต้องสร้างไดเรกทอรีย่อยใหม่ภายใต้ tests
ไม่ว่าโครงสร้างจะเป็นอย่างไร คุณจะต้องป้อนข้อมูลในไดเรกทอรี tests หรือ
ไดเรกทอรีย่อยที่สร้างขึ้นใหม่ด้วยไฟล์ที่คล้ายกับไฟล์ใน
ไดเรกทอรี instrumentation ในการเปลี่ยนแปลง Gerrit ตัวอย่าง รายละเอียดของแต่ละ
ไฟล์จะอธิบายในภายหลังในเอกสารนี้
ไฟล์ Manifest
เช่นเดียวกับโปรเจ็กต์แอป โมดูลการทดสอบการวัดคุมแต่ละโมดูลต้องมีไฟล์ Manifest ที่ชื่อ AndroidManifest.xml หากต้องการรวมไฟล์นี้โดยอัตโนมัติโดยใช้BUILD_PACKAGE core makefile ให้วางไฟล์นี้ไว้ข้างไฟล์Android.mkสำหรับโมดูลทดสอบ
หากไม่คุ้นเคยกับไฟล์ AndroidManifest.xml ให้อ่านภาพรวมของไฟล์ Manifest ของแอป
ตัวอย่างไฟล์ AndroidManifest.xml มีดังนี้
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:sharedUserId="android.uid.system"
package="android.test.example.helloworld" >
<application>
<uses-library android:name="android.test.runner"/>
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="android.test.example.helloworld"
android:label="Hello World Test"/>
</manifest>
ข้อสังเกตบางประการเกี่ยวกับไฟล์ Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.test.example.helloworld" >
แอตทริบิวต์ package คือชื่อแพ็กเกจแอปพลิเคชัน ซึ่งเป็นตัวระบุที่ไม่ซ้ำกัน
ที่เฟรมเวิร์กแอปพลิเคชัน Android ใช้เพื่อระบุแอปพลิเคชัน (หรือในบริบทนี้คือแอปพลิเคชันทดสอบของคุณ) ผู้ใช้แต่ละรายในระบบ
จะติดตั้งแอปพลิเคชันที่มีชื่อแพ็กเกจนั้นได้เพียงแอปเดียว
นอกจากนี้ แอตทริบิวต์ package นี้ยังเหมือนกับที่ ComponentName#getPackageName()
แสดงผล และยังเหมือนกับที่คุณใช้เพื่อโต้ตอบกับคำสั่งย่อย pm ต่างๆ โดยใช้ adb shell ด้วย
โปรดทราบว่าแม้ว่าโดยทั่วไปแล้วชื่อแพ็กเกจจะมีรูปแบบเดียวกับชื่อแพ็กเกจ Java แต่จริงๆ แล้วชื่อแพ็กเกจไม่ได้เกี่ยวข้องกับชื่อแพ็กเกจ Java มากนัก กล่าวอีกนัยหนึ่ง แพ็กเกจแอปพลิเคชัน (หรือการทดสอบ) อาจมีคลาสที่มีชื่อแพ็กเกจใดก็ได้ แต่ในทางกลับกัน คุณอาจเลือกใช้ความเรียบง่ายและมีชื่อแพ็กเกจ Java ระดับบนสุดในแอปพลิเคชันหรือการทดสอบที่เหมือนกับชื่อแพ็กเกจแอปพลิเคชัน
android:sharedUserId="android.uid.system"
ซึ่งเป็นการประกาศว่าในเวลาที่ติดตั้ง ระบบควรให้รหัสผู้ใช้เดียวกันกับไฟล์ APK นี้ นั่นคือข้อมูลระบุตัวตนของรันไทม์ เช่นเดียวกับแพลตฟอร์มหลัก โปรดทราบว่าการดำเนินการนี้จะขึ้นอยู่กับ APK ที่ลงนามด้วยใบรับรองเดียวกันกับแพลตฟอร์มหลัก
(ดู LOCAL_CERTIFICATE ในส่วนก่อนหน้า) แต่ทั้ง 2 อย่างนี้เป็นแนวคิดที่แตกต่างกัน
- สิทธิ์หรือ API บางรายการได้รับการป้องกันด้วยลายเซ็น ซึ่งต้องใช้ ใบรับรองการลงนามเดียวกัน
- สิทธิ์หรือ API บางรายการต้องใช้
systemข้อมูลประจำตัวผู้ใช้ของผู้โทร ซึ่งกำหนดให้แพ็กเกจที่เรียกใช้ต้องแชร์รหัสผู้ใช้กับsystemหากเป็น แพ็กเกจแยกต่างหากจากแพลตฟอร์มหลัก
<uses-library android:name="android.test.runner" />
การทดสอบเครื่องมือทั้งหมดต้องมีสิ่งนี้เนื่องจากคลาสที่เกี่ยวข้องจะ รวมอยู่ในไฟล์ไลบรารี JAR ของเฟรมเวิร์กแยกต่างหาก จึงต้องมีรายการ classpath เพิ่มเติมเมื่อเฟรมเวิร์กแอปพลิเคชันเรียกใช้แพ็กเกจการทดสอบ
android:targetPackage="android.test.example.helloworld"
คุณอาจสังเกตเห็นว่า targetPackage ที่นี่ประกาศเหมือนกับแอตทริบิวต์
packageที่ประกาศในแท็ก manifest ของไฟล์นี้ ดังที่กล่าวไว้ในพื้นฐานการทดสอบ โดยปกติแล้วการทดสอบการวัดคุมประเภทนี้มีไว้สำหรับทดสอบ API ของเฟรมเวิร์กการทดสอบ ดังนั้นจึงไม่ค่อยมีความหมายที่แอปพลิเคชันเป้าหมายเฉพาะจะมีแพ็กเกจอื่นนอกเหนือจากตัวแอปเอง
ไฟล์การกำหนดค่าอย่างง่าย
โมดูลทดสอบใหม่แต่ละโมดูลต้องมีไฟล์กำหนดค่าเพื่อสั่งให้ ระบบบิลด์ใช้ข้อมูลเมตาของโมดูล การอ้างอิงในเวลาคอมไพล์ และวิธีการแพ็กเกจ ในกรณีส่วนใหญ่ ตัวเลือกไฟล์ Blueprint ที่อิงตาม Soong จะเพียงพอ โปรดดูรายละเอียดที่การกำหนดค่าการทดสอบอย่างง่าย
ไฟล์การกำหนดค่าที่ซับซ้อน
สำหรับกรณีที่ซับซ้อนมากขึ้นเหล่านี้ คุณยังต้องเขียนไฟล์การกำหนดค่าการทดสอบสำหรับเครื่องมือทดสอบของ Android ซึ่งก็คือ Trade Federation ด้วย
การกำหนดค่าการทดสอบสามารถระบุตัวเลือกการตั้งค่าอุปกรณ์พิเศษและอาร์กิวเมนต์เริ่มต้น เพื่อส่งไปยังคลาสการทดสอบ ดูตัวอย่างได้ที่ /platform_testing/tests/example/instrumentation/AndroidTest.xml
เราได้รวมภาพรวมไว้ที่นี่เพื่อความสะดวก
<configuration description="Runs sample instrumentation test.">
<target_preparer class="com.android.tradefed.targetprep.TestFilePushSetup"/>
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
<option name="test-file-name" value="HelloWorldTests.apk"/>
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"/>
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"/>
<option name="test-suite-tag" value="apct"/>
<option name="test-tag" value="SampleInstrumentationTest"/>
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="android.test.example.helloworld"/>
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
</test>
</configuration>
ข้อสังเกตบางประการเกี่ยวกับไฟล์การกำหนดค่าการทดสอบ
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
<option name="test-file-name" value="HelloWorldTests.apk"/>
</target_preparer>
ซึ่งจะบอก Trade Federation ให้ติดตั้ง HelloWorldTests.apk ลงในอุปกรณ์เป้าหมาย โดยใช้ target_preparer ที่ระบุ นักพัฒนาแอปใน Trade Federation มีเครื่องมือเตรียมเป้าหมายมากมาย ซึ่งสามารถใช้เพื่อให้แน่ใจว่า ได้ตั้งค่าอุปกรณ์อย่างถูกต้องก่อนการทดสอบ
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="android.test.example.helloworld"/>
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
</test>
ซึ่งจะระบุคลาสการทดสอบของ Trade Federation ที่จะใช้ในการเรียกใช้การทดสอบและส่งผ่านในแพ็กเกจบนอุปกรณ์ที่จะเรียกใช้ รวมถึงเฟรมเวิร์กโปรแกรมเรียกใช้การทดสอบซึ่งในกรณีนี้คือ JUnit
ดูข้อมูลเพิ่มเติมได้ที่ กำหนดค่าโมดูลทดสอบ
ฟีเจอร์ JUnit4
การใช้ไลบรารี android-support-test เป็นตัวเรียกใช้การทดสอบจะช่วยให้ใช้คลาสการทดสอบรูปแบบ JUnit4 ใหม่ได้ และการเปลี่ยนแปลง Gerrit ตัวอย่างมีการใช้ฟีเจอร์พื้นฐานบางอย่าง ดูตัวอย่างได้ที่
/platform_testing/tests/example/instrumentation/src/android/test/example/helloworld/HelloWorldTest.java
แม้ว่ารูปแบบการทดสอบมักจะเฉพาะเจาะจงสำหรับทีมคอมโพเนนต์ แต่ก็มีรูปแบบการใช้งานบางอย่างที่ มีประโยชน์โดยทั่วไป
@RunWith(JUnit4.class)
public class HelloWorldTest {
ความแตกต่างที่สำคัญใน JUnit4 คือไม่จำเป็นต้องให้การทดสอบ สืบทอดจากคลาสการทดสอบฐานทั่วไปอีกต่อไป แต่คุณจะเขียนการทดสอบในคลาส Java ธรรมดาและใช้คำอธิบายประกอบเพื่อระบุการตั้งค่าและการจำกัดการทดสอบบางอย่างแทน ใน ตัวอย่างนี้ เรากำลังสั่งให้คลาสนี้ทำงานเป็นการทดสอบ JUnit4
@BeforeClass
public static void beforeClass() {
...
@AfterClass
public static void afterClass() {
...
@Before
public void before() {
...
@After
public void after() {
...
@Test
@SmallTest
public void testHelloWorld() {
...
JUnit4 ใช้หมายเหตุ @Before และ @After กับเมธอดเพื่อดำเนินการ
ตั้งค่าก่อนการทดสอบและล้างข้อมูลหลังการทดสอบ ในทำนองเดียวกัน JUnit4 จะใช้หมายเหตุประกอบ @BeforeClass และ
@AfterClass ในเมธอดเพื่อทำการตั้งค่าก่อน
เรียกใช้การทดสอบทั้งหมดในคลาสการทดสอบ และทำการล้างข้อมูลภายหลัง โปรดทราบว่าเมธอดการตั้งค่าและการล้างข้อมูลระดับคลาสต้องเป็นแบบคงที่ สำหรับเมธอดทดสอบ
ไม่เหมือนกับ JUnit เวอร์ชันก่อนๆ เมธอดทดสอบไม่จำเป็นต้องขึ้นต้นชื่อเมธอด
ด้วย test อีกต่อไป แต่เมธอดทดสอบแต่ละรายการต้องมีคำอธิบายประกอบด้วย @Test เช่นเคย เมธอดทดสอบต้องเป็นแบบสาธารณะ ไม่ประกาศค่าที่ส่งคืน ไม่รับพารามิเตอร์ และอาจส่งข้อยกเว้น
การเข้าถึงคลาสเครื่องมือ
แม้ว่าตัวอย่าง "Hello World" พื้นฐานจะไม่ได้ครอบคลุมถึงเรื่องนี้ แต่การทดสอบ Android มักจะต้องเข้าถึงอินสแตนซ์ Instrumentation ซึ่งเป็นอินเทอร์เฟซ API หลัก
ที่ให้สิทธิ์เข้าถึงบริบทของแอปพลิเคชัน, API การทดสอบที่เกี่ยวข้องกับวงจรของกิจกรรม
และอื่นๆ
เนื่องจากการทดสอบ JUnit4 ไม่จำเป็นต้องใช้คลาสพื้นฐานร่วมอีกต่อไป จึงไม่จำเป็นต้องรับอินสแตนซ์ Instrumentation ผ่าน
InstrumentationTestCase#getInstrumentation() อีกต่อไป แต่โปรแกรมเรียกใช้การทดสอบใหม่จะจัดการผ่าน InstrumentationRegistry
ซึ่งจะจัดเก็บการตั้งค่าตามบริบทและสภาพแวดล้อมที่สร้างขึ้นโดยเฟรมเวิร์กการวัดคุม
หากต้องการเข้าถึงอินสแตนซ์ของคลาส Instrumentation ให้เรียกใช้เมธอดแบบคงที่
getInstrumentation() ในคลาส InstrumentationRegistry ดังนี้
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation()
สร้างและทดสอบในเครื่อง
สำหรับกรณีการใช้งานที่พบบ่อยที่สุด ให้ใช้ Atest
สำหรับกรณีที่ซับซ้อนมากขึ้นซึ่งต้องมีการปรับแต่งที่หนักกว่า ให้ทำตามวิธีการติดตั้งเครื่องมือ