自动化性能测试:CTS/CTS Verifier Camera测试、自定义性能测试脚本(Python/Shell)、持续集成中的性能回归检测、性能基线建立

做Camera HAL这么多年,我越来越觉得一件事:性能优化不是靠“感觉”的,而是靠“数据”说话的。你优化了一个模块,到底快了多少?会不会把别的模块拖慢了?这些问题,没有自动化测试,你根本答不上来。

今天我们就聊聊自动化性能测试这套体系。说白了,就是让机器替你去跑测试、收集数据、判断好坏。你想想看,一个版本迭代几百次,每次都手动测?那不得累死。

CTS与CTS Verifier:官方给你的“体检单”

CTS(Compatibility Test Suite)是Google提供的兼容性测试套件。它不光是测功能,也测性能。比如Camera的启动时间、拍照延迟、预览帧率,CTS里都有对应的测试项。

我个人习惯,每次合入大改之后,先跑一遍CTS Camera相关的测试。不是为了过认证,而是为了看看有没有把基础性能搞崩了。

关键点:CTS测试通过 ≠ 性能达标。CTS只设了一个“及格线”,你要做的是远超及格线。

CTS Verifier呢?它需要人工参与。比如对着特定 chart 拍照、比对画面。这部分没法完全自动化,但你可以写脚本辅助操作,减少人工重复劳动。

我曾经遇到一个坑:CTS全过了,但用户反馈拍照卡顿。后来发现CTS测的是“冷启动”,而用户场景是“热启动+连拍”。所以,别迷信CTS,它只是起点。

自定义性能测试脚本:Python/Shell才是你的武器

CTS测的是通用场景。但你的产品可能有特殊场景,比如“夜景模式连续拍10张”、“HDR+人像同时开启”。这些CTS不测,你得自己来。

我推荐用Python写测试脚本,配合adb命令。结构很简单:

import subprocess
import time

def measure_camera_launch_time():
    # 启动相机
    subprocess.run(["adb", "shell", "am", "start", "-n", "com.android.camera/.CameraActivity"])
    time.sleep(0.5)
    # 获取logcat中的启动完成标记
    result = subprocess.run(["adb", "logcat", "-d", "|", "grep", "CameraOpen:end"], capture_output=True, text=True)
    # 解析时间戳
    # ... 你的解析逻辑
    return launch_time_ms

# 循环跑10次取平均值
times = []
for i in range(10):
    times.append(measure_camera_launch_time())
    subprocess.run(["adb", "shell", "am", "force-stop", "com.android.camera"])

avg_time = sum(times) / len(times)
print(f"平均启动时间: {avg_time} ms")

Shell脚本适合做快速验证。比如我经常写一个test_perf.sh,里面就几行:

#!/bin/bash
for i in {1..5}; do
    adb shell am start -W com.android.camera/.CameraActivity | grep "TotalTime"
    adb shell am force-stop com.android.camera
    sleep 1
done
小技巧:Python脚本里加上异常重试机制。设备偶尔会抽风,一次失败就放弃,数据就不准了。我一般设3次重试,还失败才跳过。

持续集成中的性能回归检测

代码合入之后,性能有没有变差?你不能等用户反馈才知道。持续集成(CI)里挂上性能测试,每次提交自动跑,这才是正解。

我参与过的项目,CI流程大概是这样的:

  1. 开发者提交代码到Gerrit
  2. 触发Jenkins job,编译新版本
  3. 刷机到测试设备(通常是一台专用的Pixel或开发板)
  4. 运行CTS Camera测试 + 自定义性能脚本
  5. 收集数据,与基线对比
  6. 如果性能下降超过阈值(比如5%),自动打回提交

这里有个关键点:阈值怎么设?设太严,天天误报;设太松,漏掉问题。我建议先跑两周数据,看正常波动范围,然后取“均值±3倍标准差”作为阈值。

注意:CI环境要稳定。同一台设备、同一版本固件、同一网络条件。否则你分不清是代码问题还是环境波动。

性能基线建立:没有基线,就没有“好”与“坏”

基线是什么?就是你的“参考值”。比如“相机启动时间基线是800ms”,那这次跑了850ms,就是退步了。

建立基线的方法:

  • 历史数据法:取过去N个稳定版本的数据,计算平均值
  • 竞品对标法:拿友商同档位设备的数据做参考
  • 理论极限法:根据硬件能力推算的理论最优值

我个人更倾向于“历史数据法+人工修正”。比如某个版本因为驱动更新,整体性能提升了10%,那基线就该跟着调。

基线不是一成不变的。每季度或每个大版本发布后,重新校准一次。我见过有的团队基线设了两年没动,结果新硬件性能翻倍了,基线反而成了拖后腿的“及格线”。

知识体系总览

下面这张图,是我对自动化性能测试体系的理解。你可以把它当作一个检查清单:

自动化性能测试体系 CTS/CTS Verifier 官方兼容性测试 自定义脚本 Python/Shell CI回归检测 Jenkins/GitLab CI 性能基线 历史数据/阈值 数据采集与汇聚 性能分析 & 回归判定 与基线对比 → 是否超过阈值 通过 / 告警 / 自动回退

你看,从CTS到自定义脚本,再到CI集成和基线建立,这是一条完整的链路。少了任何一环,你的性能优化都是在“盲打”。

嗯,今天就先聊到这儿。自动化测试这块,工具和方法都不难,难的是坚持和持续改进。你先把基线建起来,后面的事情就好办了。


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