เมื่อเริ่มการทดสอบเครื่องมือวัด แพ็คเกจเป้าหมายจะเริ่มต้นใหม่โดยป้อนรหัสเครื่องมือวัดและเริ่มดำเนินการ ข้อยกเว้นประการหนึ่งคือ แพ็กเกจเป้าหมายที่นี่ไม่สามารถเป็นเฟรมเวิร์กแอปพลิเคชัน Android ได้ เช่น แพ็กเกจ android
เพราะการทำเช่นนั้นจะนำไปสู่สถานการณ์ที่ขัดแย้งกันซึ่งจะต้องรีสตาร์ทเฟรมเวิร์ก Android ซึ่งเป็นสิ่งที่รองรับฟังก์ชันของระบบ รวมถึงเครื่องมือวัด ตัวเอง.
ซึ่งหมายความว่าการทดสอบเครื่องมือวัดไม่สามารถแทรกตัวเองลงในเฟรมเวิร์กของ Android หรือที่เรียกว่าเซิร์ฟเวอร์ระบบเพื่อดำเนินการได้ ในการทดสอบเฟรมเวิร์ก Android โค้ดทดสอบสามารถเรียกใช้ได้เฉพาะพื้นผิว API สาธารณะหรือที่เปิดเผยผ่าน Android Interface Definition Language AIDL ที่มีอยู่ในแผนผังแหล่งที่มาของแพลตฟอร์ม สำหรับการทดสอบประเภทนี้ การกำหนดเป้าหมายแพ็คเกจใดโดยเฉพาะไม่มีความหมาย ดังนั้นจึงเป็นธรรมเนียมที่จะต้องประกาศเครื่องมือวัดดังกล่าวเพื่อกำหนดเป้าหมายแพ็คเกจแอปพลิเคชันทดสอบของตัวเอง ตามที่กำหนดไว้ในแท็ก <manifest>
ของ AndroidManifest.xml
ขึ้นอยู่กับข้อกำหนด แพ็คเกจแอปพลิเคชันทดสอบในหมวดหมู่นี้อาจ:
- กิจกรรมบันเดิลที่จำเป็นสำหรับการทดสอบ
- แบ่งปัน ID ผู้ใช้กับระบบ
- ลงนามด้วยคีย์แพลตฟอร์ม
- ถูกคอมไพล์เทียบกับซอร์สเฟรมเวิร์กแทนที่จะเป็น SDK สาธารณะ
การทดสอบเครื่องมือประเภทนี้บางครั้งเรียกว่าการวัดด้วยตนเอง ต่อไปนี้คือตัวอย่างบางส่วนของการทดสอบด้วยตนเองในแหล่งที่มาของแพลตฟอร์ม:
ตัวอย่างที่กล่าวถึงในที่นี้คือการเขียนการทดสอบเครื่องมือวัดใหม่ด้วยแพ็คเกจเป้าหมายที่ตั้งไว้ที่แพ็คเกจแอปพลิเคชันการทดสอบของตัวเอง คู่มือนี้ใช้การทดสอบต่อไปนี้เป็นตัวอย่าง:
ขอแนะนำให้เรียกดูโค้ดก่อนเพื่อให้ได้ข้อมูลคร่าวๆ ก่อนดำเนินการต่อ
การตัดสินใจเลือกตำแหน่งต้นทาง
โดยทั่วไปแล้ว ทีมของคุณจะมีรูปแบบสถานที่สำหรับตรวจสอบโค้ดอยู่แล้ว และสถานที่สำหรับเพิ่มการทดสอบ ทีมส่วนใหญ่เป็นเจ้าของที่เก็บ git เดียวหรือใช้ร่วมกับทีมอื่น แต่มีไดเร็กทอรีย่อยเฉพาะที่มีซอร์สโค้ดของคอมโพเนนต์
สมมติว่าตำแหน่งรูทสำหรับแหล่งที่มาของคอมโพเนนต์ของคุณอยู่ที่ <component source root>
คอมโพเนนต์ส่วนใหญ่มีโฟลเดอร์ src
และ tests
อยู่ข้างใต้ และไฟล์เพิ่มเติมบางไฟล์ เช่น Android.mk
(หรือแบ่งเป็นไฟล์ .mk
เพิ่มเติม) ไฟล์รายการ AndroidManifest.xml
และไฟล์การกำหนดค่าการทดสอบ 'AndroidTest.xml'
เนื่องจากคุณกำลังเพิ่มการทดสอบใหม่ คุณอาจต้องสร้างไดเร็กทอรี tests
ถัดจากส่วนประกอบ src
ของคุณและเติมข้อมูลลงในเนื้อหา
ในบางกรณี ทีมของคุณอาจมีโครงสร้างไดเร็กทอรีเพิ่มเติมภายใต้ tests
เนื่องจากจำเป็นต้องจัดแพ็กเกจชุดการทดสอบต่างๆ ลงใน apk แต่ละรายการ และในกรณีนี้ คุณจะต้องสร้างไดเรกทอรีย่อยใหม่ภายใต้ tests
โดยไม่คำนึงถึงโครงสร้าง คุณจะต้องเติมไดเร็กทอรี tests
หรือไดเร็กทอรีย่อยที่สร้างขึ้นใหม่ด้วยไฟล์ที่คล้ายกับที่อยู่ในไดเร็กทอรี instrumentation
ในการเปลี่ยนแปลง gerrit ตัวอย่าง ส่วนด้านล่างจะอธิบายรายละเอียดเพิ่มเติมของแต่ละไฟล์
ไฟล์ Manifest
เช่นเดียวกับแอปพลิเคชันทั่วไป โมดูลการทดสอบเครื่องมือแต่ละโมดูลต้องการไฟล์รายการ หากคุณตั้งชื่อไฟล์เป็น AndroidManifest.xml
และวางไว้ข้าง Android.mk
สำหรับโมดูลการทดสอบของคุณ ไฟล์จะถูกรวมโดยอัตโนมัติโดย makefile หลักของ BUILD_PACKAGE
ก่อนดำเนินการต่อ ขอแนะนำอย่างยิ่งให้อ่าน ภาพรวมของรายการแอพ ก่อน
ข้อมูลนี้จะให้ภาพรวมขององค์ประกอบพื้นฐานของไฟล์ Manifest และฟังก์ชันการทำงาน ดูตัวอย่างได้ที่ platform_testing/tests/example/instrumentation/AndroidManifest.xml
รวมสแนปชอตไว้ที่นี่เพื่อความสะดวก:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.test.example.helloworld" >
<application/>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="android.test.example.helloworld"
android:label="Hello World Test"/>
</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 ระดับบนสุดในแอปพลิเคชันของคุณ หรือการทดสอบเหมือนกับชื่อแพ็คเกจของแอปพลิเคชัน
android:sharedUserId="android.uid.system"
สิ่งนี้ประกาศว่า ณ เวลาติดตั้ง apk นี้ควรได้รับ ID ผู้ใช้เดียวกัน กล่าวคือ เอกลักษณ์รันไทม์ เป็นแพลตฟอร์มหลัก โปรดทราบว่าสิ่งนี้ขึ้นอยู่กับ apk ที่ลงนามด้วยใบรับรองเดียวกันกับแพลตฟอร์มหลัก (ดู LOCAL_CERTIFICATE
ในส่วนด้านบน) แต่แนวคิดเหล่านี้ต่างกัน:
- สิทธิ์หรือ API บางอย่างได้รับการป้องกันด้วยลายเซ็น ซึ่งต้องใช้ใบรับรองการลงนามเดียวกัน
- สิทธิ์หรือ API บางอย่างต้องการข้อมูลประจำตัวผู้ใช้
system
ของผู้โทร ซึ่งต้องใช้แพ็คเกจการโทรเพื่อแชร์ ID ผู้ใช้กับsystem
หากเป็นแพ็คเกจแยกต่างหากจากแพลตฟอร์มหลักเอง
<uses-library android:name="android.test.runner" />
สิ่งนี้จำเป็นสำหรับการทดสอบ Instrumentation ทั้งหมด เนื่องจากคลาสที่เกี่ยวข้องถูกจัดแพ็กเกจในไฟล์ไลบรารี jar เฟรมเวิร์กที่แยกจากกัน ดังนั้นต้องมีรายการ classpath เพิ่มเติมเมื่อแพ็กเกจการทดสอบถูกเรียกใช้โดยเฟรมเวิร์กแอ็พพลิเคชัน
android:targetPackage="android.test.example.helloworld"
คุณอาจสังเกตเห็นว่า targetPackage
ที่นี่ถูกประกาศเหมือนกับแอตทริบิวต์ package
ที่ manifest
ในแท็กรายการของไฟล์นี้ ตามที่กล่าวไว้ใน พื้นฐานการทดสอบ การ ทดสอบเครื่องมือประเภทนี้โดยทั่วไปมีไว้สำหรับการทดสอบเฟรมเวิร์ก API ดังนั้นจึงไม่มีความหมายมากนักสำหรับพวกเขาที่จะมีแพ็คเกจแอปพลิเคชันเป้าหมายเฉพาะ อย่างอื่นนอกเหนือจากตัวเอง
ไฟล์กำหนดค่าอย่างง่าย
โมดูลทดสอบใหม่แต่ละโมดูลต้องมีไฟล์คอนฟิกูเรชันเพื่อกำหนดทิศทางของระบบบิลด์ด้วยข้อมูลเมตาของโมดูล การขึ้นต่อกันเวลาคอมไพล์ และคำแนะนำในการบรรจุภัณฑ์ ในกรณีส่วนใหญ่ ตัวเลือกไฟล์พิมพ์เขียวแบบ Soong ก็เพียงพอแล้ว สำหรับรายละเอียด โปรดดูที่ Simple Test Configuration
ไฟล์การกำหนดค่าที่ซับซ้อน
สำหรับกรณีที่ซับซ้อนกว่านี้ คุณต้องเขียนไฟล์การกำหนดค่าการทดสอบสำหรับสายรัดทดสอบของ Android สหพันธ์การค้า
การกำหนดค่าการทดสอบสามารถระบุตัวเลือกการตั้งค่าอุปกรณ์พิเศษและอาร์กิวเมนต์เริ่มต้นเพื่อจัดหาคลาสการทดสอบ ดูตัวอย่างได้ที่ /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>
สิ่งนี้บอกให้สหพันธ์การค้าติดตั้ง HelloWorldTests.apk บนอุปกรณ์เป้าหมายโดยใช้ target_preparer ที่ระบุ มีผู้จัดเตรียมเป้าหมายจำนวนมากสำหรับนักพัฒนาในสหพันธ์การค้า และสามารถใช้สิ่งเหล่านี้เพื่อให้แน่ใจว่าอุปกรณ์ได้รับการตั้งค่าอย่างถูกต้องก่อนที่จะดำเนินการทดสอบ
<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>
สิ่งนี้ระบุคลาสการทดสอบของสหพันธ์การค้าเพื่อใช้ในการดำเนินการทดสอบและผ่านในแพ็คเกจบนอุปกรณ์ที่จะดำเนินการและเฟรมเวิร์กของตัวดำเนินการทดสอบซึ่งก็คือ JUnit ในกรณีนี้
สำหรับข้อมูลเพิ่มเติม โปรดดูที่ การกำหนดค่าโมดูลการทดสอบ
คุณสมบัติของ JUnit4
การใช้ android-support-test
library เป็นตัวดำเนินการทดสอบทำให้สามารถปรับใช้คลาสการทดสอบรูปแบบ 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() {
...
คำอธิบายประกอบ @Before
และ @After
ใช้กับเมธอดโดย JUnit4 เพื่อดำเนินการตั้งค่าก่อนการทดสอบและหลังการทดสอบการแยกย่อย ในทำนองเดียวกัน คำอธิบายประกอบ @BeforeClass
และ @AfterClass
ใช้ในเมธอดโดย JUnit4 เพื่อดำเนินการตั้งค่าก่อนดำเนินการทดสอบทั้งหมดในคลาสทดสอบ และแยกส่วนในภายหลัง โปรดทราบว่าการตั้งค่าขอบเขตคลาสและวิธีการรื้อถอนต้องเป็นแบบคงที่ สำหรับวิธีการทดสอบ ซึ่งแตกต่างจาก JUnit เวอร์ชันก่อนหน้า พวกเขาไม่จำเป็นต้องเริ่มชื่อเมธอดด้วย test
อีกต่อไป แต่แต่ละรายการต้องใส่คำอธิบายประกอบด้วย @Test
ตามปกติ วิธีการทดสอบต้องเป็นแบบสาธารณะ ประกาศว่าไม่มีค่าส่งคืน ไม่ใช้พารามิเตอร์ และอาจมีข้อยกเว้น
สำคัญ : วิธีการทดสอบนั้นจะมีคำอธิบายประกอบ @Test
และโปรดทราบว่าสำหรับการทดสอบที่จะดำเนินการผ่าน APCT จะต้องใส่คำอธิบายประกอบด้วยขนาดการทดสอบ: ตัวอย่างวิธีการใส่คำอธิบายประกอบ testHelloWorld
เป็น @SmallTest
อาจใช้คำอธิบายประกอบที่ขอบเขตเมธอดหรือขอบเขตคลาส
การเข้าถึง instrumentation
แม้ว่าจะไม่ครอบคลุมในตัวอย่าง Hello World พื้นฐาน แต่การทดสอบ Android นั้นมักต้องการการเข้าถึง Instrumentation
สแตนซ์ของเครื่องมือวัด: นี่คืออินเทอร์เฟซ API หลักที่ให้การเข้าถึงบริบทของแอปพลิเคชัน API การทดสอบที่เกี่ยวข้องกับวงจรกิจกรรม และอื่นๆ
เนื่องจากการทดสอบ JUnit4 ไม่ต้องการคลาสพื้นฐานทั่วไปอีกต่อไป จึงไม่จำเป็นต้องรับอินสแตนซ์ของ Instrumentation
ผ่าน InstrumentationTestCase#getInstrumentation()
อีกต่อไป แต่ตัวดำเนินการทดสอบใหม่จะจัดการผ่าน InstrumentationRegistry
ซึ่งการตั้งค่าบริบทและสภาพแวดล้อมที่สร้างโดยเฟรมเวิร์กเครื่องมือวัดถูกเก็บไว้
ในการเข้าถึงอินสแตนซ์ของคลาส Instrumentation
เพียงเรียกเมธอดคงที่ getInstrumentation()
บนคลาส InstrumentationRegistry
:
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation()
สร้างและทดสอบในเครื่อง
สำหรับกรณีการใช้งานทั่วไป ให้ใช้ Atest
สำหรับกรณีที่ซับซ้อนมากขึ้นซึ่งต้องการการปรับแต่งที่หนักกว่า ให้ทำตาม คำแนะนำเครื่องมือวัด