27. 启动优化自动化测试:UI Automator模拟启动、重复性测试、性能基线

启动优化做完了,效果到底怎么样?

说实话,光靠手动点几下、肉眼看看,根本不够。我见过太多团队,优化完自我感觉良好,结果一上自动化测试,数据波动大得吓人。所以今天咱们聊聊,怎么用UI Automator把启动测试做成自动化,跑出靠谱的性能基线。

为什么需要自动化测试?

你想想看,手动测试有几个硬伤:

  • 手速不一致:每次点击的间隔、力度都不一样,数据没法对比
  • 样本量太少:手动跑个三五次就累了,但启动时间本身就有随机波动
  • 回归成本高:改一行代码,就得把所有机型重新测一遍,谁受得了?

我在项目中遇到过,有一次优化了冷启动,手动测了5次,平均快了200ms。结果自动化一跑,50次下来,发现只是运气好,实际只快了50ms。嗯,从那以后,我再也不信手动数据了。

核心原则:启动优化测试,必须自动化、重复化、基线化。缺一不可。

UI Automator 模拟启动

UI Automator 是 Android 官方提供的 UI 测试框架。用它模拟启动,说白了就是写个脚本,让手机自动打开应用、等待首页加载、记录时间。

我习惯用这种方式来写启动测试:

// 冷启动测试示例
public class LaunchTest extends BaseTest {

    @Test
    public void testColdLaunch() {
        // 1. 先杀掉进程,保证是冷启动
        UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
        device.executeShellCommand("am force-stop com.example.app");

        // 2. 等待进程彻底消失
        SystemClock.sleep(2000);

        // 3. 记录开始时间
        long startTime = System.currentTimeMillis();

        // 4. 启动应用
        Context context = InstrumentationRegistry.getContext();
        Intent intent = context.getPackageManager()
                .getLaunchIntentForPackage("com.example.app");
        context.startActivity(intent);

        // 5. 等待首页关键元素出现
        UiObject2 homeElement = device.wait(
                Until.findObject(By.res("com.example.app:id/home_container")),
                5000);

        // 6. 记录结束时间
        long endTime = System.currentTimeMillis();

        // 7. 计算启动耗时
        long launchTime = endTime - startTime;
        System.out.println("冷启动耗时: " + launchTime + "ms");

        // 8. 断言:不能超过性能基线
        assertTrue("启动时间超标: " + launchTime + "ms", launchTime < 2000);
    }
}

小技巧:判断首页加载完成,别用「等几秒」这种笨办法。应该等一个关键UI元素出现,比如首页的列表、标题栏。这样更准确,也更能反映真实用户体验。

重复性测试:跑出稳定数据

单次测试没有意义。启动时间受很多因素影响:CPU频率、内存状态、后台进程……所以必须重复跑,取统计值。

我个人习惯的做法是:

  • 冷启动跑20次:每次都要杀掉进程,模拟首次打开
  • 温启动跑10次:按Home键再回来,模拟切换场景
  • 热启动跑10次:按最近任务键再切回来

跑完之后,我一般看这几个指标:

指标 说明 我常用的阈值
P50(中位数) 去掉极端值后的典型表现 冷启动 < 1.5s
P95 最差情况下的表现 冷启动 < 2.5s
标准差 数据波动程度 < 200ms

为什么要看P95?因为用户遇到的就是最差情况。平均值再好看,偶尔卡一次,用户就骂娘了。

注意:测试前一定要保证手机状态一致。比如:关闭自动亮度、关闭省电模式、清空后台进程。我曾经因为没关省电模式,数据直接翻了一倍,排查了半天才发现。

性能基线:让数据说话

基线是什么?说白了就是一条红线。每次代码提交后,自动化测试跑出来的数据,不能越过这条线。

我建议这样建立基线:

  1. 先跑一轮基准测试:在稳定版本上,跑50次冷启动,记录P50和P95
  2. 写入配置文件:把基线值写到项目的性能配置里
  3. CI/CD集成:每次构建自动跑测试,超基线就报警
// 性能基线配置示例
public class PerformanceBaseline {
    // 冷启动基线(单位:ms)
    public static final long COLD_LAUNCH_P50 = 1500;
    public static final long COLD_LAUNCH_P95 = 2500;

    // 温启动基线
    public static final long WARM_LAUNCH_P50 = 800;
    public static final long WARM_LAUNCH_P95 = 1200;
}

有了基线,你就能回答老板的灵魂拷问:「这次优化到底有没有效果?」直接把数据甩过去,比说一万句都有用。

自动化测试的整体流程

我把整个流程画了张图,方便你理解:

启动优化自动化测试流程 1. 环境准备 关闭省电/清后台 2. 执行测试 UI Automator脚本 3. 数据采集 记录启动耗时 4. 数据分析 计算P50/P95 5. 基线对比 是否超出阈值? 重复N次 6. 生成报告 CI/CD集成 关键点: • 每次测试前保证环境一致 • 至少跑20次取统计值 • 基线要写入CI/CD,自动拦截劣化

避坑指南

做自动化测试,有几个坑我踩过,分享给你:

  • 不要用Thread.sleep()等固定时间:不同机型速度不同,应该用UI Automator的wait()方法,等元素出现
  • 注意第一次启动的特殊性:安装后的第一次启动,可能会有dex优化、资源加载,数据要单独记录
  • 别忘了清理缓存:每次测试前,最好清一下应用缓存,避免上次的数据影响本次结果

我的习惯:每次跑完测试,自动把结果发到钉钉/飞书群。这样团队每个人都能看到性能趋势,谁改坏了代码,一目了然。

好了,自动化测试这块就聊到这儿。记住一句话:没有数据支撑的优化,都是耍流氓。把UI Automator用起来,让机器替你盯着性能,你就能腾出手来做更有价值的事。

公众号:蓝海资料掘金营,微信deep3321