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

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

android:sharedUserId="android.uid.system"

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

  • สิทธิ์บางรายการหรือ 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 เพียงพอ โปรดดูรายละเอียดที่หัวข้อ การกำหนดค่าการทดสอบแบบง่าย

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

สำหรับกรณีที่ซับซ้อนมากขึ้นเหล่านี้ คุณจะต้องเขียนไฟล์การกําหนดค่าการทดสอบสําหรับTrade Federation ซึ่งเป็นชุดทดสอบของ 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>

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

การเข้าถึงคลาสเครื่องมือวัด

แม้ว่าจะไม่ได้กล่าวถึงในตัวอย่าง Hello World พื้นฐาน แต่การทดสอบ Android มักกำหนดให้ต้องเข้าถึงอินสแตนซ์ Instrumentation ซึ่งเป็นอินเทอร์เฟซ API หลักที่ให้สิทธิ์เข้าถึงบริบทแอปพลิเคชัน, API การทดสอบที่เกี่ยวข้องกับวงจรของกิจกรรม และอื่นๆ

เนื่องจากการทดสอบ JUnit4 ไม่จำเป็นต้องใช้คลาสพื้นฐานทั่วไปอีกต่อไป จำเป็นต้องรับอินสแตนซ์ Instrumentation ผ่านทาง InstrumentationTestCase#getInstrumentation() เป็นตัวทดสอบใหม่แทน จัดการผ่าน InstrumentationRegistry โดยการตั้งค่าตามบริบทและสภาพแวดล้อมที่สร้างโดยเฟรมเวิร์กการใช้เครื่องมือ ที่จัดเก็บไว้

หากต้องการเข้าถึงอินสแตนซ์ของคลาส Instrumentation เพียงเรียกเมธอดแบบคงที่ getInstrumentation() ใน InstrumentationRegistry ชั้นเรียน:

Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation()

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

สำหรับกรณีการใช้งานที่พบบ่อยที่สุด ล่าสุด

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