测试场景等待启动屏幕完成,滚动浏览 RecyclerView,然后单击其中的随机项目。您的 XML 布局包括一个 CollapsingToolbarLayout 和一个名为 mainAdsRecyclerView 的 RecyclerView,其中似乎包含广告项。
您的 UI 测试类 BaselineProfileGenerator 包含测试场景每个步骤的方法:
这个设置看起来很全面,涵盖了等待时间、滚动操作以及与 RecyclerView 的交互。但是,如果您遇到任何问题或需要进一步帮助,请随时询问!
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/mainAdsRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingHorizontal="16dp"
android:paddingBottom="120dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:listitem="@layout/row_ad"
tools:visibility="gone" />
@RunWith(AndroidJUnit4::class)
class BaselineProfileGenerator {
@get:Rule
val rule = BaselineProfileRule()
@Test
fun generate() {
rule.collect("com.camelan") {
pressHome()
startActivityAndWait()
// Ensure the activity is fully loaded
device.waitForIdle(10_000)
waitSplashScreenFinish()
scrollThroughToolbarLayout()
waitForAsyncContent()
scrollThroughMainAdsRecyclerView()
goToMainAdDetailJourney()
}
}
}
fun MacrobenchmarkScope.waitSplashScreenFinish() {
val timeout = 15_000L // Increase timeout to 15 seconds for more robustness
Log.d("BaselineProfileGenerator", "Waiting for toolbar_layout to appear")
if (!device.wait(Until.hasObject(By.res("com.camelan.main:id/toolbar_layout")), timeout)) {
Log.e("BaselineProfileGenerator", "toolbar_layout did not appear within the timeout")
throw IllegalStateException("toolbar_layout did not appear within the timeout")
}
Log.d("BaselineProfileGenerator", "toolbar_layout appeared")
}
fun MacrobenchmarkScope.scrollThroughToolbarLayout() {
val toolbarLayout = UiScrollable(UiSelector().resourceId("com.camelan.main:id/toolbar_layout"))
toolbarLayout.flingToEnd(10)
device.waitForIdle()
}
fun MacrobenchmarkScope.waitForAsyncContent() {
val timeout = 15_000L // Increase timeout to 15 seconds for more robustness
Log.d("BaselineProfileGenerator", "Waiting for mainAdsRecyclerView to appear")
if (device.wait(Until.hasObject(By.res("com.camelan.main:id/mainAdsRecyclerView")), timeout)) {
val contentList = device.findObject(By.res("com.camelan.main:id/mainAdsRecyclerView"))
if (contentList != null) {
if (!contentList.wait(
Until.hasObject(By.res("com.camelan.main:id/ad_item")),
timeout
)
) {
Log.e("BaselineProfileGenerator", "No ad items appeared within the timeout")
throw IllegalStateException("No ad items appeared within the timeout")
}
} else {
Log.e("BaselineProfileGenerator", "mainAdsRecyclerView not found")
throw IllegalStateException("mainAdsRecyclerView not found")
}
} else {
Log.e("BaselineProfileGenerator", "mainAdsRecyclerView did not appear within the timeout")
throw IllegalStateException("mainAdsRecyclerView did not appear within the timeout")
}
Log.d("BaselineProfileGenerator", "mainAdsRecyclerView appeared")
}
fun MacrobenchmarkScope.scrollThroughMainAdsRecyclerView() {
val mainAdsRecyclerView =
UiScrollable(UiSelector().resourceId("com.camelan.main:id/mainAdsRecyclerView"))
mainAdsRecyclerView.flingToEnd(10)
device.waitForIdle()
}
fun MacrobenchmarkScope.goToMainAdDetailJourney() {
val mainAdsRecyclerView = device.findObject(By.res("com.camelan.main:id/mainAdsRecyclerView"))
if (mainAdsRecyclerView != null) {
val ads = mainAdsRecyclerView.findObjects(By.res("com.camelan.main:id/ad_item"))
if (ads.isNotEmpty()) {
val index = (iteration ?: 0) % ads.size
ads[index].click()
device.wait(Until.gone(By.res("com.camelan.main:id/mainAdsRecyclerView")), 5_000)
} else {
Log.e("BaselineProfileGenerator", "No ads found in mainAdsRecyclerView")
throw IllegalStateException("No ads found in mainAdsRecyclerView")
}
} else {
Log.e("BaselineProfileGenerator", "mainAdsRecyclerView not found")
throw IllegalStateException("mainAdsRecyclerView not found")
}
}
我也试过这个
@RunWith(AndroidJUnit4::class)
class RecyclerViewActivityBaselineProfileGenerator : BaselineProfileGenerator() {
override fun MacrobenchmarkScope.profileBlock() {
// Start into the RecyclerViewActivity
startActivityAndWait()
device.waitForIdle(20_000)
// Scrolling RecyclerView journey
device.findObject(By.res("com.camelan.main", "mainAdsRecyclerView")).also {
it.setGestureMargin(device.displayWidth / 10)
it.fling(Direction.DOWN)
it.fling(Direction.UP)
}
}
}
但是我收到了这个错误
java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.test.uiautomator.UiObject2.setGestureMargin(int)' on a null object reference
at com.camelan.baselineprofile.RecyclerViewActivityBaselineProfileGenerator.profileBlock(HomeBaselineProfileGenerator.kt:20)
at com.camelan.baselineprofile.BaselineProfileGenerator$profileGenerator$1.invoke(BaselineProfileGenerator.kt:28)
at com.camelan.baselineprofile.BaselineProfileGenerator$profileGenerator$1.invoke(BaselineProfileGenerator.kt:23)
at androidx.benchmark.macro.BaselineProfilesKt$collect$1$1.invoke(BaselineProfiles.kt:77)
at androidx.benchmark.macro.BaselineProfilesKt$collect$1$1.invoke(BaselineProfiles.kt:71)
at androidx.benchmark.macro.CompilationMode$Partial.compileImpl$benchmark_macro_release(CompilationMode.kt:318)
at androidx.benchmark.macro.CompilationMode.resetAndCompile$benchmark_macro_release(CompilationMode.kt:114)
at androidx.benchmark.macro.BaselineProfilesKt.collect(BaselineProfiles.kt:71)
at androidx.benchmark.macro.junit4.BaselineProfileRule.collect(BaselineProfileRule.kt:136)
at androidx.benchmark.macro.junit4.BaselineProfileRule.collect$default(BaselineProfileRule.kt:126)
at com.camelan.baselineprofile.BaselineProfileGenerator.profileGenerator(BaselineProfileGenerator.kt:23)