01-17-11 兼容性测试策略
01-17-11 兼容性测试策略兼容性测试的重要性Android设备碎片化严重兼容性测试是保证应用质量的关键环节。碎片化现状Android版本 - Android 6-14共9个大版本在使用 - 各版本市场占比不同 - API行为差异巨大 设备厂商 - Samsung、Xiaomi、OPPO、VIVO等 - 各厂商系统深度定制 - ROM行为可能与AOSP不同 屏幕尺寸 - 手机4.7-7 - 平板7-13 - 折叠屏多种形态 硬件配置 - CPU骁龙、联发科、海思等 - 内存2GB-16GB - 存储16GB-1TB兼容性测试维度1. API Level兼容性/** * API Level兼容性测试检查点 */objectApiLevelTestChecklist{/** * minSdkVersion测试 */funtestMinSdkVersion(){// 在最低支持版本设备上测试// 检查点// 1. 应用能否正常安装// 2. 启动是否崩溃// 3. 核心功能是否可用// 4. UI是否正常显示}/** * targetSdkVersion测试 */funtestTargetSdkVersion(){// 在目标版本设备上测试// 检查点// 1. 运行时权限申请// 2. 分区存储适配// 3. 后台限制// 4. 通知权限}/** * 最新版本测试 */funtestLatestVersion(){// 在最新Android版本上测试// 检查点// 1. 新API兼容性// 2. 废弃API替换// 3. 新权限适配// 4. 新特性支持}/** * 边界版本测试 */funtestBoundaryVersions(){// 在关键版本边界测试// Android 6.0运行时权限// Android 10分区存储// Android 11强制分区存储// Android 12精确位置// Android 13通知权限}}2. 厂商兼容性/** * 厂商兼容性测试 */objectVendorTestChecklist{/** * 主流厂商设备 */valmainVendorslistOf(Samsung,// 三星Xiaomi,// 小米OPPO,// OPPOVIVO,// VIVOHuawei,// 华为OnePlus,// 一加Realme,// 真我Motorola,// 摩托罗拉Google Pixel// 原生Android)/** * 厂商定制检查 */funtestVendorCustomization(){// 检查点// 1. 后台进程管理// - 小米神隐模式// - 华为电池优化// - OPPO/VIVO省电模式//// 2. 权限管理// - 悬浮窗权限// - 自启动权限// - 后台定位权限//// 3. 通知管理// - 通知渠道兼容// - 通知免打扰// - 通知角标//// 4. ROM特性// - 全面屏手势// - 黑暗模式// - 系统字体大小}/** * 原生Android基准测试 */funtestAOSP(){// Google Pixel或Android模拟器// 作为基准参考}}3. 屏幕尺寸兼容性/** * 屏幕兼容性测试 */objectScreenTestChecklist{/** * 手机屏幕 */valphoneScreenslistOf(480x854 (FWVGA),// 小屏手机720x1280 (HD),// HD手机1080x1920 (FHD),// Full HD手机1440x2560 (QHD),// 2K手机1080x2340 (FHD),// 刘海屏1080x2400 (FHD),// 打孔屏)/** * 平板屏幕 */valtabletScreenslistOf(800x1280 (7\),// 7寸平板1200x1920 (10\),// 10寸平板1600x2560 (12\),// 12寸平板)/** * 折叠屏 */valfoldableScreenslistOf(展开态,折叠态,桌面模式,)/** * 屏幕测试检查点 */funtestScreenCompatibility(){// 检查点// 1. 布局适配// - 横竖屏切换// - 不同DPI显示// - 刘海屏/打孔屏// - 折叠屏适配//// 2. 文本显示// - 不同字体大小// - 长文本截断// - 多语言显示//// 3. 图片资源// - mdpi/hdpi/xhdpi/xxhdpi/xxxhdpi// - 矢量图标//// 4. 交互体验// - 触摸区域大小// - 滚动流畅度// - 动画效果}}自动化兼容性测试使用Firebase Test Lab/** * Firebase Test Lab配置 */// build.gradleandroid{defaultConfig{testInstrumentationRunnerandroidx.test.runner.AndroidJUnitRunner}}dependencies{androidTestImplementation androidx.test.ext:junit:1.1.5 androidTestImplementation androidx.test.espresso:espresso-core:3.5.1}// app/src/androidTest/java/com/example/CompatibilityTest.ktRunWith(AndroidJUnit4::class)classCompatibilityTest{get:RulevalactivityRuleActivityScenarioRule(MainActivity::class.java)TestfuntestAppLaunch(){// 测试应用启动onView(withId(R.id.main_layout)).check(matches(isDisplayed()))}TestfuntestCoreFeatures(){// 测试核心功能onView(withId(R.id.button)).perform(click())onView(withId(R.id.result)).check(matches(withText(Success)))}TestfuntestPermissions(){// 测试权限申请// ...}TestfuntestScreenRotation(){// 测试屏幕旋转activityRule.scenario.onActivity{activity-activity.requestedOrientationActivityInfo.SCREEN_ORIENTATION_LANDSCAPE}Thread.sleep(1000)onView(withId(R.id.main_layout)).check(matches(isDisplayed()))}}# Firebase Test Lab命令行# 上传APK并在多个设备上测试gcloud firebasetestandroid run\--typeinstrumentation\--appapp/build/outputs/apk/debug/app-debug.apk\--testapp/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk\--devicemodelPixel2,version28,localeen,orientationportrait\--devicemodelPixel4,version30,localeen,orientationportrait\--devicemodelgalaxy_s21,version31,localeen,orientationportrait矩阵测试配置# Firebase Test Lab矩阵配置 # .github/workflows/android-test.yml name: Android CI on: [push, pull_request] jobs: test: runs-on: ubuntu-latest strategy: matrix: api-level: [23, 26, 28, 30, 31, 33] target: [google_apis] arch: [x86, x86_64] steps: - uses: actions/checkoutv3 - name: Run tests uses: reactivecircus/android-emulator-runnerv2 with: api-level: ${{ matrix.api-level }} target: ${{ matrix.target }} arch: ${{ matrix.arch }} script: ./gradlew connectedCheck版本检测测试测试Build.VERSION判断RunWith(AndroidJUnit4::class)classVersionCheckTest{TestfuntestAndroid6Permissions(){// 模拟Android 6.0if(Build.VERSION.SDK_INTBuild.VERSION_CODES.M){// 验证运行时权限逻辑assertTrue(应该请求权限,shouldRequestPermission())}else{// 验证无需权限逻辑assertFalse(不应该请求权限,shouldRequestPermission())}}TestfuntestAndroid10ScopedStorage(){// 模拟Android 10if(Build.VERSION.SDK_INTBuild.VERSION_CODES.Q){// 验证分区存储逻辑assertTrue(应该使用MediaStore,usesMediaStore())}else{// 验证传统存储逻辑assertTrue(应该使用File API,usesFileApi())}}TestfuntestAndroid13NotificationPermission(){// 模拟Android 13if(Build.VERSION.SDK_INTBuild.VERSION_CODES.TIRAMISU){// 验证通知权限逻辑assertTrue(应该请求通知权限,needsNotificationPermission())}else{// 验证无需通知权限assertFalse(不应该请求通知权限,needsNotificationPermission())}}privatefunshouldRequestPermission():Boolean{// 实际权限检查逻辑returnfalse}privatefunusesMediaStore():Boolean{returntrue}privatefunusesFileApi():Boolean{returntrue}privatefunneedsNotificationPermission():Boolean{returntrue}}Mock Build.VERSION测试/** * 使用Robolectric模拟不同Android版本 */RunWith(RobolectricTestRunner::class)Config(sdk[Build.VERSION_CODES.M])// Android 6.0classAndroid6Test{TestfuntestRuntimePermission(){valactivityRobolectric.buildActivity(MainActivity::class.java).create().get()// 验证Android 6.0行为assertTrue(activity.usesRuntimePermissions())}}RunWith(RobolectricTestRunner::class)Config(sdk[Build.VERSION_CODES.Q])// Android 10classAndroid10Test{TestfuntestScopedStorage(){valactivityRobolectric.buildActivity(MainActivity::class.java).create().get()// 验证Android 10行为assertTrue(activity.usesScopedStorage())}}RunWith(RobolectricTestRunner::class)Config(sdk[Build.VERSION_CODES.TIRAMISU])// Android 13classAndroid13Test{TestfuntestNotificationPermission(){valactivityRobolectric.buildActivity(MainActivity::class.java).create().get()// 验证Android 13行为assertTrue(activity.needsNotificationPermission())}}兼容性回归测试建立回归测试套件/** * 兼容性回归测试套件 */RunWith(Suite::class)Suite.SuiteClasses(PermissionCompatTest::class,StorageCompatTest::class,NotificationCompatTest::class,LifecycleCompatTest::class,LayoutCompatTest::class)classCompatibilityRegressionTestSuite/** * 权限兼容性测试 */RunWith(AndroidJUnit4::class)classPermissionCompatTest{TestfuntestCameraPermission(){// 测试相机权限在不同版本的行为}TestfuntestLocationPermission(){// 测试位置权限在不同版本的行为}TestfuntestStoragePermission(){// 测试存储权限在不同版本的行为}}/** * 存储兼容性测试 */RunWith(AndroidJUnit4::class)classStorageCompatTest{TestfuntestSaveImage(){// 测试保存图片在不同版本的兼容性}TestfuntestReadImage(){// 测试读取图片在不同版本的兼容性}TestfuntestFileAccess(){// 测试文件访问在不同版本的兼容性}}/** * 通知兼容性测试 */RunWith(AndroidJUnit4::class)classNotificationCompatTest{TestfuntestNotificationChannel(){// 测试通知渠道兼容性}TestfuntestNotificationPermission(){// 测试通知权限兼容性}TestfuntestNotificationStyles(){// 测试通知样式兼容性}}真机测试策略建立测试机库【必测设备矩阵】 低端机 - 小米 Redmi 9A (Android 10, 2GB RAM) - OPPO A5 (Android 9, 3GB RAM) 中端机 - 小米 11 Lite (Android 11, 8GB RAM) - OPPO Reno 5 (Android 11, 8GB RAM) 高端机 - 小米 13 Pro (Android 13, 12GB RAM) - 三星 S23 Ultra (Android 13, 12GB RAM) 原生机 - Google Pixel 6 (Android 13) - Google Pixel 7 Pro (Android 14) 平板 - 小米平板 5 (Android 11) - 三星 Tab S8 (Android 12) 折叠屏 - 三星 Z Fold 4 (Android 12) - 华为 Mate X2 (HarmonyOS)真机测试检查清单/** * 真机测试检查清单 */objectRealDeviceTestChecklist{/** * 基础功能测试 */funtestBasicFeatures(){// 1. 安装启动// - 能否正常安装// - 启动是否崩溃// - 启动时间//// 2. 核心功能// - 登录注册// - 主要业务流程// - 数据加载//// 3. 权限申请// - 权限弹窗显示// - 授予/拒绝处理// - 永久拒绝引导//// 4. 网络请求// - 正常网络// - 弱网环境// - 无网络提示}/** * UI测试 */funtestUI(){// 1. 布局显示// - 不同屏幕尺寸// - 横竖屏切换// - 刘海屏/打孔屏//// 2. 交互体验// - 按钮点击// - 列表滚动// - 页面跳转// - 返回键处理//// 3. 视觉效果// - 图片加载// - 动画流畅度// - 深色模式}/** * 性能测试 */funtestPerformance(){// 1. 内存占用// - 正常使用// - 长时间使用// - 内存泄漏检测//// 2. CPU占用// - 待机状态// - 正常使用// - 高负载场景//// 3. 电量消耗// - 前台运行// - 后台运行// - 锁屏状态//// 4. 流畅度// - 页面渲染FPS// - 滑动卡顿// - 动画掉帧}/** * 稳定性测试 */funtestStability(){// 1. 长时间运行// - 24小时不崩溃// - 内存稳定//// 2. 极端场景// - 低内存// - 低电量// - 弱网络//// 3. 异常处理// - 崩溃恢复// - 网络错误// - 数据异常}/** * 兼容性测试 */funtestCompatibility(){// 1. Android版本// - 最低支持版本// - 主流版本// - 最新版本//// 2. 厂商定制// - 权限管理// - 后台限制// - 通知管理//// 3. 屏幕适配// - 不同分辨率// - 不同DPI// - 特殊屏幕}}云测试平台主流云测试平台对比Firebase Test LabGoogle: - 支持真机和模拟器 - 集成度高配置简单 - 免费配额有限 - 主要覆盖Google设备 AWS Device FarmAmazon: - 真机数量多 - 支持自动化和手动测试 - 按使用付费 - 全球设备覆盖 腾讯WeTest: - 国内设备全 - 中文友好 - 支持性能分析 - 适合国内市场 阿里移动测试MQC: - 阿里云生态 - 国内主流设备 - 自动化兼容测试 - 集成便捷Firebase Test Lab集成// build.gradleplugins{id com.google.gms.google-services}dependencies{androidTestImplementation androidx.test:runner:1.5.2 androidTestImplementation androidx.test.espresso:espresso-core:3.5.1}# 命令行测试gcloud firebasetestandroid run\--typeinstrumentation\--appapp-debug.apk\--testapp-debug-androidTest.apk\--devicemodelPixel2,version28\--devicemodelPixel4,version30\--devicemodelgalaxy_s21,version31\--timeout30m\--results-bucketgs://my-bucket\--results-dirtest-results兼容性监控线上监控指标/** * 兼容性监控 */objectCompatibilityMonitoring{/** * 崩溃率监控 */funmonitorCrashRate(){// 按Android版本统计// 按设备型号统计// 按ROM版本统计// Firebase CrashlyticsFirebaseCrashlytics.getInstance().setCustomKey(android_version,Build.VERSION.SDK_INT)FirebaseCrashlytics.getInstance().setCustomKey(device_model,Build.MODEL)FirebaseCrashlytics.getInstance().setCustomKey(device_manufacturer,Build.MANUFACTURER)}/** * 兼容性问题上报 */funreportCompatibilityIssue(issue:CompatibilityIssue){// 上报到监控平台valparamsmapOf(issue_typetoissue.type,android_versiontoBuild.VERSION.SDK_INT,device_modeltoBuild.MODEL,rom_versiontogetRomVersion(),error_messagetoissue.message)analytics.logEvent(compatibility_issue,params)}dataclassCompatibilityIssue(valtype:String,valmessage:String)privatefungetRomVersion():String{returnBuild.DISPLAY}}兼容性指标看板【关键指标】 1. 崩溃率 - 总体崩溃率 0.5% - 按版本崩溃率 1% - 按设备崩溃率 2% 2. ANR率 - 总体ANR率 0.1% - 主线程阻塞 5秒 3. 兼容性覆盖率 - Android版本覆盖 ≥ 95% - 设备型号覆盖 ≥ 90% - 屏幕尺寸覆盖 ≥ 85% 4. 用户体验 - 启动时间 2秒 - 页面加载 1秒 - 交互响应 100ms总结兼容性测试核心策略版本矩阵测试覆盖minSdk到最新版本厂商设备测试主流厂商原生Android自动化测试Firebase Test LabCI/CD真机测试建立测试机库定期回归线上监控崩溃率兼容性问题追踪测试优先级P0必测minSdk、targetSdk、主流版本P1重要主流厂商设备、常见屏幕P2次要边界版本、特殊设备持续改进建立兼容性问题库定期更新测试矩阵自动化覆盖率提升真机测试常态化关键要点兼容性测试是持续过程需要自动化真机测试相结合并持续监控线上数据