กำหนดเป้าหมายตัวอย่างแอป

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

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

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

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

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

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

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

ดูการสนทนาเพิ่มเติมเกี่ยวกับตำแหน่งต้นทางใน ตัวอย่างจากต้นทางถึงปลายทางสำหรับการทดสอบการใช้เครื่องมือด้วยตนเอง

ไฟล์ Manifest

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

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

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

เวอร์ชันล่าสุดของไฟล์ Manifest สำหรับตัวอย่างการเปลี่ยนแปลง Gerrit สามารถเข้าถึงได้ที่: https://android.googlesource.com/platform/frameworks/base/+/main/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 ของเฟรมเวิร์กแยกต่างหาก ดังนั้นจึงจำเป็นต้องมีรายการคลาสพาธเพิ่มเติมเมื่อเฟรมเวิร์กแอปพลิเคชันเรียกใช้แพ็คเกจการทดสอบ

android:targetPackage="com.android.shell"

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

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

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

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

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

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

เวอร์ชันล่าสุดของไฟล์กำหนดค่าสำหรับการเปลี่ยนแปลง 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>

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

<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>

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

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

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

การใช้ไลบรารี android-support-test เป็นตัวดำเนินการทดสอบช่วยให้สามารถนำคลาสการทดสอบสไตล์ 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 ระบุขนาดการทดสอบสำหรับคลาสการทดสอบทั้งหมด: วิธีการทดสอบทั้งหมดที่เพิ่มในคลาสการทดสอบนี้สืบทอดคำอธิบายประกอบขนาดการทดสอบนี้ การตั้งค่าคลาสการทดสอบก่อน การแยกการทดสอบหลัง และการแยกคลาสการทดสอบหลัง: คล้ายกับวิธี setUp และ tearDown ใน 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

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