ตัวอย่างการทดสอบด้วยตนเอง

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

สำหรับกรณีที่ซับซ้อนมากขึ้นซึ่งต้องการการปรับแต่งที่หนักกว่า ให้ทำตาม คำแนะนำเครื่องมือวัด