與大多數 Android UI 測試不同,Macrobenchmark 測試會在獨立的程序中執行 從應用程式本身直接擷取內容以便執行能夠停止 應用程式程序,並從 DEX 位元碼編譯至機器碼。
您可以使用 UIAutomator 程式庫或其他
可透過測試程序控制目標應用程式的機制。
Espresso 或 ActivityScenario
無法用於
Macrobenchmark,因為需搭配應用程式一起執行。
以下示範使用資源 ID 尋找 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 Automator 。只要影格處於建立狀態,系統就會收集成效指標 由 View 系統產生的,包括 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 帳戶。