การกำหนดเป้าหมายตัวอย่างแอปพลิเคชัน

การทดสอบเครื่องมือประเภทนี้ไม่ต่างจากการทดสอบที่กำหนดเป้าหมายไปยังแอปพลิเคชัน Android ทั่วไป เป็นที่น่าสังเกตว่าแอปพลิเคชันทดสอบที่รวมเครื่องมือวัดนั้นต้องลงนามด้วยใบรับรองเดียวกันกับแอปพลิเคชันที่กำหนดเป้าหมาย

โปรดทราบว่าคู่มือนี้ถือว่าคุณมีความรู้ในเวิร์กโฟลว์แผนผังแหล่งที่มาของแพลตฟอร์มอยู่แล้ว หากไม่ใช่ โปรดดูที่ https://source.android.com/source/requirements ตัวอย่างที่กล่าวถึงในที่นี้คือการเขียนการทดสอบเครื่องมือวัดใหม่ด้วยแพ็คเกจเป้าหมายที่ตั้งไว้ที่แพ็คเกจแอปพลิเคชันทดสอบของตัวเอง หากคุณไม่คุ้นเคยกับแนวคิดนี้ โปรดอ่าน บทแนะนำการทดสอบแพลตฟอร์ม

คู่มือนี้ใช้การทดสอบติดตามเพื่อเป็นตัวอย่าง:

  • เฟรมเวิร์ก/ฐาน/แพ็คเกจ/เชลล์/การทดสอบ

ขอแนะนำให้เรียกดูโค้ดก่อนเพื่อให้ได้ข้อมูลคร่าวๆ ก่อนดำเนินการต่อ

การตัดสินใจเลือกตำแหน่งต้นทาง

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

ดูการอภิปรายเพิ่มเติมเกี่ยวกับตำแหน่งต้นทางในตัวอย่าง แบบ end-to-end สำหรับการทดสอบด้วยตนเอง

ไฟล์ Manifest

เช่นเดียวกับแอปพลิเคชันทั่วไป โมดูลการทดสอบเครื่องมือแต่ละโมดูลต้องการไฟล์รายการ หากคุณตั้งชื่อไฟล์เป็น AndroidManifest.xml และวางไว้ข้าง Android.mk สำหรับโมดูลการทดสอบของคุณ ไฟล์จะถูกรวมโดยอัตโนมัติโดย makefile หลักของ BUILD_PACKAGE

ก่อนดำเนินการต่อ ขอแนะนำอย่างยิ่งให้อ่าน ภาพรวมของรายการแอพ ก่อน

ข้อมูลนี้จะให้ภาพรวมขององค์ประกอบพื้นฐานของไฟล์ Manifest และฟังก์ชันการทำงาน

เวอร์ชันล่าสุดของไฟล์ Manifest สำหรับการเปลี่ยนแปลง gerrit ตัวอย่างสามารถเข้าถึงได้ที่: https://android.googlesource.com/platform/frameworks/base/+/master/packages/Shell/tests/AndroidManifest.xml

รวมสแนปชอตไว้ที่นี่เพื่อความสะดวก:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.shell.tests">

    <application>
        <uses-library android:name="android.test.runner" />

        <activity
            android:name="com.android.shell.ActionSendMultipleConsumerActivity"
            android:label="ActionSendMultipleConsumer"
            android:theme="@android:style/Theme.NoDisplay"
            android:noHistory="true"
            android:excludeFromRecents="true">
            <intent-filter>
                <action android:name="android.intent.action.SEND_MULTIPLE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="*/*" />
            </intent-filter>
        </activity>
    </application>

    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
        android:targetPackage="com.android.shell"
        android:label="Tests for Shell" />

</manifest>

ข้อสังเกตบางประการเกี่ยวกับไฟล์รายการ:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.shell.tests">

แอตทริบิวต์ของ package คือชื่อแพ็คเกจของแอปพลิเคชัน: นี่คือตัวระบุเฉพาะที่กรอบงานแอปพลิเคชัน Android ใช้เพื่อระบุแอปพลิเคชัน (หรือในบริบทนี้: แอปพลิเคชันทดสอบของคุณ) ผู้ใช้แต่ละรายในระบบสามารถติดตั้งแอปพลิเคชันที่มีชื่อแพ็กเกจนั้นได้เพียงแอปพลิเคชันเดียวเท่านั้น

เนื่องจากนี่คือแพ็กเกจแอปพลิเคชันทดสอบ ซึ่งเป็นอิสระจากแพ็กเกจแอปพลิเคชันที่อยู่ภายใต้การทดสอบ จึงต้องใช้ชื่อแพ็กเกจอื่น: หลักการทั่วไปประการหนึ่งคือการเพิ่มคำต่อท้าย .test

นอกจากนี้ แอตทริบิวต์ package นี้เหมือนกับที่ ComponentName#getPackageName() ส่งคืน และเหมือนกับที่คุณจะใช้ในการโต้ตอบกับคำสั่งย่อย pm ต่างๆ ผ่าน adb shell

โปรดทราบด้วยว่าแม้ว่าโดยทั่วไปชื่อแพ็กเกจจะมีลักษณะเดียวกับชื่อแพ็กเกจ Java แต่จริงๆ แล้วมีบางสิ่งที่ต้องทำ กล่าวอีกนัยหนึ่ง แพ็คเกจแอปพลิเคชัน (หรือการทดสอบ) ของคุณอาจมีคลาสที่มีชื่อแพ็คเกจใดก็ได้ แม้ว่าในทางกลับกัน คุณสามารถเลือกความเรียบง่ายและมีชื่อแพ็คเกจ Java ระดับบนสุดในแอปพลิเคชันของคุณ หรือการทดสอบเหมือนกับชื่อแพ็คเกจของแอปพลิเคชัน

<uses-library android:name="android.test.runner" />

สิ่งนี้จำเป็นสำหรับการทดสอบ Instrumentation ทั้งหมด เนื่องจากคลาสที่เกี่ยวข้องถูกจัดแพ็กเกจในไฟล์ไลบรารี jar เฟรมเวิร์กที่แยกจากกัน ดังนั้นต้องมีรายการ classpath เพิ่มเติมเมื่อแพ็กเกจการทดสอบถูกเรียกใช้โดยเฟรมเวิร์กแอ็พพลิเคชัน

android:targetPackage="com.android.shell"

ซึ่งจะกำหนดแพ็คเกจเป้าหมายของเครื่องมือวัดเป็น com.android.shell เมื่อเรียกใช้เครื่องมือวัดผ่านคำสั่ง am instrument เฟรมเวิร์กจะรีสตาร์ทกระบวนการ com.android.shell และแทรกโค้ดเครื่องมือวัดลงในกระบวนการสำหรับการดำเนินการทดสอบ นอกจากนี้ยังหมายความว่ารหัสทดสอบจะสามารถเข้าถึงอินสแตนซ์ของคลาสทั้งหมดที่ทำงานอยู่ในแอปพลิเคชันภายใต้การทดสอบ และอาจจัดการสถานะได้ขึ้นอยู่กับ hooks การทดสอบที่เปิดเผย

ไฟล์กำหนดค่าอย่างง่าย

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

ไฟล์การกำหนดค่าที่ซับซ้อน

สำหรับการทดสอบที่ซับซ้อนยิ่งขึ้น คุณต้องเขียนไฟล์การกำหนดค่าการทดสอบสำหรับสายรัดทดสอบของ Android สหพันธ์การค้า

การกำหนดค่าการทดสอบสามารถระบุตัวเลือกการตั้งค่าอุปกรณ์พิเศษและอาร์กิวเมนต์เริ่มต้นเพื่อจัดหาคลาสการทดสอบ

เวอร์ชันล่าสุดของไฟล์ปรับแต่งสำหรับการเปลี่ยนแปลง gerrit ตัวอย่างสามารถเข้าถึงได้ที่: frameworks/base/packages/Shell/tests/AndroidTest.xml

รวมสแนปชอตไว้ที่นี่เพื่อความสะดวก:

<configuration description="Runs Tests for Shell.">
    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
        <option name="test-file-name" value="ShellTests.apk" />
    </target_preparer>

    <option name="test-suite-tag" value="apct" />
    <option name="test-tag" value="ShellTests" />
    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
        <option name="package" value="com.android.shell.tests" />
        <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="ShellTests.apk"/>
</target_preparer>

สิ่งนี้บอกให้สหพันธ์การค้าติดตั้ง ShellTests.apk บนอุปกรณ์เป้าหมายโดยใช้ target_preparer ที่ระบุ มีผู้จัดเตรียมเป้าหมายจำนวนมากสำหรับนักพัฒนาในสหพันธ์การค้า และสามารถใช้สิ่งเหล่านี้เพื่อให้แน่ใจว่าอุปกรณ์ได้รับการตั้งค่าอย่างถูกต้องก่อนที่จะดำเนินการทดสอบ

<test class="com.android.tradefed.testtype.AndroidJUnitTest">
  <option name="package" value="com.android.shell.tests"/>
  <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
</test>

สิ่งนี้ระบุคลาสการทดสอบของสหพันธ์การค้าเพื่อใช้ในการดำเนินการทดสอบและผ่านในแพ็คเกจบนอุปกรณ์ที่จะดำเนินการและเฟรมเวิร์กของตัวดำเนินการทดสอบซึ่งก็คือ JUnit ในกรณีนี้

ดูข้อมูลเพิ่มเติมเกี่ยวกับ การกำหนดค่าโมดูลการทดสอบ . ที่นี่

คุณสมบัติของ JUnit4

การใช้ android-support-test library เป็นตัวดำเนินการทดสอบทำให้สามารถปรับใช้คลาสการทดสอบสไตล์ JUnit4 ใหม่และการเปลี่ยนแปลง gerrit ตัวอย่างมีการใช้งานคุณสมบัติพื้นฐานบางอย่าง

ซอร์สโค้ดล่าสุดสำหรับการเปลี่ยนแปลง gerrit ตัวอย่างสามารถเข้าถึงได้ที่: frameworks/base/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java

แม้ว่ารูปแบบการทดสอบมักจะเฉพาะเจาะจงสำหรับทีมส่วนประกอบ แต่ก็มีรูปแบบการใช้งานที่มีประโยชน์โดยทั่วไปอยู่บ้าง

@SmallTest
@RunWith(AndroidJUnit4.class)
public final class FeatureFactoryImplTest {

ความแตกต่างที่สำคัญใน JUnit4 คือการทดสอบไม่จำเป็นต้องสืบทอดจากคลาสการทดสอบพื้นฐานทั่วไปอีกต่อไป แต่คุณเขียนการทดสอบในคลาส Java ธรรมดาและใช้คำอธิบายประกอบเพื่อระบุการตั้งค่าการทดสอบและข้อจำกัดบางอย่าง ในตัวอย่างนี้ เรากำลังแนะนำว่าคลาสนี้ควรรันเป็นการทดสอบ Android JUnit4

คำอธิบายประกอบ @SmallTest ระบุขนาดการทดสอบสำหรับคลาสการทดสอบทั้งหมด: วิธีการทดสอบทั้งหมดที่เพิ่มลงในคลาสการทดสอบนี้จะสืบทอดหมายเหตุประกอบขนาดการทดสอบนี้ การตั้งค่าคลาสก่อนการทดสอบ การแยกส่วนหลังการทดสอบ และการแยกส่วนหลังการทดสอบ: คล้ายกับวิธี tearDown setUp JUnit4 คำอธิบายประกอบ Test ใช้สำหรับทำหมายเหตุประกอบการทดสอบจริง

    @Before
    public void setup() {
    ...
    @Test
    public void testGetProvider_shouldCacheProvider() {
    ...

คำอธิบายประกอบ @Before ใช้กับเมธอดโดย JUnit4 เพื่อดำเนินการตั้งค่าการทดสอบล่วงหน้า แม้ว่าจะไม่ได้ใช้ในตัวอย่างนี้ แต่ก็มี @After สำหรับการทดสอบหลังการทดสอบ ในทำนองเดียวกัน คำอธิบายประกอบ @BeforeClass และ @AfterClass สามารถใช้ได้กับเมธอดโดย JUnit4 เพื่อดำเนินการตั้งค่าก่อนดำเนินการทดสอบทั้งหมดในคลาสทดสอบ และแยกส่วนในภายหลัง โปรดทราบว่าการตั้งค่าขอบเขตคลาสและวิธีการรื้อถอนต้องเป็นแบบคงที่

สำหรับวิธีการทดสอบ ซึ่งแตกต่างจาก JUnit เวอร์ชันก่อนหน้า พวกเขาไม่จำเป็นต้องเริ่มชื่อเมธอดด้วย test อีกต่อไป แต่แต่ละรายการต้องใส่คำอธิบายประกอบด้วย @Test ตามปกติ วิธีการทดสอบต้องเป็นแบบสาธารณะ ประกาศว่าไม่มีค่าส่งคืน ไม่ใช้พารามิเตอร์ และอาจมีข้อยกเว้น

        Context context = InstrumentationRegistry.getTargetContext();

เนื่องจากการทดสอบ JUnit4 ไม่ต้องการคลาสพื้นฐานทั่วไปอีกต่อไป จึงไม่จำเป็นต้องรับอินสแตนซ์ Context ผ่าน getContext() หรือ getTargetContext() ผ่านเมธอดคลาสพื้นฐานอีกต่อไป แทน นักวิ่งทดสอบใหม่จัดการพวกเขาผ่าน InstrumentationRegistry ซึ่งการตั้งค่าตามบริบทและสิ่งแวดล้อมที่สร้างขึ้นโดยเฟรมเวิร์กเครื่องมือวัดจะถูกเก็บไว้ คุณยังสามารถโทรผ่านชั้นเรียนนี้:

  • getInstrumentation() : อินสแตนซ์ของคลาส Instrumentation
  • getArguments() : อาร์กิวเมนต์บรรทัดคำสั่งส่งผ่านไปยัง am instrument ผ่าน -e <key> <value>

สร้างและทดสอบในเครื่อง

สำหรับกรณีการใช้งานทั่วไป ให้ใช้ Atest

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