Files
knowledge-kit/Chapter1 - iOS/1.99.md
2022-03-24 09:28:13 +08:00

17 KiB
Raw Blame History

客户端质量把控

笔者结合中台经验,本文重点谈谈 App 的质量稳定性该如何做。业务作为 App 的核心服务之一,业务异常监控当然也很重要,这不是本文重点。

质量问题的现状

对于质量问题,直接以小故事的形式展开。下面是移动中台年度针对质量复盘的一些思考

  1. 技术方案阶体现测试用例 对于业务项目来说会存在测试资源、冒烟用例、精准测试、QA 新业务的业务回归、核心业务的 UI 自动化、高铁阶段的 QA 人工回归等。这里简单讲讲这些词语,对于新的业务项目,一定会有测试资源,简单说就是 QA新项目在经过 PRD、MRD、需求讨论会、Kick-off 之后,技术方案评审后,会经过测试用例评审,产出的结果就是用例指南,到时候 QA 会在用例平台指配给对应的开发。 敏捷开发思想下,业务需求跟车,而不是针对业务项目开车,每周一创建本周高铁,需求买票跟着上车。上车之前针对你的开发分支,会走精准测试,产出精准测试报告,分析测试报告,如果覆盖率比较低,需要分析是兜底代码太多,还是 QA 没有执行完全,针对后者你可以结合用例,是否有遗漏,然后去 push QA 再去回归。 针对不变的业务,沉淀出的自动化用例,会走 UI 自动化测试。期间线下性能监控会发现一些性能问题。每周值班 QA 会无差别回归业务。

但是啊,这些大多是针对业务,如果是基础 SDK 的能力和性能,大多是无法定位到问题的,所以针对技术 SDK 可能没有测试资源,需要中台开发者在 SDK 阶段,去思考基础 SDK 本身的核心用例,用例需要思考功能用例和性能用例,还需要思考一些开关情况、版本升级等问题。 所以第一个话题,主要是针对基础 SDK 来说的,不过业务项目,在技术方案阶段思考的不是测试用例,而是天网报警(业务异常埋点上报)、业埋点(核心数据)等

  1. 官方组件引入 BetterMR 经过约定:业务代码经过测试之后,才可以从个人分支合并到 dev 分支(注意 dev 分支不是市场分支release 分支是市场分支)。提交的 MR 必须至少 +2 后才可以合并。其中1个人是同技术栈的老司机另一个人是同项目的业务开发做到对齐。

代码质量直接关系到产品质量Code Review 是保证代码质量一个最显著可行的措施之一,而 BetterMR 是我们探索最佳 Code Review 的方式之一。

约定与建议 【约定】后续所有项目与日常均默认走 betterMR 流程,如果相对简单,可以申请不走 betterMR 流程; 【约定】MR 分级,默认为普通 MR在 24H 内完成 review提交者可选择为紧急 MR在 2H 内要完成 review 【约定】在后续规划中,架构师在工作分配上预留一定时间到 CR 上; 【约定】被 @ 的 reviewer 当自己手头忙碌无法 review 的情况下,可以选择在评论中 @ 一位 backup 替自己 review 【建议】紧急MR发出后请提 MR 的同学主动口头或企业微信联系和催促 reviewer 快速响应; 【建议】reviewer 手头忙碌时,可以先 +1 merge后续再 review 建议;

reviewer 数量与选择 约定与建议 【约定】每个 MR @ 到两位同学,其中包含该业务域的 owner以及另一位适合的同学熟悉业务或者熟悉代码 【约定】MR 不要 @ 超过两位同学;

小MR流程上是否可以更快一些 约定与建议 【约定】质量是核心问题,因此暂时所有走 betterMR 的项目和日常都坚持走 +2 的逻辑;直至我们的质量数据有显著好转,代表我们的质量意识有明显提升,再考虑轻量化; 【建议】提MR的同学和 reviewer 可以通过更有效的描述、注释、沟通来加速 review 流程,如 UI 部分更快速 review逻辑部分重点review 等;

MR的代码量与有效拆分 约定与建议 【约定】在技术评审与 kick-off 阶段对工作量进行MR任务的逻辑拆分业务域 owner 在这两个阶段进行把关,拆分的任务尽量粒度细化; 【约定】在一个 MR 中尽量将相关逻辑完整提交,有利于代码的整体 review 【约定】在技术评审阶段,业务域 owner 对技术方案与拆分做内审,提前熟悉改动面和设计细节,避免在 MR 提交的代码之外存在逻辑遗漏; 【建议】在保证子任务MR逻辑完整的前提下尽量约束每个 MR 的代码量,保证 review 效果;

  1. 业务 SDK 接入精准测试,产出报告必须分析 业务项目我在第一部分说明了会针对业务做哪些测试动作,在中台角度出发,思考业务中台(比如商品、消息)如何保证质量,也可以参考业务项目,接入精准测试,针对每一份测试报告,做进一步的分析,如果覆盖率比较低,需要分析是兜底代码太多,还是 QA 没有执行完全,针对后者你可以结合用例,是否有遗漏,然后去 push QA 再去回归。

技术中台负责的业务中台项目,也就是业务 SDK 也需要严格管控,否则就是业务异常,从而产生线上问题或者线上资损。

  1. 业务项目一定接入天网报警,基础 SDK 关键流程接入天网报警 App 质量与稳定性划分为:性能与质量稳定性、业务稳定性。业务不稳定了就很容易产生线上问题或者资损。针对业务异常,我们对线上问题归因做了一些梳理,一般可以分为: 方法或接口的参数数据类型不对、参数值不在合法区间、边界 case 没有覆盖、其他(历史遗留 bug、三方 SDK 升级导致、2端沟通不足需求没对齐 假如我们将第一二类问题解决好,线上问题将会显著改善。这正好就是天网报警的设计初衷,天网报警用于业务异常监控并报警。天网报警监控并不像 APM 一样是 SDK 去主动监控的,而是需要开发者自己在当前负责的模块、当前开发的项目、当前开发的日常迭代中去梳理关键业务流程和业务场景,对于一些可能存在的异常 case去埋点上报。

所以制定规范:业务项目一定要接入天网报警,基础 SDK 比如 IM、商品Socket 链接有问题,那么就是线上问题,肯定是业务异常。所以这样的关键环节一定要梳理并上报

  1. 新 SDK UT 覆盖率90%以上,老 SDK 基于 BDD 通过 基于资源有限的情况下,历史遗留的 SDK 可能无法去梳理并编写单测,那老的 SDK 可以去给予行为去编写 BDD 测试用例,这里不展开描述什么是 BDD 和怎么实践。针对新的 SDK 在技术方案阶段就需要思考好测试用例并体现出来,开发阶段 UT 覆盖率须大于90%。

  2. SDK 一定要 Lint 通过 这里的 lint 并不是针对语法、锁进等的 OCLint而是 pod lint。因为发生过一些情况就是 MR 提交后,去打包系统打包阶段, 因为 pod SDK 的问题导致的打包失败,所以 pod 的 lint 一定要通过,将问题提前解决掉。

  3. SDK Warning 清理 SDK 内部的 warning 尽量清理掉,比如 UIWebView 或者某个使用的 API 苹果标记为待废弃,假如你不按时修改掉,万一上线后用户使用的某个功能异常,那就 GG 了

  4. SDK 核心用例梳理,确保接入 App 集成测试 老的 SDK 梳理核心用例,便于 BDD 测试。SDK 的所有功能需要接入至少2个业务线 App 去验证功能和性能是否符合预期

  5. SDK Demo 必须体现开发能力,多端 Demo 对齐 SDK 的功能设计、类的 API 多端对齐,能力一致。且在 Demo 上可以体现出核心功能

  6. 脏乱差治理并优化 年底统计线上问题原因,经常会发现不管是业务线还是中台,都有一些遗留或者接手的线上问题,所以不管何种原因,都需要 Owner 意识,脏乱差梳理去修复问题

  7. 确保测试用例冒烟通过 QA 指派的测试用例一定要冒烟通过,冒烟打回很严重的,这是对质量的不认真,也是对 QA 工作的不尊重

  8. 关键功能有限老司机操刀开发,避免形成卡点(进度)或者影响质量,太忙的情况下至少老带新 核心业务功能,新人很难评估到所有影响面和边缘 case所以优先老司机操刀开发或者新人梳理评估出方案老司机 review 把关。避免因为不熟悉造成进度落后或者线上质量问题

  9. 基础 SDK 交叉测试 业务项目有 QA 资源,基础 SDK 不一定有测试资源需要开发者本身去思考测试用例包括功能和性能方面最后可以交叉测试Android、iOS 互测,确保质量。

SDK 质量 CheckList

  • ChangeLog、Podspec、Readme 完善

  • BetterMR +3 机制深入贯彻(一名角色为项目的另一端同学,另一名角色为本技术栈更资深的老司机)

  • 冒烟通过率100%(假如技术项目、日常优化可以交叉测试)

  • 精准测试以及精准测试报告分析。代码行覆盖率至少80%

  • 高铁包回归阶段UI 自动化点击页面发现性能APM与稳定性问题Crash、业务异常天网报警监控之前都是忽略未上线前高铁阶段的质量问题的提前感知问题提前修复减少线上问题

  • 业务 SDK 正式发布阶段,业务线接入升级时,工程师需充当 QA 角色,评估业务影响面,数据需要全面评估(新老版本兼容性、灰度策略),产出 SDK 性能测试报告和影响面报告

技术 SDK 质量 CheckList

  • ChangeLog、Podspec、Readme 完善SDK 发布必须 Lint 通过

  • BetterMR +3 机制深入贯彻(一名角色为项目的另一端同学,另一名角色为本技术栈更资深的老司机)

  • 新开的 SDK 必须写单测覆盖率90%以上

  • 对于存量 SDK 可以通过 BDD 补充测试用例,不如 APM 卡顿测试可以在10s内 Mock 3次卡顿。假设普通卡顿临界值为0.2s严重卡顿为1sANR为5s手动Mock3次卡顿分别为0.3s、2s、6s基于 BDD 我们可以对监控结果进行判断比如断言抓到3次卡顿其中2次严重卡顿、1次 ANR

  • 开发阶段必须关心性能:内存、电量、卡顿、网络。用 Instrucments 测试

  • 冒烟通过率100%(假如技术项目、日常优化可以交叉测试)

  • 高铁包回归阶段UI 自动化点击页面发现性能APM与稳定性问题Crash、业务异常天网报警监控之前都是忽略未上线前高铁阶段的质量问题的提前感知问题提前修复减少线上问题

  • 业务 SDK 正式发布阶段,业务线接入升级时,工程师需充当 QA 角色,评估业务影响面,数据需要全面评估(新老版本兼容性、灰度策略),产出 SDK 性能测试报告和影响面报告

SDK 测试方法

客户端SDK是为第三方开发者提供的软件开发工具包包括 SDK 接口、开发文档和 Demo 示例等。SDK 和应用之间的关系?以 IM 为例App 调用 IM SDK 接口。进行客服消息功能模块的接入,也包括消息 PUSH 功能的使用方。包括 Weex、JS 等资源的更新、商品数据更新 PUSH 后端上的感知能力、智能经营消息等。

客户端 SDK 测试的对象

客户端 SDK 测试,就是对提供给开发者的工具包里面的内容进行测试

因此测试的主要内容有:

  1. SDK 接口和文档
  • SDK 接口是测试的主要对象,也是核心的内容
  1. SDK 日志 对开发者来说SDK 接口里面的具体实现是透明的,当上层调用时遇到问题,只能依赖 SDK 打印的日志来定位分析。所以 SDK 日志是否完备,是否有助于解决问题,对应用开发者和 SDK 提供方来说都很重要

  2. Demo 或行业解决方案 Demo 测试可以看成是基于行为的测试。Demo 是SDK提供方用来示例如何调用接口实现具体的功能也可以作为开发者直观感受SDK接入效果。行业解决方案类似 Demo但是比 Demo 更加像一个产品,具有比较完整和典型的行业应用场景。可以让行业开发者比较明确知道,接入这个 SDK 做出来的产品效果如何。

  3. 其他周边 比如UIkit等可能只是在SDK开发中的附带输出但对有的开发者来说能极大降低接入成本

客户端SDK接口测试类型

客户端SDK根据需求和开发平台不同可能需要选择不同的测试类型对SDK接口进行测试

常见的测试类型有:

  1. 功能测试 保证 SDK 接口功能正确性和完备性。客户端 SDK 接口测试跟服务端接口测试类似,包括场景覆盖和接口参数覆盖 主要测试各种参数组合下的返回值,考虑数据是否缓存与存储,是否有回调,对于请求成功或失败都能按预期进行处理

  2. 性能测试 保证 SDK 接口满足特定的性能需求,比如资源占用、移动设备耗电量等。比如 APM 在卡顿定制抓取堆栈的时候会对设备有内存和 CPU 的影响,如果全量抓取一次堆栈会更加耗时,如果异步抓取主线程堆栈。实现不好,很有可能在发生卡顿的时候,由于 APM 实现不好,导致本来的卡顿变成了 OOM。所以测试时就需要考虑这个场景的性能

  3. 兼容性测试 保证 SDK 兼容特定的设备平台,并与其他软件兼容。兼容设备平台的工作量通常是比较大的,先根据产品需求和市场现状对需要适配的设备平台做分析,再根据需要覆盖的机型、系统版本、分辨率等进行优先覆盖排序 移动端 SDK 兼容性测试需要考虑下对模拟器的支持,因为很多开发者可能就是先在模拟器上开发。客户端 SDK 覆盖多平台设备的,还要考虑多端消息数据包的互通

  4. 稳定性测试 考察业务场景在一定压力下,持续运行一段时间,接口功能和设备资源占用有无异常。比如早期做 APM 时候,参考腾讯 Matrix 的代码,居然线上发生了 OOM最后二分法排查代码改动居然定位到了 CPU 利用率获取代码中,有 c 对象没有 free所以代码的稳定性也是需要测试去考虑和关注的。

  5. 网络相关测试 保证在不同网络类型不同网络环境下SDK 接口都能较好的处理。在涉及到多媒体资源或音视频通信,弱网下测试的需求较多,并且弱网下的处理通常需要反复优化和对比,不仅是新老版本效果对比,还包括竞品的效果对比测试

  6. 安全性测试 对隐私数据保护访问权限的控制用户服务鉴权等SDK 接口的安全性问题也是比较突出。安全性很多是在架构设计和开发设计中就考虑进去,但是最好还是有专门的安全性测试

上述诸多测试类型中功能测试先行。在进行客户端SDK测试前需要全面的了解测试对象的细节

  • 了解业务流程结合API接口文档和开发指南理顺接口的使用场景和调用关系
  • 了解 SDK 协议,理解协议中字段的意义以及服务器端的处理逻辑;
  • 了解各接口或协议返回码,分析对应的场景;
  • 了解开发实现细节,可以绘制成图,便于测试分析和分层验证。

对客户端 SDK 进行测试,可以采用的分层测试方式由上至下依次有:基于 Demo 和解决方案->基于接口调用->基于代码。

1、基于 Demo 和解决方案的测试 大多客户端SDK在提测时都会有对应的Demo或者解决方案提交给测试因此可以覆盖到该Demo或解决方案对应的接口或业务场景。而且测试人员可以比较直观的看到界面表现上手快所以在客户端SDK测试中比较常用也是比较有效的。

但这种测试方式的缺点也很多Demo对接口和业务场景覆盖比较有限对接口的输入输出参数不能全覆盖发现问题时定位复杂度增加。精心设计的Demo以及多解决方案的形式或许可以最大程度满足测试需要但是需要较大的Demo开发测试投入也使得问题暴露的时间大大滞后。基于Demo和解决方案的测试可以是手工的也可以是UI层自动化测试。

2、基于接口调用的自动化测试 基于接口调用的测试,包括对单个接口的测试,也包括业务场景的覆盖。这种测试方式直接有效,需要一定开发基础

比如 SDK Repo功能实现代码 + XCTest Case 代码),通过脚本同步 SDK 代码到测试 Repo主要包括SDK 功能实现代码 + XCTest Case 代码 + QA 的 XCTest 代码Special TestCase + Normal TestCase 其中,开发的测试 Case 走基础单元测试。QA 的 Special Test Case专项测试的测试 Case最小回归集等日常测试的测试 Case

基于接口调用的自动化测试需要有产品的思路、开发的知识和测试的思维做起来有难度。但是因为SDK接口通常比较稳定所以一旦实现并投入使用测试效率和质量的收益都很大值得拥有。

3、基于代码的单元测试 单元测试是为开发代码质量保驾护航的一个重要环节,在测试左移推进的道路上,大家越来越意识到单元测试的重要价值。特别是在一些核心业务上,值得开发同学投入精力去做。

其他测试类型的展开,跟应用层测试类似,就不再重复了。