เขียนการทดสอบอัตโนมัติด้วย UI Automator

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

เฟรมเวิร์กการทดสอบ UI Automator เป็น API ที่อิงตามการใช้เครื่องมือและ ด้วยตัวดำเนินการทดสอบ AndroidJUnitRunner เหมาะสำหรับการเขียน การทดสอบอัตโนมัติแบบกล่องทึบ ซึ่งโค้ดการทดสอบไม่ได้อาศัยข้อมูลภายใน รายละเอียดการใช้งานของแอปเป้าหมาย

ฟีเจอร์หลักของเฟรมเวิร์กการทดสอบ UI Automator มีดังนี้

  • API สำหรับเรียกข้อมูลสถานะและดำเนินการในเป้าหมาย อุปกรณ์ โปรดดูข้อมูลเพิ่มเติมที่การเข้าถึงสถานะของอุปกรณ์
  • API ที่รองรับการทดสอบ UI ข้ามแอป สำหรับข้อมูลเพิ่มเติม โปรดดู UI Automator API

การเข้าถึงสถานะอุปกรณ์

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

  1. เปลี่ยนการหมุนอุปกรณ์
  2. กดปุ่มฮาร์ดแวร์ เช่น "เพิ่มระดับเสียง"
  3. กดปุ่มย้อนกลับ หน้าแรก หรือเมนู
  4. เปิดหน้าต่างแจ้งเตือน
  5. ถ่ายภาพหน้าจอของหน้าต่างปัจจุบัน

ตัวอย่างเช่น หากต้องการจำลองการกดปุ่มหน้าแรก ให้เรียกใช้ UiDevice.pressHome()

API Automator สำหรับ UI

UI Automator API ช่วยให้คุณเขียนการทดสอบที่มีประสิทธิภาพได้โดยไม่ต้องรู้ เกี่ยวกับรายละเอียดการใช้แอปที่คุณกําหนดเป้าหมาย คุณสามารถใช้ API เหล่านี้เพื่อบันทึกและจัดการคอมโพเนนต์ UI ในหลายๆ แอป

  • UiObject2: แสดงองค์ประกอบ UI ที่มองเห็นได้ในอุปกรณ์
  • BySelector: ระบุเกณฑ์ในการจับคู่องค์ประกอบ UI
  • By: สร้าง BySelector ให้กระชับ
  • Configurator: ให้คุณตั้งค่าพารามิเตอร์ที่สำคัญสำหรับการเรียกใช้การทดสอบ UI อัตโนมัติของ UI

ตัวอย่างเช่น โค้ดต่อไปนี้แสดงวิธีเขียนสคริปต์ทดสอบที่ เปิดแอป Gmail ในอุปกรณ์

Kotlin

device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
device.pressHome()

val gmail: UiObject2 = device.findObject(By.text("Gmail"))
// Perform a click and wait until the app is opened.
val opened: Boolean = gmail.clickAndWait(Until.newWindow(), 3000)
assertThat(opened).isTrue()

Java

device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
device.pressHome();

UiObject2 gmail = device.findObject(By.text("Gmail"));
// Perform a click and wait until the app is opened.
Boolean opened = gmail.clickAndWait(Until.newWindow(), 3000);
assertTrue(opened);

ตั้งค่าโปรแกรมสร้าง UI อัตโนมัติ

ก่อนสร้างการทดสอบ UI ด้วยโปรแกรมสร้าง UI Automator อย่าลืมกำหนดค่าการทดสอบ ตำแหน่งซอร์สโค้ดและทรัพยากร Dependency ของโปรเจ็กต์ ตามที่อธิบายไว้ในตั้งค่าโปรเจ็กต์ สำหรับ AndroidX Test

ในไฟล์ build.gradle ของโมดูลแอป Android คุณต้องตั้งค่าทรัพยากร Dependency การอ้างอิงไลบรารี Automator ของ UI:

Kotlin

dependencies {
  ...
  androidTestImplementation('androidx.test.uiautomator:uiautomator:2.3.0-alpha03')
}

ดึงดูด

dependencies {
  ...
  androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.3.0-alpha03'
}

หากต้องการเพิ่มประสิทธิภาพการทดสอบ UI Automator คุณควรตรวจสอบแอปเป้าหมายก่อน คอมโพเนนต์ UI และตรวจสอบว่าเข้าถึงได้ เคล็ดลับการเพิ่มประสิทธิภาพเหล่านี้ ซึ่งอธิบายไว้ใน 2 ส่วนถัดไป

ตรวจสอบ UI ในอุปกรณ์

ก่อนที่จะออกแบบการทดสอบ ให้ตรวจสอบคอมโพเนนต์ UI ที่ปรากฏใน อุปกรณ์ เพื่อให้การทดสอบ UI Automator เข้าถึงคอมโพเนนต์เหล่านี้ได้ ตรวจสอบว่าคอมโพเนนต์เหล่านี้มีป้ายกำกับข้อความที่มองเห็นได้ android:contentDescription ค่า หรือทั้ง 2 ค่า

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

วิธีเปิดเครื่องมือ uiautomatorviewer

  1. เปิดแอปเป้าหมายในอุปกรณ์จริง
  2. เชื่อมต่ออุปกรณ์กับเครื่องพัฒนาซอฟต์แวร์
  3. เปิดหน้าต่างเทอร์มินัลและไปยังไดเรกทอรี <android-sdk>/tools/
  4. เรียกใช้เครื่องมือด้วยคำสั่งนี้
 $ uiautomatorviewer

วิธีดูพร็อพเพอร์ตี้ UI ของแอปพลิเคชัน

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

หากต้องการเรียนรู้เกี่ยวกับประเภทคอมโพเนนต์ UI ทั่วไปที่ Android มีให้ โปรดดูที่ผู้ใช้ อินเทอร์เฟซ

ตรวจสอบว่ากิจกรรมเข้าถึงได้

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

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

  1. สร้างชั้นเรียนที่เป็นรูปธรรมที่ขยาย ExploreByTouchHelper
  2. เชื่อมโยงอินสแตนซ์ของชั้นเรียนใหม่กับองค์ประกอบ UI ที่กำหนดเองที่เจาะจงด้วยวิธี ที่เรียกใช้ setAccessibilityDelegate()

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

สร้างคลาสการทดสอบ UI Automator

คลาสการทดสอบ UI Automator ของคุณควรเขียนในลักษณะเดียวกับการทดสอบ JUnit 4 ดูข้อมูลเพิ่มเติมเกี่ยวกับการสร้างชั้นเรียนทดสอบ JUnit 4 และการใช้ JUnit 4 การยืนยันและคำอธิบายประกอบ โปรดดูสร้างคลาสการทดสอบหน่วยการวัด

เพิ่มคำอธิบายประกอบ @RunWith(AndroidJUnit4.class) ในช่วงต้นของการทดสอบ คำจำกัดความของคลาส คุณจะต้องระบุคลาส AndroidJUnitRunner ซึ่งมีให้ใน AndroidX Test ในฐานะตัวดำเนินการทดสอบเริ่มต้นของคุณ มีการอธิบายขั้นตอนนี้ ดูรายละเอียดเพิ่มเติมในเรียกใช้การทดสอบ UI Automator ในอุปกรณ์หรือโปรแกรมจำลอง

ใช้โมเดลการเขียนโปรแกรมต่อไปนี้ในชั้นเรียนทดสอบ UI Automator

  1. รับออบเจ็กต์ UiDevice เพื่อเข้าถึงอุปกรณ์ที่คุณต้องการทดสอบด้วยการโทร เมธอด getInstance() และส่งออบเจ็กต์ Instrumentation เป็น อาร์กิวเมนต์
  2. รับออบเจ็กต์ UiObject2 เพื่อเข้าถึงคอมโพเนนต์ UI ที่แสดงใน (เช่น มุมมองปัจจุบันในเบื้องหน้า) โดยการเรียกใช้ เมธอด findObject()
  3. จำลองการโต้ตอบของผู้ใช้ที่เฉพาะเจาะจงเพื่อเรียกใช้ในคอมโพเนนต์ UI นั้นโดย เรียกเมธอด UiObject2 เช่น เรียก scrollUntil() เพื่อเลื่อน และ setText() เพื่อแก้ไขช่องข้อความ คุณสามารถเรียกใช้ API ได้ในขั้นตอนที่ 2 และ 3 ซ้ำๆ ตามความจำเป็นเพื่อทดสอบการโต้ตอบ ที่ซับซ้อนยิ่งขึ้นของผู้ใช้ ซึ่งเกี่ยวข้องกับ คอมโพเนนต์ UI หลายรายการหรือลำดับการดำเนินการของผู้ใช้
  4. ตรวจสอบว่า UI แสดงสถานะหรือลักษณะการทำงานที่ต้องการหลังจากที่ผู้ใช้เหล่านี้ ที่มีการโต้ตอบกัน

เราอธิบายขั้นตอนเหล่านี้โดยละเอียดยิ่งขึ้นในส่วนด้านล่าง

เข้าถึงคอมโพเนนต์ UI

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

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

ข้อมูลโค้ดต่อไปนี้แสดงวิธีที่การทดสอบอาจได้รับอินสแตนซ์ UiDevice และจำลองการกดปุ่มหน้าแรก:

Kotlin

import org.junit.Before
import androidx.test.runner.AndroidJUnit4
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
...

private const val BASIC_SAMPLE_PACKAGE = "com.example.android.testing.uiautomator.BasicSample"
private const val LAUNCH_TIMEOUT = 5000L
private const val STRING_TO_BE_TYPED = "UiAutomator"

@RunWith(AndroidJUnit4::class)
@SdkSuppress(minSdkVersion = 18)
class ChangeTextBehaviorTest2 {

private lateinit var device: UiDevice

@Before
fun startMainActivityFromHomeScreen() {
  // Initialize UiDevice instance
  device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())

  // Start from the home screen
  device.pressHome()

  // Wait for launcher
  val launcherPackage: String = device.launcherPackageName
  assertThat(launcherPackage, notNullValue())
  device.wait(
    Until.hasObject(By.pkg(launcherPackage).depth(0)),
    LAUNCH_TIMEOUT
  )

  // Launch the app
  val context = ApplicationProvider.getApplicationContextC<ontext(>)
  val intent = context.packageManager.getLaunchIntentForPackage(
  BASIC_SAMPLE_PACKAGE).apply {
    // Clear out any previous instances
    addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
  }
  context.startActivity(intent)

  // Wait for the app to appear
  device.wait(
    Until.hasObject(By.pkg(BASIC_SAMPLE_PACKAGE).depth(0)),
    LAUNCH_TIMEOUT
    )
  }
}

Java

import org.junit.Before;
import androidx.test.runner.AndroidJUnit4;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.Until;
...

@RunWith(AndroidJUnit4.class)
@SdkSuppress(minSdkVersion = 18)
public class ChangeTextBehaviorTest {

  private static final String BASIC_SAMPLE_PACKAGE
  = "com.example.android.testing.uiautomator.BasicSample";
  private static final int LAUNCH_TIMEOUT = 5000;
  private static final String STRING_TO_BE_TYPED = "UiAutomator";
  private UiDevice device;

  @Before
  public void startMainActivityFromHomeScreen() {
    // Initialize UiDevice instance
    device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());

    // Start from the home screen
    device.pressHome();

    // Wait for launcher
    final String launcherPackage = device.getLauncherPackageName();
    assertThat(launcherPackage, notNullValue());
    device.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)),
    LAUNCH_TIMEOUT);

    // Launch the app
    Context context = ApplicationProvider.getApplicationContext();
    final Intent intent = context.getPackageManager()
    .getLaunchIntentForPackage(BASIC_SAMPLE_PACKAGE);
    // Clear out any previous instances
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
    context.startActivity(intent);

    // Wait for the app to appear
    device.wait(Until.hasObject(By.pkg(BASIC_SAMPLE_PACKAGE).depth(0)),
    LAUNCH_TIMEOUT);
    }
}

ในตัวอย่างนี้ คำสั่ง @SdkSuppress(minSdkVersion = 18) จะช่วยให้ การทดสอบนั้นจะใช้ได้เฉพาะกับอุปกรณ์ที่ใช้ Android 4.3 (API ระดับ 18) ขึ้นไป ตามที่เฟรมเวิร์ก UI Automator กำหนดไว้

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

ข้อมูลโค้ดต่อไปนี้แสดงวิธีที่การทดสอบอาจสร้าง UiObject2 อินสแตนซ์ที่แสดงปุ่ม "ยกเลิก" และปุ่ม "ตกลง" ในแอป

Kotlin

val okButton: UiObject2 = device.findObject(
    By.text("OK").clazz("android.widget.Button")
)

// Simulate a user-click on the OK button, if found.
if (okButton != null) {
    okButton.click()
}

Java

UiObject2 okButton = device.findObject(
    By.text("OK").clazz("android.widget.Button")
);

// Simulate a user-click on the OK button, if found.
if (okButton != null) {
    okButton.click();
}

ระบุตัวเลือก

หากต้องการเข้าถึงคอมโพเนนต์ UI ที่เจาะจงในแอป ให้ใช้ By เพื่อสร้างอินสแตนซ์ BySelector BySelector แสดงคำค้นหาสำหรับองค์ประกอบที่เฉพาะเจาะจงใน UI ที่แสดง

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

คุณใช้เมธอด hasChild() หรือ hasDescendant() เพื่อซ้อนได้ อินสแตนซ์ BySelector หลายรายการ ตัวอย่างเช่น ตัวอย่างโค้ดต่อไปนี้แสดง วิธีที่การทดสอบอาจระบุการค้นหาเพื่อหา ListView แรกที่ มีองค์ประกอบ UI ย่อยที่มีพร็อพเพอร์ตี้ข้อความ

Kotlin

val listView: UiObject2 = device.findObject(
    By.clazz("android.widget.ListView")
        .hasChild(
            By.text("Apps")
        )
)

Java

UiObject2 listView = device.findObject(
    By.clazz("android.widget.ListView")
        .hasChild(
            By.text("Apps")
        )
);

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

ดำเนินการ

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

  • click() : คลิกกึ่งกลางของขอบเขตที่มองเห็นได้ขององค์ประกอบ UI
  • drag() : ลากวัตถุนี้ไปยังพิกัดที่กำหนดเอง
  • setText() : ตั้งค่าข้อความในช่องที่แก้ไขได้ หลังจากล้าง เนื้อหาก็ได้ ในทางกลับกัน เมธอด clear() จะล้างข้อความที่มีอยู่ ในช่องที่แก้ไขได้
  • swipe() : ปัดนิ้วไปยังทิศทางที่ระบุ
  • scrollUntil(): ดำเนินการเลื่อนไปยังทิศทางที่ระบุ จนกว่าจะพอใจ Condition หรือ EventCondition

เฟรมเวิร์กการทดสอบ UI Automator ช่วยให้คุณสามารถส่ง Intent หรือการเปิดตัว Activity ที่ไม่ต้องใช้คำสั่ง Shell โดยการรับบริบท ผ่าน getContext()

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

Kotlin

fun setUp() {
...

  // Launch a simple calculator app
  val context = getInstrumentation().context
  val intent = context.packageManager.getLaunchIntentForPackage(CALC_PACKAGE).apply {
    addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
  }
  // Clear out any previous instances
  context.startActivity(intent)
  device.wait(Until.hasObject(By.pkg(CALC_PACKAGE).depth(0)), TIMEOUT)
}

Java

public void setUp() {
...

  // Launch a simple calculator app
  Context context = getInstrumentation().getContext();
  Intent intent = context.getPackageManager()
  .getLaunchIntentForPackage(CALC_PACKAGE);
  intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);

  // Clear out any previous instances
  context.startActivity(intent);
  device.wait(Until.hasObject(By.pkg(CALC_PACKAGE).depth(0)), TIMEOUT);
}

ยืนยันผลลัพธ์

InstrumentationTestCase จะขยาย TestCase เพื่อให้คุณใช้ เมธอด JUnit Assert มาตรฐานเพื่อทดสอบคอมโพเนนต์ UI นั้นในการส่งกลับแอป ผลลัพธ์ที่คาดหวัง

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

Kotlin

private const val CALC_PACKAGE = "com.myexample.calc"

fun testTwoPlusThreeEqualsFive() {
  // Enter an equation: 2 + 3 = ?
  device.findObject(By.res(CALC_PACKAGE, "two")).click()
  device.findObject(By.res(CALC_PACKAGE, "plus")).click()
  device.findObject(By.res(CALC_PACKAGE, "three")).click()
  device.findObject(By.res(CALC_PACKAGE, "equals")).click()

  // Verify the result = 5
  val result: UiObject2 = device.findObject(By.res(CALC_PACKAGE, "result"))
  assertEquals("5", result.text)
}

Java

private static final String CALC_PACKAGE = "com.myexample.calc";

public void testTwoPlusThreeEqualsFive() {
  // Enter an equation: 2 + 3 = ?
  device.findObject(By.res(CALC_PACKAGE, "two")).click();
  device.findObject(By.res(CALC_PACKAGE, "plus")).click();
  device.findObject(By.res(CALC_PACKAGE, "three")).click();
  device.findObject(By.res(CALC_PACKAGE, "equals")).click();

  // Verify the result = 5
  UiObject2 result = device.findObject(By.res(CALC_PACKAGE, "result"));
  assertEquals("5", result.getText());
}

เรียกใช้การทดสอบ Automator สำหรับ UI ในอุปกรณ์หรือโปรแกรมจำลอง

คุณสามารถทำการทดสอบอัตโนมัติของ UI ได้จาก Android Studio หรือจาก บรรทัดคำสั่ง อย่าลืมระบุ AndroidJUnitRunner เป็นค่าเริ่มต้น ตัวดำเนินการการวัดคุมในโปรเจ็กต์ของคุณ

ตัวอย่างเพิ่มเติม

โต้ตอบกับ UI ของระบบ

UI Automator สามารถโต้ตอบกับทุกอย่างบนหน้าจอ รวมถึงระบบ องค์ประกอบนอกแอปของคุณ ดังที่ปรากฏในข้อมูลโค้ดต่อไปนี้

Kotlin

// Opens the System Settings.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
device.executeShellCommand("am start -a android.settings.SETTINGS")

Java

// Opens the System Settings.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
device.executeShellCommand("am start -a android.settings.SETTINGS");

Kotlin

// Opens the notification shade.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
device.openNotification()

Java

// Opens the notification shade.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
device.openNotification();

Kotlin

// Opens the Quick Settings shade.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
device.openQuickSettings()

Java

// Opens the Quick Settings shade.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
device.openQuickSettings();

Kotlin

// Get the system clock.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
UiObject2 clock = device.findObject(By.res("com.android.systemui:id/clock"))
print(clock.getText())

Java

// Get the system clock.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
UiObject2 clock = device.findObject(By.res("com.android.systemui:id/clock"));
print(clock.getText());

รอการเปลี่ยน

วันที่ ปิดสิ่งรบกวน
รูปที่ 1 UI Automator จะปิดโหมดห้ามรบกวนใน อุปกรณ์ทดสอบ

การเปลี่ยนหน้าจออาจใช้เวลานาน และการคาดคะเนระยะเวลาก็ไม่น่าเชื่อถือ ดังนั้น คุณควรให้ UI Automator รอหลังจากดำเนินการ เครื่องมือสร้าง UI อัตโนมัติ มีวิธีดำเนินการหลายวิธี ดังนี้

ข้อมูลโค้ดต่อไปนี้แสดงวิธีใช้ UI Automator เพื่อปิด Do Not โหมดห้ามรบกวนในการตั้งค่าระบบที่ใช้เมธอด performActionAndWait() ที่ รอการเปลี่ยน:

Kotlin

@Test
@SdkSuppress(minSdkVersion = 21)
@Throws(Exception::class)
fun turnOffDoNotDisturb() {
    device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
    device.performActionAndWait({
        try {
            device.executeShellCommand("am start -a android.settings.SETTINGS")
        } catch (e: IOException) {
            throw RuntimeException(e)
        }
    }, Until.newWindow(), 1000)
    // Check system settings has been opened.
    Assert.assertTrue(device.hasObject(By.pkg("com.android.settings")))

    // Scroll the settings to the top and find Notifications button
    var scrollableObj: UiObject2 = device.findObject(By.scrollable(true))
    scrollableObj.scrollUntil(Direction.UP, Until.scrollFinished(Direction.UP))
    val notificationsButton = scrollableObj.findObject(By.text("Notifications"))

    // Click the Notifications button and wait until a new window is opened.
    device.performActionAndWait({ notificationsButton.click() }, Until.newWindow(), 1000)
    scrollableObj = device.findObject(By.scrollable(true))
    // Scroll down until it finds a Do Not Disturb button.
    val doNotDisturb = scrollableObj.scrollUntil(
        Direction.DOWN,
        Until.findObject(By.textContains("Do Not Disturb"))
    )
    device.performActionAndWait({ doNotDisturb.click() }, Until.newWindow(), 1000)
    // Turn off the Do Not Disturb.
    val turnOnDoNotDisturb = device.findObject(By.text("Turn on now"))
    turnOnDoNotDisturb?.click()
    Assert.assertTrue(device.wait(Until.hasObject(By.text("Turn off now")), 1000))
}

Java

@Test
@SdkSuppress(minSdkVersion = 21)
public void turnOffDoNotDisturb() throws Exception{
    device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
    device.performActionAndWait(() - >{
        try {
            device.executeShellCommand("am start -a android.settings.SETTINGS");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }, Until.newWindow(), 1000);
    // Check system settings has been opened.
    assertTrue(device.hasObject(By.pkg("com.android.settings")));

    // Scroll the settings to the top and find Notifications button
    UiObject2 scrollableObj = device.findObject(By.scrollable(true));
    scrollableObj.scrollUntil(Direction.UP, Until.scrollFinished(Direction.UP));
    UiObject2 notificationsButton = scrollableObj.findObject(By.text("Notifications"));

    // Click the Notifications button and wait until a new window is opened.
    device.performActionAndWait(() - >notificationsButton.click(), Until.newWindow(), 1000);
    scrollableObj = device.findObject(By.scrollable(true));
    // Scroll down until it finds a Do Not Disturb button.
    UiObject2 doNotDisturb = scrollableObj.scrollUntil(Direction.DOWN,
            Until.findObject(By.textContains("Do Not Disturb")));
    device.performActionAndWait(()- >doNotDisturb.click(), Until.newWindow(), 1000);
    // Turn off the Do Not Disturb.
    UiObject2 turnOnDoNotDisturb = device.findObject(By.text("Turn on now"));
    if(turnOnDoNotDisturb != null) {
        turnOnDoNotDisturb.click();
    }
    assertTrue(device.wait(Until.hasObject(By.text("Turn off now")), 1000));
}

แหล่งข้อมูลเพิ่มเติม

หากต้องการข้อมูลเพิ่มเติมเกี่ยวกับการใช้ UI Automator ในการทดสอบ Android โปรดดู แหล่งข้อมูลต่อไปนี้

เอกสารอ้างอิง:

ตัวอย่าง

  • BasicSample: ตัวอย่างตัวสร้างอัตโนมัติของ UI พื้นฐาน