移动端功能测试的难点不是单个平台,而是两端系统机制不同导致的同一功能、不同行为。
一、权限模型:
权限是iOS和Android功能测试差别最集中的领域,两者的模型完全不同。
Android采用Manifest声明加运行时授权的双层模型。应用在 AndroidManifest.xml 中声明所需权限,安装时系统展示权限清单,但敏感权限(相机、位置、通讯录等)自Android6.0 起需要在运行时逐个向用户弹窗申请。测试时需要包括:首次启动申请、用户拒绝、永久拒绝(不再询问)、以及从设置中手动恢复权限等途径。
iOS 的权限模型更为复杂,是三层结构的叠加:基础沙盒(自动应用,无需用户交互)加开发者侧 entitlements(安装时生效)加运行时授权弹窗(相机、麦克风、位置、通讯录、照片、蓝牙等)。其中区别是:iOS 的通知权限不属于 TCC体系,无法通过simctl等命令行工具预授予,测试自动化时必须在运行时处理系统弹窗。此外iOS的照片权限从iOS 14起还支持有限访问(用户仅选择部分照片),测试时需要证实应用在受限照片库下的表现。
测试差别:Android测试动态权限的申请时机、拒绝后的降级行为、以及Android 13+的通知运行时权限(POST_NOTIFICATIONS);iOS 重点测试 purpose string(隐私用途描述)是不是正确配置、权限状态在设置中被用户中途更改后的应用行为。
二、导航和返回:
Android有系统级的Back机制-不管是传统的三大键(返回/Home/多任务),还是全面屏手势中的侧滑返回,系统都会向应用发送统一的返回事件。这意味着测试Android时必须测试Back键在每一个页面层级的行为:是正常返回上一页、退出当前Flow、还是应该被拦截如再按一次退出。Back 键的行为还可能被应用重写,测试需要确定重写后的反馈是不是符合预期。此外Android的Back事件还可以用于应用间切换和返回主屏幕。
iOS 没有系统级的Back键或Back事件。应用需要自行在导航栏放置返回按钮,或依赖UINavigationController 提供的边缘侧滑手势。测试iOS 时,必须逐一证实每个页面的返回按钮是不是可见、可点击,以及边缘侧滑返回是不是在预期区域内生效。在 React Native 等跨平台框架中,BackHandler 仅对Android和 tvOS 有效,iOS 完全不响应硬件返回事件。这意味着如果Android端依赖 BackHandler 实现了返回拦截/确定退出思路,iOS 端必须有一套独立的实现方案。
三、后台机制和生命周期
后台行为的差别直接影响中断测试和状态恢复测试的设计。
iOS 对后台执行有严格限制。第三方应用进入后台后,一般只有很短的执行窗口(约数秒到数十秒),之后会被系统挂起。如果应用在挂起期间内存压力升高,可能被系统静默结束,用户切回时应用会从冷启动状态恢复。WebView中的 JavaScript 内存状态在iOS后台挂起时一般可以保留。
Android 的后台管理则宽松但不可预测。应用可以声明后台Service不断运行,但在Doze方式、厂商省电方法(如小米、华为、OPPO 的激进后台清理)以及低内存条件下,后台进程随时可能被杀死。更重要的是,Android的WebView在应用被系统挂起时,内存中的 JS 状态可能丢失-开发者文档确定建议“将Android挂起视为应用冷启动”来处理。
测试:两端都需要包括“支付/上传/表单填写过程中应用被切到后台再返回”的场景,但预期行为不同。iOS 的重点是证实应用从挂起恢复后状态是不是一致;Android 的重点是证实应用被后台杀死后,重点数据是不是已持久化、重新打开时能否正确重建状态。中断测试应按风险分级-“支付过程中系统杀死应用”这类灾难性场景的优先级远高于“收到短信” 。
四、通知机制
推送通知的功能测试需要在两端分别设计用例。
传输通道不同:iOS使用APNs(Apple Push Notification service),Android 使用FCM(Firebase Cloud Messaging)。两者的 payload 结构、大小限制和消息类型语义不同。FCM的notification类型消息在应用后台时由系统直接展示,而data类型消息完全交给应用代码处理;iOS 的静默推送(content-available)则是 best-effort 投递,在低电量方式或后台刷新关闭时可能被延迟甚至丢弃。
Android 的通道(Channel)机制是独特测试点。从Android8.0 起,每条通知必须归属一个 Channel,Channel 的重要级别在创建时由应用指定且用户创建后无法修改应用侧的设定。测试需要证实:Channel 是不是正确创建、通知是不是在正确的 Channel 中展示、用户将 Channel 设为“静默”后应用的行为是不是合理。
通知权限处理也不同:iOS 的通知授权弹窗只能出现一次,用户拒绝后只能引导去设置中手动开启;Android 13+ 的通知运行时权限可以在应用内再次触发弹窗(如果用户之前未选择“不再询问”)。
五、数据存储和文件系统
跨平台应用如果涉及本地文件读写,两端的存储途径语义差别会导致测试用例无法简单复用。
iOS应用运行在严格沙盒中,可写目录主要是 Documents(用户数据,可被 iTunes/iCloud 备份)、Library/Caches(缓存,系统可清理)、tmp(临时文件)。Android 则有 Context.getFilesDir()(内部存储)、getExternalFilesDir()(外部存储中的应用专属目录,卸载时删除)、以及真正的共享外部存储(需权限)。同一个“持久化数据”的语义在两端的实际存储位置可能完全不同。
测试时需要分别测试:应用卸载重装后哪些数据应保留(iOS 的 Keychain 数据在卸载后仍保留,Android 的 SharedPreferences 随卸载清除)、系统清理缓存时应用是不是会出现数据不一致、以及应用在外部存储不可用(Android 外置存储弹出/只读)时的降级行为。
六、安装、升级和分发
Android 的侧载(sideload)能力使得安装测试需要额外包括:从非 Play 商店渠道安装、安装时权限授予、以及包括安装(升级)时签名一致性的证实。Android 还允许同一应用的不同版本共存(通过修改包名),这在测试环境切换中常用,但iOS不支持。
iOS 的安装受签名和 Provisioning Profile 严格约束。测试包的安装需要通过 TestFlight、Ad Hoc 分发或 Xcode 直接部署,每种方式对设备 UDID 和证书的要求不同。iOS 应用的升级测试需要特别重视:从旧版本升级后,Keychain 中的认证信息是不是保留、NSUserDefaults 中的数据结构变是不是导致崩溃。
App Store 审核方法的差别也会反向影响功能设计。如iOS对热更新有严格限制,Android 则相对宽松;iOS 的隐私标签要求应用在 App Store 页面确定披露数据收集类型,测试时需要证实实际行为和披露内容一致。
七、自动化测试工具和执行环境
测试工具的选择本身就是差别点。Android 有 Google 官方的 Espresso(UI 测试)和 UI Automator(跨应用测试),执行速度快、和Android系统深度集成;iOS有Apple 官方的XCUITest,和Xcode集成,但在测试执行的稳定性和API 丰富度上受到更多系统限制。Appium作为跨平台方案被广泛使用,但它对iOS的支持受限于Apple的自动化框架能力-如 Appium 在iOS上不支持长按(Long-click)和系统级 Back 操作,对Android则没有这些限制。
执行环境也不同:iOS 自动化测试只能在 macOS 上运行(需要 Xcode 和iOS模拟器/真机),Android测试可以在Windows、Linux或macOS上进行。在不断集成流水线中,这意味着iOS测试节点必须是 macOS 机器,成本更高。
模拟器/仿真器的能力边界不同:iOS模拟器无法接收真实推送通知,测试推送需要在真机上进行;Android仿真器如果使用Google APIs镜像,可以接收FCM推送。此外,iOS模拟器不支持某些硬件传感器(如蓝牙、部分摄像头功能),涉及这些功能的测试必须使用真机。
建议:iOS 和Android的功能测试差别可以归结为一句话-iOS 的约束是系统替你做了更多决定,Android 的约束是系统把更多决定留给了你,但厂商可能随时改变规则。测试方法上,两端可以共享业务思路层的用例,但系统交互层(权限、导航、后台、通知)的用例必须分别设计,不能简单复制。在设备包括上,iOS聚焦 2–3 个主流系统版本和约 40 款机型,Android则需要面对 10+ 系统版本和 1000+ 设备变体,碎片化程度决定了Android的兼容性测试成本远高于 iOS。