ควบคุมแอปจากการเปรียบเทียบแบบมาโคร

การทดสอบ Macrobenchmark แตกต่างจากการทดสอบ UI ของ Android ส่วนใหญ่ตรงที่กระบวนการที่แยกจากกัน จากตัวแอปเอง การดำเนินการนี้เป็นสิ่งจำเป็นสำหรับการเปิดใช้สิ่งต่างๆ เช่น การหยุด กระบวนการของแอปและการคอมไพล์จากไบต์โค้ด DEX ไปยังโค้ดของเครื่อง

คุณกำหนดสถานะของแอปได้โดยใช้ไลบรารี UIAutomator หรือ ที่สามารถควบคุมแอปเป้าหมายจากกระบวนการทดสอบได้ คุณไม่สามารถใช้ Espresso หรือ ActivityScenario สำหรับ การเปรียบเทียบมาโคร เนื่องจากลูกค้าคาดหวังว่าจะทำงานในกระบวนการที่แชร์กับแอป

ตัวอย่างต่อไปนี้จะค้นหา RecyclerView โดยใช้รหัสทรัพยากรและ เลื่อนลงหลายครั้ง

KotlinJava
@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 ที่คุณต้องการเปรียบเทียบเท่านั้น

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