22、CTS/GTS认证:测试用例编写、兼容性测试、问题修复

CTS(Compatibility Test Suite)和GTS(Google Test Suite),说白了就是Google给Android设备发的“准生证”。没有通过这两项认证,你的设备就别想预装Google服务,比如Play商店、Gmail这些。我当年第一次接触CTS时,觉得不就是跑个测试嘛,结果被一堆FAIL砸得晕头转向。嗯,今天我就把这块硬骨头掰开了讲。

CTS和GTS到底测什么?

CTS测的是Android兼容性。它确保你的设备能正确运行Android API,不会出现“这个App在我的手机上闪退”这种尴尬事。GTS则更偏向Google服务本身,比如Google账号登录、安全补丁级别这些。

我个人习惯把CTS/GTS比作“体检报告”:

  • CTS:检查硬件和系统的基本健康指标
  • GTS:检查Google服务生态的兼容性

举个例子,如果你的设备把返回键映射错了,CTS里有个测试用例专门验证KeyEvent的分发。我遇到过一台平板,返回键死活不触发onBackPressed(),查了半天发现是驱动层把按键码搞混了。

测试用例怎么写?

CTS的测试用例基于JUnit和Android的Instrumentation框架。你不需要从零写,因为Google已经开源了测试源码。但有时候你需要自定义测试,比如验证某个硬件特性。

来看一个简单的例子:

public class CustomGtsTest extends AndroidTestCase {
    
    public void testCameraPermission() {
        Context context = getContext();
        int result = ContextCompat.checkSelfPermission(
            context, Manifest.permission.CAMERA);
        assertEquals("Camera permission must be granted", 
            PackageManager.PERMISSION_GRANTED, result);
    }
    
    public void testDisplayDensity() {
        DisplayMetrics metrics = getContext().getResources()
            .getDisplayMetrics();
        assertTrue("Density must be at least 320dpi", 
            metrics.densityDpi >= 320);
    }
}

这里要注意几点:

  • 测试类必须继承AndroidTestCase或InstrumentationTestCase
  • 方法名以test开头,返回void
  • 断言用JUnit的assert系列方法

💡 小技巧:写测试用例时,尽量模拟真实用户场景。比如测试相机权限,别只检查权限是否granted,最好再拍一张照片验证实际功能。

兼容性测试的完整流程

跑CTS/GTS不是一键搞定的事。我总结了一套标准流程:

  1. 准备环境:一台干净的设备(恢复出厂设置),连接USB调试模式
  2. 下载测试包:从Google官方下载对应Android版本的CTS/GTS包
  3. 执行测试:用命令行启动,比如 ./cts-tradefed run cts --plan CTS
  4. 分析结果:查看生成的XML报告,重点关注FAIL和NOT_EXECUTED
  5. 修复问题:根据失败日志定位代码或配置问题
  6. 回归验证:修复后重新跑失败的模块

我曾经遇到一个坑:跑CTS时设备突然断开连接,结果所有测试都标记为NOT_EXECUTED。后来发现是USB线质量太差,换了一根带屏蔽的线就稳了。

问题修复实战:从FAIL到PASS

假设你遇到一个典型的CTS失败:android.hardware.camera2.cts.CameraTest#testCameraCharacteristics。日志显示:

junit.framework.AssertionFailedError: 
Expected: 30fps, but got: 15fps
at CameraTest.testCameraCharacteristics(CameraTest.java:245)

这说明相机预览帧率不达标。怎么修?

  • 检查驱动配置:看kernel里camera sensor的帧率设置是否正确
  • 检查HAL层:Camera HAL返回的supported_fps_range是否包含30fps
  • 检查功耗策略:有时候系统为了省电,会主动降帧率

⚠️ 注意:千万别为了过测试而硬编码返回值。Google会检查HAL层的实际行为,造假会被拉黑名单。

我处理过一个更隐蔽的问题:GTS测试com.google.android.gts.devicepolicy.DevicePolicyTest#testPasswordQuality一直失败。日志说密码策略没生效。查了两天,最后发现是Settings Provider里一个flag写错了位置。你想想看,这种问题光看日志根本看不出来,得一行一行对比AOSP源码。

SVG:CTS/GTS认证知识体系

CTS/GTS认证知识体系 CTS/GTS认证 测试用例编写 JUnit + Instrumentation 自定义测试场景 兼容性测试流程 环境准备 执行测试 分析报告 问题修复 驱动/HAL层 系统配置 核心目标:通过认证,预装Google服务

避坑指南:我踩过的那些雷

做CTS/GTS认证,有些坑几乎是必踩的。我列几个典型的:

  • 测试环境不干净:设备里装了第三方App,导致测试结果异常。我曾经因为装了个输入法,导致GTS的键盘测试全挂。
  • 忽略NOT_EXECUTED:很多人只看FAIL,但NOT_EXECUTED也可能是问题。比如某个测试因为依赖条件不满足被跳过,实际上你的设备根本不支持那个特性。
  • 盲目修改AOSP代码:为了过测试,直接改framework层的代码。这样做风险极高,因为Google的测试会检查签名和哈希值。

记住:CTS/GTS认证不是目的,让用户获得一致的Android体验才是。我见过一些团队为了赶进度,用hack的方式绕过测试,结果后续OTA升级时问题集中爆发,得不偿失。

总结一下

CTS/GTS认证这件事,说白了就是“细节决定成败”。从测试用例的编写,到兼容性测试的执行,再到问题的定位和修复,每一步都需要耐心和细心。我个人建议,在项目初期就把CTS/GTS纳入每日构建流程,而不是等到最后才跑。这样发现问题早,修复成本也低。

好了,关于CTS/GTS认证的核心内容就这些。如果你在实际项目中遇到什么奇葩问题,欢迎来交流。毕竟,搞嵌入式Android的,谁还没被CTS虐过呢?

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