Android MacroBenchmark:FrameTimingMetric 测试仅运行 1 次迭代

问题描述 投票:0回答:1

我正在尝试使用 FrameTimingMetric 在回收器视图上执行 5 次迭代的滚动测试。

我使用 StartupTimingMetric() 的 AppStartup 测试工作正常,并为所有 5 次迭代生成结果。

对于使用 FrameTimingMetric 的滚动测试,它正在执行第一次迭代并且 recyclerview 滚动,但在该测试失败并出现错误(java.lang.IllegalArgumentException:失败的要求)后,应用程序退出并且没有迭代其他剩余的 4 次迭代。

Macrobenchmark 类。

@RunWith(AndroidJUnit4.class)
public class ExampleStartupBenchmark {

    @Rule
    public MacrobenchmarkRule mBenchmarkRule = new MacrobenchmarkRule();

    @Test
    public void startup() {
        mBenchmarkRule.measureRepeated(
                "my-app-package-name",
                Collections.singletonList(new StartupTimingMetric()),
                CompilationMode.DEFAULT,
                StartupMode.COLD,
                5,
                scope -> {
                    scope.startActivityAndWait();
                    return Unit.INSTANCE;
                });
    }

    @Test
    public void scroll() {
        mBenchmarkRule.measureRepeated(
                "my-app-package-name",
                Collections.singletonList(new FrameTimingMetric()),
                CompilationMode.DEFAULT,
                StartupMode.COLD,
                5,
                macrobenchmarkScope -> {
                   
                    Log.i("MacrobenchmarkRuleTAG", "justBeforeIntent");

                    Intent intent = new Intent("MarkMainActivity-intentlaunch-string");

                    macrobenchmarkScope.startActivityAndWait(intent);

                    // Wait until activity is shown.
                    Log.i("MacrobenchmarkRuleTAG", "justBeforeMarkMainActivityWait");
                    macrobenchmarkScope.getDevice().wait(
                            Until.hasObject(By.clazz("MarkMainActivity")),
                            10_000L
                    );

                    Log.i("MacrobenchmarkRuleTAG", "justAfterMarkMainActivityWait");
                    return Unit.INSTANCE;
                }, scope ->{

                    UiDevice device = scope.getDevice();

                    UiObject2 recycler = device.findObject(By.res(scope.getPackageName(), "mark_recyclerview"));
                    SearchCondition<Boolean> searchCond2  = Until.hasObject(By.res("mark_adapter_single_view"));
                    recycler.wait(searchCond2, 10_000L); // wait until recyclerview object loads a singleitemview

                    Log.i("MacrobenchmarkRuleTAG", recycler.getClassName());
           
                    recycler.setGestureMargin(device.getDisplayWidth() / 5);

                    Log.i("MacrobenchmarkRuleTAG", "justbeforefling");
                    recycler.scroll(Direction.DOWN, 55);
             
                    return Unit.INSTANCE;
                });
    }
}

我的 AppStartup 测试运行良好,进行了 5 次迭代并生成结果。所以我最初的基准测试模块设置应该没问题。

对于滚动测试,我需要等到recyclerview加载,因为数据来自MarkMainActivity的Oncreate方法上的API调用,然后recyclerview启动并加载。 所以我尝试为回收器视图设置一些等待条件(“mark_recyclerview”是recyclerview的xml Id)及其singleItem布局(“mark_adapter_single_view”是singleItemView的xml Id)。

对于这段代码,我的markactivity正在打开并且recyclerview正在加载,然后几秒钟后,执行滚动,之后我的测试因错误而停止(java.lang.IllegalArgumentException:失败的要求)并且应用程序关闭并且没有执行剩余的操作4 次迭代。

此外,为了检查日志,日志被写入到最后一个,即:Log.i(“MacrobenchmarkRuleTAG”,“justbeforefling”)。并且还执行了滚动。 所以测试应该执行到最后一行。

如果有人有任何意见或建议,请帮助我了解如何为此用例执行剩余的四次迭代并生成输出。

谢谢。

错误代码:

java.lang.IllegalArgumentException: Failed requirement.
at androidx.benchmark.macro.perfetto.FrameTimingQuery.getFrameSubMetrics(FrameTimingQuery.kt:182)
at androidx.benchmark.macro.FrameTimingMetric.getMetrics$benchmark_macro_release(Metric.kt:231)
at androidx.benchmark.macro.MacrobenchmarkKt.macrobenchmark(Macrobenchmark.kt:209)
at androidx.benchmark.macro.MacrobenchmarkKt.macrobenchmarkWithStartupMode(Macrobenchmark.kt:301)
at androidx.benchmark.macro.junit4.MacrobenchmarkRule.measureRepeated(MacrobenchmarkRule.kt:106)
at com.tc.macrobenchmark.ExampleStartupBenchmark.scroll(ExampleStartupBenchmark.java:51)

我遵循以下准则: 宏观基准

宏基准代码实验室

android performance android-jetpack android-testing macrobenchmark
1个回答
0
投票

FrameTimingQuery.kt 是一个辅助类,用于从 perfetto 跟踪查询帧信息。

“java.lang.IllegalArgumentException:未满足要求。”是 kotlin 中的

require
语句抛出的异常。

FrameTimingQuery.kt 类中有 3 个 require 语句。

require(actualSlices.isEmpty() == newSlicesShouldBeEmpty)
require(expectedSlices.isEmpty() == newSlicesShouldBeEmpty)
require(slices.none { it.frameId == null })

一定有一个不满意的地方。

Slice 表示带有开始/结束时间戳和名称的跟踪事件。 实际切片是指应用程序生成帧切片 Expexted Slice 表示应用程序期望生成帧切片 FrameId 是 Expected/Actual Slice 中的 id,Choreographer#doFrame 中 UiThread 中的 slice,drawFrames 中 RenderThread 中的 id,这有助于将它们关联起来。

您需要通过macrobenchmark测试检查perfetto跟踪记录,使用https://ui.perfetto.dev/打开它,手动检查。

© www.soinside.com 2019 - 2024. All rights reserved.