0 业务
骑行服务业务的四个领域
- 用户流程体验:找还用,首页/红条/面板,结费页等
- 用户开关锁体验:开关锁链路,状态机,骑行安全等
- 用户骑行合规:合规引导,合规判定,策略管理等
- 用户基础服务:骑行账号维护,用户协议,第三方账号打通等
1 需求评审
- 业务性需求:关注业务场景和功能实现,预估改动后的场景通过手工用例和自动化用例能否实现全覆盖。
- 技术性需求:关注技术性架构的变化,协助开发人员定制自测解决方案,预估存量自动化用例覆盖范围,查漏补缺。
2 技术评审
1 技术方案本身实现的合理性,是否覆盖了产品文档中所有的需求点,是否保证了各种边界条件和异常处理兜底策略等 2 熟悉现有架构的前提下,对技术方案提出适当的改进建议。 3 对技术方案进行针对性的用例可行性。当前用例需要补充什么才能覆盖技术方案的全部。
比如在一次功能测试中,测试完发现覆盖率不达标,看代码发现为校园车的逻辑进行单独处理,增卡方案中,普通单车和校园单车的逻辑不同。
3 用例评审
用例需要结合产品文档和技术方案
- 产品文档用于了解改需求所涉及的业务场景,用例是否对应到了具体的需求点,包括一些边缘场景也要注意涉及。
- 技术方案用于在测试过程中观测用例执行所调用的服务接口是否符合预期,前端传参和后端返参是否符合预期(appmock);以及所有的用例是否能够完整的覆盖代码。
- 同时考虑用例是否自动化,是否有相应标记,是否关联了自动化脚本,是否需要编写新的自动化用例。
写完用例测试之前需要根据技术文档和自己的用例大体看一下提测单里给出的流程和代码符不符合,用例有没有覆盖此次的变更代码。
-
自动化测试目的。自动化测试往往用于上线前的门禁。门禁包括此次需求的用例和从前的用例,确保能够在实现此次功能的前提下也不影响曾经的功能。
-
手工测试则是能够更直观的看到测试过程,包括抓包看到接口,或者mock数据等。同时根据实际灵活性的改变测试路径,能够更好的从用户角度观测需求的实现。
在一次蓝牙引导的线上回归测试中,由于软锁不能正常开锁,因此需要用到真锁。组内真锁的锁型为2G通信强网,功能中只有弱网才能够命中蓝牙引导开锁。在测试环境中已经确认整体前期流程没有问题,但是由于蓝牙原因不能开锁,回归测试的重点在能否开锁。最后采用mock后端的返回结果给前端,确认能够正常开锁。
4 提测 + 功能测试
研发开发自测完成之后,会触发流水线在提测泳道部署服务同时执行自动化测试,如果失败用例过多且拦截到缺陷,qa同学可以考虑提测打回,确认无误后可流转到冒烟通过。
测试设计
- 测试范围:测试范围描述的是被测对象以及主要的测试内容,需要明确“测什么”和“不测什么”。 测试范围的确定通常是在测试需求分析完成后进行,所以确定测试范围的过程在一定程度上也是对测试需求分析的进一步检验,这将有助于在早期阶段就发现潜在的测试遗漏。同时,由于不可能进行穷尽测试,而且测试的时间和资源都是有限的,所以必须有所取舍,进行有针对性的测试。
- 测试策略:测试策略需要明确“先测什么后测什么”和“如何来测”这两个问题。 测试策略要求明确测试的重点,各项测试的先后顺序,以及采用什么样的测试类型和测试方法。 test,stage,prod环境,手工测试和自动化测试。
- 测试资源:测试资源需要明确“谁来测”和“在哪里测”这两个问题。
- 测试排期:测试排期主要描述各类测试活动的开始时间、所需工作量、预计完成时间,并以此为依据来建议最终产品的上线发布时间。
- 测试风险预估:预估整个测试过程中可能存在的潜在风险,以及当这些风险发生时的应对策略。
5 st测试
功能测试位于测试环境。st测试位于stage环境,stage环境和线上环境共用同一套数据库,测试环境的数据则是单独的,stage环境更接近于线上。
6 上线 + 回归测试 + 覆盖率
上线前需要观测覆盖率,也就是测试过程中是否覆盖到了开发此次的新增代码。 上线之后需进行回归测试,再次观测各项数据指标是否正常,然后放量。
7 bug
bug类型,排查过程,缺陷原因和影响范围。 注意排查过程中需要注意缺陷的复现,追踪缺陷产生的成因。至少通过查询日志,查看代码等方式分析问题原因,减少沟通成本,最好能给出推荐解法。同时,阅读代码可以完善测试点。
功能类bug 技术型bug 在测试单车包时卡需求时,根据提测单测试发现结果始终达不到预期,先查看日志发现没有返回期望的参数没有走到流程,在确认各方面都无误的情况下;然后再查看代码中的流程发现提测单上的提测流程存在问题,在两种场景中对应lion配置和实验对应有误,联系研发同学予以修正。
需求类bug 双蓝牙开锁需求中,因为增加了蓝牙引导,在增加的弹窗中存在去开启蓝牙的引导按钮,看接口中该接口返回的但是按了之后不会返回当前界面而是直接退出,从用户角度上不符合常规逻辑,前端予以修正。
8 自动化测试
自动化测试框架mobike-api-test
骑行服务端自动化测试框架基于python unittesy进行开发扩展,主要分为四层:
- 基础层:封装基础组件,比如http,thrift,squirrel缓存等
- 业务层:封装业务基础组件,比如不同车型的软锁,新用户,订单的增删改查,开关锁,结费页等
- 用例层:每次需求的具体用例。
- 工具层:封装提效类工具,比如自动化门禁多进程执行等。
一般编写自动化用例时需要观测各个接口的数据是否符合预期,在不符合日期时通过traceid查日志看其中的过程哪步导致的问题去解决。
自动化测试遵循DRP原则
即deterministic稳定,rapid快速,pricise feedback精确反馈三点。这三个原则是基于测试活动的本源出发而提出的,即测试的重要目的,是向产品负责方提供全方位的质量信息。那么,此类信息首先应该稳定,才具有可信度;其次信息产出过程要快速,才有效率;最后信息的呈现要精确,才更有利于进一步分析评判以及修复迭代。
在整个需求流程中,持续交付(CD)的难点在于持续集成(CI),持续集成的关键在于可持续运行的自动化测试,而只有高质量的自动化测试才可持续运行。
在整个测试过程中,自动化测试与探索性(手工)测试都属于测试方法,互为补充,而非互相替代。
- 自动化测试能够「积累」测试工作,包括经验与知识。软件产品的功能或者系统的程序代码,是很容易堆积的,然而手工测试不能,它依赖的是测试人员的自身经验与能力。自动化测试可以使部分测试工作以可执行程序的形式被留存下来,得以在后续迭代中持续更新,也可以在同一迭代中转移。
- 自动化测试能够提升测试深度。一方面,自动化测试能够构造更为复杂的测试场景:高并发输入、长时间不间歇运行、遍历所有入参组合、检测不可见输出信息,这些在手工测试中无法做到的事情,在自动化测试中可以达成。配合可测性改造,自动化测试带来了极大的发挥空间;另一方面,在创建自动化测试的工作中,测试人员必须将一个场景及校验以计算机程序描述出来,这促使测试人员更加深入地理解被测系统。
- 自动化测试可以被随时运行。这使得已有的检查能够被更频繁地执行,更前置地暴露风险,这远比后置地去替代手工回归要更加有意义。
同时,我们也要看清楚自动化测试的局限:
- 大多数的问题,都发生在具有代码改动的模块中,发生在新加入的功能之中。高度可重复的自动化测试,实际上在暴露重要缺陷上并不占优势。在一个正常功能迭代的稳定的软件产品中,我们应适度控制对自动化测试能发现问题的预期(如果不将在开发自动化测试过程中发现的缺陷计算在内)。
- 自动化测试或多或少影响到测试的真实性。自动化的测试总是会有别于真实用户的使用,我们应该看到这一点,并在测试策略中有意识地补足,而不是想要徒劳地消除这种区别。
- 自动化测试无法评估用户体验。产品的最终使用者是人,「好不好用」这个极难量化的评判最终是由活生生的用户来决定的,而一个自动化测试场景是否通过是由不具备人类审美观的程序判断的。
在某次编写用例时,发现运行不稳定。查看日志发现由于用的是同一车辆,同时蓝牙不能开锁,因此第二次运行时该车辆还在位于开锁阶段导致开锁失败。解决方案有两种,一是强制开锁,二是每次使用随机车辆,lion中为车辆增加配置,在结束后删除。最终采取2更稳定。后来运行发现依旧失败,查日志发现由于lion配置后存在会有2秒的生效时间,等待两秒后成功。
自动化门禁概要
- 前置检查阶段:生成任务id,看泳道服务是部署,testx是否能够录制
- 任务准备阶段:执行需求相关的自动化用例,用例编排
- 用例执行阶段:加载执行用例
- 后处理阶段:生成测试结果
在实习中,我主要编写的是骑行服务端自动化用例,包括新需求上线前的核心流程(如用户开锁、关锁、结费)、边缘场景(如弱网状态下蓝牙开锁)以及部分接口的异常情况。 这里的难点主要有两个:一是线上和测试环境不一致导致用例不稳定,比如测试环境的真锁类型与线上实际弱网场景不同;二是部分流程需要依赖复杂配置(如校园车与普通单车的增卡流程逻辑差异),需要在用例里做动态数据准备与清理。
文档中提到「用例评审需要结合产品文档和技术方案」这部分,我的做法是先根据产品文档梳理需求点和业务流程,然后结合技术方案关注关键接口和配置点,比如提测单里有一次需求涉及校园车单独逻辑,我就结合代码发现原用例只覆盖了普通单车,通过代码走读发现遗漏了校园车场景,用例里及时补充了这部分。
对于提测单流程或实验配置出错,我一般先查提测单的配置和接口日志,确认参数有没有正确传到后端;再直接看代码里条件分支,比如实验白名单或配置项,如果发现和提测单不一致,就第一时间同步研发,并明确指出是哪一行或哪个配置需要调整,让研发可以快速定位。文档里这里其实写得偏笼统,可以加上自己是怎么查的、怎么沟通的,让面试官更有画面感。
关于自动化测试 DRP 原则(稳定、快速、精确反馈),我们团队是通过多进程执行和mock接口返回来保证快速,通过跑固定数据集保证稳定,通过traceid日志校验来实现精确反馈。比如有一次发现同一辆车连续开锁导致失败,我就改为用随机选车并增加延时,让结果更稳定,这部分文档里提到了,但可以更突出是我自己发现问题和解决的。
mock 后端返回结果时,我用的是自研的appmock服务,可以在需求测试时注入预期返回值,比如在弱网开锁场景里mock后端返回「弱网」状态,让前端走到蓝牙开锁引导,这样能避免真锁测试受网络限制。
上线后观测覆盖率,团队是接入了SonarQube和自研的覆盖率采集工具,在提测和上线前的自动化流程里跑完用例后自动出覆盖率报告,我主要负责看报告里本次需求的新增代码是否被覆盖,也会结合diff看具体哪些逻辑没被覆盖并补充用例。
最后,我自己觉得自动化测试和探索性测试是互补的:自动化更适合回归和高频、稳定场景,比如核心开关锁流程,能持续积累;而探索性测试能在新需求上线前找出交互、异常流程或配置问题,比如mock+抓包去验证用户体验和异常场景,这是自动化替代不了的。文档里虽然写了自动化和手工互补,但可以更强调是我具体做了什么探索性测试,而不是停留在理论。