การทดสอบ Macrobenchmark แตกต่างจากการทดสอบ UI ของ Android ส่วนใหญ่ตรงที่กระบวนการที่แยกจากกัน จากตัวแอปเอง การดำเนินการนี้เป็นสิ่งจำเป็นสำหรับการเปิดใช้สิ่งต่างๆ เช่น การหยุด กระบวนการของแอปและการคอมไพล์จากไบต์โค้ด DEX ไปยังโค้ดของเครื่อง
คุณกำหนดสถานะของแอปได้โดยใช้ไลบรารี UIAutomator หรือ
ที่สามารถควบคุมแอปเป้าหมายจากกระบวนการทดสอบได้
คุณไม่สามารถใช้ Espresso หรือ ActivityScenario
สำหรับ
การเปรียบเทียบมาโคร เนื่องจากลูกค้าคาดหวังว่าจะทำงานในกระบวนการที่แชร์กับแอป
ตัวอย่างต่อไปนี้จะค้นหา RecyclerView
โดยใช้รหัสทรัพยากรและ
เลื่อนลงหลายครั้ง
@Test
fun scrollList() {
benchmarkRule.measureRepeated(
// ...
setupBlock = {
// Before starting to measure, navigate to the UI to be measured
val intent = Intent("$packageName.RECYCLER_VIEW_ACTIVITY")
startActivityAndWait(intent)
}
) {
val recycler = device.findObject(By.res(packageName, "recycler"))
// Set gesture margin to avoid triggering gesture navigation
// with input events from automation.
recycler.setGestureMargin(device.displayWidth / 5)
// Scroll down several times
repeat(3) { recycler.fling(Direction.DOWN) }
}
}
@Test
public void scrollList() {
benchmarkRule.measureRepeated(
// ...
/* setupBlock */ scope -> {
// Before measuring, navigate to the UI to be measured.
val intent = Intent("$packageName.RECYCLER_VIEW_ACTIVITY")
scope.startActivityAndWait();
return Unit.INSTANCE;
},
/* measureBlock */ scope -> {
UiDevice device = scope.getDevice();
UiObject2 recycler = device.findObject(By.res(scope.getPackageName(), "recycler"));
// Set gesture margin to avoid triggering gesture navigation
// with input events from automation.
recycler.setGestureMargin(device.getDisplayWidth() / 5);
// Fling the recycler several times.
for (int i = 0; i < 3; i++) {
recycler.fling(Direction.DOWN);
}
return Unit.INSTANCE;
}
);
}
การเปรียบเทียบไม่จำเป็นต้องเลื่อน UI เครื่องมือนี้สามารถเรียกใช้ ภาพเคลื่อนไหว โดยไม่จำเป็นต้องใช้โปรแกรมดำเนินการ UI อัตโนมัติ โดยเฉพาะอย่างยิ่ง ระบบจะรวบรวมเมตริกประสิทธิภาพตราบใดที่ยังมีเฟรม ที่ผลิตโดยระบบมุมมอง รวมถึงเฟรมที่ผลิตโดย Jetpack Compose
ไปยังส่วนภายในของแอป
บางครั้งคุณต้องการเปรียบเทียบส่วนต่างๆ ของแอปของคุณที่ไม่ได้
เข้าถึงได้จากภายนอก ตัวอย่างเช่น การเข้าถึงกิจกรรมภายใน
ที่มีเครื่องหมาย exported=false
, การไปยัง Fragment
หรือการเลื่อน
ของ UI บางส่วนออกไป การเปรียบเทียบต้องไปยังส่วนเหล่านี้ด้วยตนเอง
เช่น ผู้ใช้
หากต้องการไปยังส่วนต่างๆ ด้วยตนเอง ให้เปลี่ยนโค้ดภายใน setupBlock{}
ให้มี
เอฟเฟกต์ที่ต้องการ เช่น การแตะปุ่มหรือเลื่อน measureBlock{}
ของคุณมี
เฉพาะการปรับแต่ง UI ที่คุณต้องการเปรียบเทียบเท่านั้น
@Test
fun nonExportedActivityScrollList() {
benchmarkRule.measureRepeated(
// ...
setupBlock = setupBenchmark()
) {
// ...
}
}
private fun setupBenchmark(): MacrobenchmarkScope.() -> Unit = {
// Before starting to measure, navigate to the UI to be measured
startActivityAndWait()
// click a button to launch the target activity.
// While we use button text here to find the button, you could also use
// accessibility info or resourceId.
val selector = By.text("RecyclerView")
if (!device.wait(Until.hasObject(selector), 5_500)) {
fail("Could not find resource in time")
}
val launchRecyclerActivity = device.findObject(selector)
launchRecyclerActivity.click()
// wait until the activity is shown
device.wait(
Until.hasObject(By.clazz("$packageName.NonExportedRecyclerActivity")),
TimeUnit.SECONDS.toMillis(10)
)
}
@Test
public void scrollList() {
benchmarkRule.measureRepeated(
// ...
/* setupBlock */ scope -> {
// Before measuring, navigate to the default activity.
scope.startActivityAndWait();
// Click a button to launch the target activity.
// While you use resourceId here to find the button, you can also
// use accessibility info or button text content.
UiObject2 launchRecyclerActivity = scope.getDevice().findObject(
By.res(packageName, "launchRecyclerActivity")
)
launchRecyclerActivity.click();
// Wait until activity is shown.
scope.getDevice().wait(
Until.hasObject(By.clazz("$packageName.NonExportedRecyclerActivity")),
10000L
)
return Unit.INSTANCE;
},
/* measureBlock */ scope -> {
// ...
}
);
}
ไม่มีคำแนะนำในขณะนี้
ลองลงชื่อเข้าใช้บัญชี Google