UI Automator เป็นเฟรมเวิร์กการทดสอบ UI ที่เหมาะสําหรับการทดสอบ UI เชิงฟังก์ชันข้ามแอป
ในแอปของระบบและแอปที่ติดตั้ง UI Automator API ช่วยให้คุณโต้ตอบกับองค์ประกอบที่มองเห็นได้ในอุปกรณ์ ไม่ว่าActivity
ใดจะอยู่ในโฟกัสก็ตาม จึงช่วยให้คุณดำเนินการต่างๆ ได้ เช่น เปิดเมนูการตั้งค่าหรือตัวเรียกใช้แอปในอุปกรณ์ทดสอบ การทดสอบสามารถค้นหาคอมโพเนนต์ UI ได้โดยใช้ตัวอธิบายที่สะดวก เช่น ข้อความที่แสดงในคอมโพเนนต์นั้นหรือคำอธิบายเนื้อหาของคอมโพเนนต์
เฟรมเวิร์กการทดสอบ UI Automator เป็น API ที่อิงตามการวัดประสิทธิภาพและทำงานร่วมกับโปรแกรมเรียกใช้การทดสอบ AndroidJUnitRunner
เหมาะอย่างยิ่งสำหรับการเขียนการทดสอบอัตโนมัติแบบกล่องดำ ซึ่งโค้ดทดสอบไม่ได้ขึ้นอยู่กับรายละเอียดการใช้งานภายในของแอปเป้าหมาย
ฟีเจอร์หลักของเฟรมเวิร์กการทดสอบ UI Automator มีดังนี้
- API สำหรับดึงข้อมูลสถานะและดำเนินการกับอุปกรณ์เป้าหมาย โปรดดูข้อมูลเพิ่มเติมที่หัวข้อการเข้าถึงสถานะของอุปกรณ์
- API ที่รองรับการทดสอบ UI ข้ามแอป ดูข้อมูลเพิ่มเติมได้ที่ UI Automator APIs
การเข้าถึงสถานะอุปกรณ์
เฟรมเวิร์กการทดสอบ UI Automator มีคลาส UiDevice
สำหรับเข้าถึงและดำเนินการในอุปกรณ์ที่แอปเป้าหมายทำงานอยู่ คุณสามารถ
เรียกใช้เมธอดเพื่อเข้าถึงพร็อพเพอร์ตี้ของอุปกรณ์ เช่น การวางแนวปัจจุบันหรือ
ขนาดการแสดงผล นอกจากนี้ คลาส UiDevice
ยังช่วยให้คุณทำสิ่งต่อไปนี้ได้ด้วย
- เปลี่ยนการหมุนอุปกรณ์
- กดปุ่มฮาร์ดแวร์ เช่น "เพิ่มระดับเสียง"
- กดปุ่มย้อนกลับ หน้าแรก หรือเมนู
- เปิดแผงการแจ้งเตือน
- ถ่ายภาพหน้าจอของหน้าต่างปัจจุบัน
เช่น หากต้องการจำลองการกดปุ่มหน้าแรก ให้เรียกใช้เมธอด UiDevice.pressHome()
UI Automator API
API ของ UI Automator ช่วยให้คุณเขียนการทดสอบที่เชื่อถือได้โดยไม่ต้องทราบรายละเอียดการติดตั้งใช้งานของแอปที่คุณกำหนดเป้าหมาย คุณใช้ API เหล่านี้เพื่อบันทึกและจัดการคอมโพเนนต์ UI ในแอปต่างๆ ได้
UiObject2
: แสดงองค์ประกอบ UI ที่มองเห็นได้บนอุปกรณ์BySelector
: ระบุเกณฑ์สำหรับการจับคู่องค์ประกอบ UIBy
: สร้างBySelector
ในลักษณะที่กระชับConfigurator
: ช่วยให้คุณตั้งค่าพารามิเตอร์หลักสำหรับการเรียกใช้การทดสอบ UI Automator
ตัวอย่างเช่น โค้ดต่อไปนี้แสดงวิธีเขียนสคริปต์ทดสอบที่ เปิดแอป 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 Automator
ก่อนสร้างการทดสอบ UI ด้วย UI Automator ให้ตรวจสอบว่าได้กำหนดค่าตำแหน่งซอร์สโค้ดของการทดสอบและการอ้างอิงโปรเจ็กต์แล้วตามที่อธิบายไว้ในตั้งค่าโปรเจ็กต์ สำหรับการทดสอบ AndroidX
ในbuild.gradle
ของโมดูลแอป Android คุณต้องตั้งค่าการอ้างอิงทรัพยากร Dependency
ไปยังไลบรารี UI Automator ดังนี้
Kotlin
dependencies {
...
androidTestImplementation("androidx.test.uiautomator:uiautomator:2.3.0")
}
Groovy
dependencies {
...
androidTestImplementation "androidx.test.uiautomator:uiautomator:2.3.0"
}
หากต้องการเพิ่มประสิทธิภาพการทดสอบ UI Automator คุณควรตรวจสอบคอมโพเนนต์ UI ของแอปเป้าหมายก่อน และตรวจสอบว่าคอมโพเนนต์เหล่านั้นเข้าถึงได้ เคล็ดลับการเพิ่มประสิทธิภาพเหล่านี้ อธิบายไว้ใน 2 ส่วนถัดไป
ตรวจสอบ UI บนอุปกรณ์
ก่อนออกแบบการทดสอบ ให้ตรวจสอบคอมโพเนนต์ UI ที่มองเห็นได้ใน
อุปกรณ์ หากต้องการให้การทดสอบ UI Automator เข้าถึงคอมโพเนนต์เหล่านี้ได้
ให้ตรวจสอบว่าคอมโพเนนต์เหล่านี้มีป้ายกำกับข้อความที่มองเห็นได้
ค่า android:contentDescription
หรือทั้ง 2 อย่าง
uiautomatorviewer
เครื่องมือนี้มีอินเทอร์เฟซแบบภาพที่สะดวกในการตรวจสอบ
ลำดับชั้นของเลย์เอาต์และดูพร็อพเพอร์ตี้ของคอมโพเนนต์ UI ที่มองเห็นได้
ในเบื้องหน้าของอุปกรณ์ ข้อมูลนี้ช่วยให้คุณสร้างการทดสอบที่ละเอียดยิ่งขึ้นได้โดยใช้ UI Automator เช่น คุณสามารถสร้างตัวเลือก UI
ที่ตรงกับพร็อพเพอร์ตี้ที่มองเห็นได้เฉพาะ
วิธีเปิดใช้เครื่องมือ uiautomatorviewer
- เปิดแอปเป้าหมายในอุปกรณ์จริง
- เชื่อมต่ออุปกรณ์กับเครื่องที่ใช้พัฒนา
- เปิดหน้าต่างเทอร์มินัลแล้วไปที่ไดเรกทอรี
<android-sdk>/tools/
- เรียกใช้เครื่องมือด้วยคำสั่งนี้
$ uiautomatorviewer
วิธีดูพร็อพเพอร์ตี้ UI สำหรับแอปพลิเคชัน
- ใน
uiautomatorviewer
อินเทอร์เฟซ ให้คลิกปุ่มภาพหน้าจอของอุปกรณ์ - วางเมาส์เหนือภาพรวมในแผงด้านซ้ายเพื่อดูคอมโพเนนต์ UI
ที่
uiautomatorviewer
เครื่องมือระบุ คุณสมบัติจะแสดงในแผงด้านขวาล่าง และลำดับชั้นของเลย์เอาต์ในแผงด้านขวาบน - (ไม่บังคับ) คลิกปุ่มสลับโหนด NAF เพื่อดูคอมโพเนนต์ UI ที่ UI Automator เข้าถึงไม่ได้ อาจมีข้อมูลจำกัดสำหรับคอมโพเนนต์เหล่านี้ เท่านั้น
ดูข้อมูลเกี่ยวกับประเภทคอมโพเนนต์ UI ทั่วไปที่ Android มีให้ได้ที่ส่วนติดต่อผู้ใช้
ตรวจสอบว่ากิจกรรมของคุณเข้าถึงได้
เฟรมเวิร์กการทดสอบ UI Automator ทำงานได้ดีกว่าในแอปที่ใช้ฟีเจอร์การช่วยเหลือพิเศษของ Android
เมื่อใช้องค์ประกอบ UI ประเภท View
หรือ
คลาสย่อยของ View
จาก SDK คุณไม่จำเป็นต้องใช้การรองรับการช่วยเหลือพิเศษ
เนื่องจากคลาสเหล่านี้ได้ดำเนินการให้คุณแล้ว
อย่างไรก็ตาม แอปบางแอปใช้องค์ประกอบ UI ที่กำหนดเองเพื่อมอบประสบการณ์การใช้งานที่ดียิ่งขึ้น
องค์ประกอบดังกล่าวจะไม่รองรับการช่วยเหลือพิเศษโดยอัตโนมัติ หากแอปของคุณมีอินสแตนซ์ของคลาสย่อยของ View
ที่ไม่ได้มาจาก SDK โปรดตรวจสอบว่าคุณได้เพิ่มฟีเจอร์การช่วยเหลือพิเศษลงในองค์ประกอบเหล่านี้โดยทำตามขั้นตอนต่อไปนี้
- สร้างคลาสที่เป็นรูปธรรมซึ่งขยาย ExploreByTouchHelper
- เชื่อมโยงอินสแตนซ์ของคลาสใหม่กับองค์ประกอบ UI ที่กำหนดเองโดยเฉพาะโดย เรียกใช้ setAccessibilityDelegate()
ดูคำแนะนำเพิ่มเติมเกี่ยวกับการเพิ่มฟีเจอร์การช่วยเหลือพิเศษลงในองค์ประกอบมุมมองที่กำหนดเองได้ที่การสร้างมุมมองที่กำหนดเองที่เข้าถึงได้ง่าย ดูข้อมูลเพิ่มเติมเกี่ยวกับ แนวทางปฏิบัติแนะนำทั่วไปสำหรับการช่วยเหลือพิเศษใน Android ได้ที่การทำให้แอปเข้าถึงได้มากขึ้น
สร้างคลาสการทดสอบ UI Automator
คุณควรเขียนคลาสการทดสอบ UI Automator ในลักษณะเดียวกับคลาสการทดสอบ JUnit 4 ดูข้อมูลเพิ่มเติมเกี่ยวกับการสร้างคลาสทดสอบ JUnit 4 และการใช้ข้อความยืนยันและคำอธิบายประกอบ JUnit 4 ได้ที่สร้างคลาสทดสอบ 1 หน่วยแบบมีเครื่องควบคุม
เพิ่มคำอธิบายประกอบ @RunWith(AndroidJUnit4.class) ไว้ที่จุดเริ่มต้นของคำจำกัดความคลาสทดสอบ นอกจากนี้ คุณยังต้องระบุคลาส AndroidJUnitRunner ที่ระบุไว้ใน AndroidX Test เป็นตัวดำเนินการทดสอบเริ่มต้นด้วย ขั้นตอนนี้อธิบายไว้ อย่างละเอียดในเรียกใช้การทดสอบ UI Automator บนอุปกรณ์หรือโปรแกรมจำลอง
ใช้รูปแบบการเขียนโปรแกรมต่อไปนี้ในคลาสการทดสอบ UI Automator
- รับออบเจ็กต์
UiDevice
เพื่อเข้าถึงอุปกรณ์ที่ต้องการทดสอบโดยการเรียกเมธอด getInstance() และส่งออบเจ็กต์ Instrumentation เป็นอาร์กิวเมนต์ - รับออบเจ็กต์
UiObject2
เพื่อเข้าถึงคอมโพเนนต์ UI ที่แสดงบน อุปกรณ์ (เช่น มุมมองปัจจุบันในเบื้องหน้า) โดยเรียกใช้เมธอด findObject() - จำลองการโต้ตอบของผู้ใช้ที่เฉพาะเจาะจงเพื่อดำเนินการในคอมโพเนนต์ UI นั้นโดย
การเรียกใช้
UiObject2
เมธอด เช่น เรียกใช้ scrollUntil() เพื่อเลื่อน และ setText() เพื่อแก้ไขช่องข้อความ คุณเรียกใช้ API ในขั้นตอนที่ 2 และ 3 ซ้ำๆ ได้ตามต้องการเพื่อทดสอบการโต้ตอบของผู้ใช้ที่ซับซ้อนมากขึ้น ซึ่งเกี่ยวข้องกับ คอมโพเนนต์ UI หลายรายการหรือลําดับการกระทําของผู้ใช้ - ตรวจสอบว่า UI แสดงสถานะหรือลักษณะการทํางานที่คาดไว้หลังจากดําเนินการโต้ตอบของผู้ใช้เหล่านี้
ซึ่งจะมีการอธิบายขั้นตอนเหล่านี้โดยละเอียดยิ่งขึ้นในส่วนด้านล่าง
เข้าถึงคอมโพเนนต์ UI
ออบเจ็กต์ UiDevice
เป็นวิธีหลักในการเข้าถึงและจัดการสถานะของอุปกรณ์
ในการทดสอบ คุณสามารถเรียกใช้เมธอด UiDevice
เพื่อตรวจสอบสถานะของพร็อพเพอร์ตี้ต่างๆ เช่น การวางแนวปัจจุบันหรือขนาดการแสดงผล
การทดสอบสามารถใช้ออบเจ็กต์ UiDevice
เพื่อดำเนินการระดับอุปกรณ์
เช่น บังคับให้อุปกรณ์หมุนในทิศทางที่เฉพาะเจาะจง กดปุ่มฮาร์ดแวร์ D-pad
และกดปุ่มหน้าแรกและปุ่มเมนู
แนวทางปฏิบัติที่ดีคือการเริ่มการทดสอบจากหน้าจอหลักของอุปกรณ์ จาก หน้าจอหลัก (หรือตำแหน่งเริ่มต้นอื่นๆ ที่คุณเลือกไว้ในอุปกรณ์) คุณสามารถเรียกใช้เมธอดที่ API ของ UI Automator มีให้เพื่อเลือกและโต้ตอบ กับองค์ประกอบ 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.getApplicationContext<Context>()
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 Automator จะค้นหาการแสดงผลปัจจุบันเพื่อหา
การจับคู่ทุกครั้งที่การทดสอบใช้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()
โดยตั้งค่าอาร์กิวเมนต์เป็นจริง
ดำเนินการ
เมื่อการทดสอบได้รับออบเจ็กต์ UiObject2
แล้ว คุณจะเรียกใช้เมธอดในคลาส UiObject2
เพื่อโต้ตอบกับผู้ใช้ในคอมโพเนนต์ UI ที่แสดงโดยออบเจ็กต์นั้นได้ คุณระบุการดำเนินการดังกล่าวได้ดังนี้
click()
: คลิกตรงกลางขอบเขตที่มองเห็นได้ขององค์ประกอบ UIdrag()
: ลากออบเจ็กต์นี้ไปยังพิกัดที่ต้องการsetText()
: ตั้งค่าข้อความในช่องที่แก้ไขได้หลังจากล้างเนื้อหาของช่อง ในทางกลับกัน วิธีclear()
จะล้างข้อความที่มีอยู่ใน ช่องที่แก้ไขได้swipe()
: ดำเนินการปัดไปยังทิศทางที่ระบุscrollUntil()
: ดำเนินการเลื่อนไปยังทิศทางที่ระบุ จนกว่าจะตรงตามเงื่อนไขCondition
หรือEventCondition
เฟรมเวิร์กการทดสอบ UI Automator ช่วยให้คุณส่ง Intent หรือเปิดใช้Activity ได้โดยไม่ต้องใช้คำสั่ง Shell เพียงรับออบเจ็กต์ Context ผ่าน 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 คุณจึงใช้เมธอด Assert ของ JUnit มาตรฐานเพื่อทดสอบว่าคอมโพเนนต์ 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());
}
เรียกใช้การทดสอบ UI Automator บนอุปกรณ์หรือโปรแกรมจำลอง
คุณเรียกใช้การทดสอบ UI Automator ได้จาก 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());
รอการเปลี่ยนฉาก

การเปลี่ยนหน้าจออาจใช้เวลาและคาดการณ์ระยะเวลาไม่ได้ ดังนั้น คุณควรให้ UI Automator รอหลังจากดำเนินการ UI Automator มีหลายวิธีในการดำเนินการนี้ ดังนี้
UiDevice.performActionAndWait(Runnable action, EventCondition<U> condition, long timeout)
: เช่น หากต้องการคลิกปุ่มและรอจนกว่าหน้าต่างใหม่จะปรากฏขึ้น ให้โทรหาdevice.performActionAndWait(() -> button.click(), Until.newWindow(), timeout)
UiDevice.wait(Condition<Object, U> condition, long timeout)
: เช่น หากต้องการรอจนกว่าจะมีUiObject2
ในอุปกรณ์ ให้เรียกใช้device.wait(Until.hasObject(By.text("my_text")), timeout);
UiObject2.wait(@NonNull Condition<Object, U> condition, long timeout)
: เช่น หากต้องการรอจนกว่าจะมีการเลือกช่องทำเครื่องหมาย ให้เรียกใช้checkbox.wait(Until.checked(true), timeout);
UiObject2.clickAndWait(@NonNull EventCondition<U> condition, long timeout)
: เช่น หากต้องการคลิกปุ่มและรอจนกว่าหน้าต่างใหม่จะปรากฏขึ้น ให้โทรหาbutton.clickAndWait(Until.newWindow(), timeout);
UiObject2.scrollUntil(@NonNull Direction direction, @NonNull Condition<Object, U> condition)
: เช่น หากต้องการเลื่อนลงจนกว่าจะเห็นออบเจ็กต์ใหม่ ให้เรียกใช้object.scrollUntil(Direction.DOWN, Until.hasObject(By.text('new_obj')));
UiObject2.scrollUntil(@NonNull Direction direction, @NonNull EventCondition<U> condition)
: เช่น หากต้องการเลื่อนลงไปที่ด้านล่าง ให้เรียกใช้object.scrollUntil(Direction.DOWN, Until.scrollFinished(Direction.DOWN));
ข้อมูลโค้ดต่อไปนี้แสดงวิธีใช้ UI Automator เพื่อปิดโหมดห้ามรบกวนในการตั้งค่าระบบโดยใช้เมธอด 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 Automator พื้นฐาน