领略项目测试的艺术:从需求评审到测试执行的实战经验分享

162 阅读15分钟

业务测试是测试人员的基本功,想要有扎实的功底,除了不断地学习、实践,还需要阶段性地回顾、反思。在本文中,笔者总结自身项目测试的经验教训,与大家一起探讨日常业务测试中较为关键的3个环节,包括需求评审、用例设计及评审、以及测试执行。

需求评审

01

熟悉需求、确认测试范围和重点,是业务测试的第一关。下面,介绍一下我摸索出的一些方法和注意事项。

01

熟悉产品写出的需求

拿到需求,从头到尾读一遍,熟悉需求的同时,注意找出没有理解或有明确错误的内容。

♢ 模糊的逻辑;

♢ 不清晰的交互、难以理解的名词;

♢ 不一致的处理方式;

♢ ......

02

思考产品未写明的需求

除了产品明确写出的内容,我们还要反观文档,发掘其中未写明的需求。

■ 产品文档的遗漏

♢ 同类逻辑被省略;

♢ 边缘逻辑或场景被遗漏;

♢ 关联功能未说明;

♢ 性能要求缺失;

♢ ......

■ 隐性的需求

♢ 想要发现隐形的需求,需要我们在读通需求后,跳出文档,进行创造性地思考。

案例:

• 需求背景:实时数据展示页面,后台以5分钟为间隔,将过去5分钟的数据加工后存放到库里,每次刷新页面时,会展示库中最新加工后的数据;

• 隐形需求:前端如果没有操作,展示的数据不会随着时间更新。为了优化使用体验,前端可以设置一个定时器,每5分钟调用一次接口更新数据,保证有新数据产出时,即使不刷新页面,也会展示最新的数据;

03

明确测试范围、核心需求和边缘需求

■ 明确测试范围,避免case设计时出现遗漏。

♢ 特别是历史功能修复或优化的需求,容易出现关联场景遗漏的情况;

■ 明确核心需求和边缘需求,可以方便在后续case设计时恰当地分配精力,在测试执行过程中,也能更好地权衡问题跟进力度,有利于保障用户常用功能和关键功能;

♢ 除了需求中重点描述的关键功能之外,一些简短的需求点也可能是系统的重要功能。针对这类需求,也应当分配更多的时间、精力在case设计上,以保障功能的易用。

♢ 为了做好这一点,首先在熟悉需求后,要站在用户视角,留心思考。其次,还可以与产品多加沟通,明确用户常用功能。

案例:

• 需求背景:账户消费数据展示列表,用以给管理者展示账户的消费情况;

• 需求文档:文档将大量篇幅用于描述系统交互和指标计算逻辑,对于排序功能仅指出了需要排序的字段,无详细要求。

• 实际情况:管理者经常需要使用排序功能来查看关键信息,同时排序与其他组件的交互较为复杂,因此需要投入较多精力来设计用例。

04

注意事项

■ 尽快完成,留出缓冲时间

♢ 越早完成,越能避免研发实现偏差的情况发生;

■ 统一确认,减少沟通成本

♢ 分散确认增加沟通成本。统一确认有利于节省双方时间,尤其是对于产品同事同时跟进多个需求的情况下,统一跟进可以避免精力反复拉扯的情况发生;

■ 推进修改,持续优化需求

♢ 一旦确定了需求有模糊、缺失或错误,要罗列清楚、并积极推进修改。

♢ 为什么要落实需求的优化和修改呢?

• 首先,模糊的需求可能导致团队内部难以对齐,在项目后期带来返工延期,甚至是上线隐蔽问题的风险;

• 其次,有时会碰到研发同事严格按照需求文档实现系统功能的情况,口头达成的共识不可靠;

• 此外,后期需要回顾需求时,重新确认浪费时间;

用例设计与评审

02

01

用例设计的基本思路

①. 按照黑盒设计方法,分区、分类覆盖需求点。

■ 设计方法。主要包含:边界值、等价类、场景法、因果图、判定表等。

■ 功能分区。以一个最简单的功能列表为例,大致分区为:权限、查询、列表、导出等。

■ 用例分类。根据实际情况,可考虑以下几类用例:基础功能、易用、兼容、性能、安全、容错、冒烟、回归、线上验证等。

②. 依据分层测试思维,对用例进行检查,补全。

大致分层:前端、后端、中间件、数据库。

■ 前端:主要考虑界面及交互细节、接口调用等。

♢ 以接口调用为例,主要检查每个操作是否调用了正确的接口,是否多调或少调了某些接口。

案例:

• 需求:上面提到的实时数据展示页面,包含列表和饼图两个维度的统计数据,支持查看从当日零点到当前时间或整点时间的统计数据;

• 场景1:指定查看当前时间的数据,对列表进行排序操作;

• 测试点1:排序操作调用了列表的接口,使列表获取到了最新的数据,并依据最新的数据排序后展示。因为查看的是实时数据,为了保证两个模块数据的一致性,所以需要同步调用饼图的接口,更新饼图展示的数据;

• 场景2:指定查看整点时间的数据,对列表进行排序操作;

• 测试点2:排序操作调用了列表的接口,列表仅更新了排序的结果,本次调用和上次调用获取的数据并没有改变,所以不再需要同步调用饼图的接口更新数据。如果此时也调用了饼图的接口,那么会带来额外的性能压力;

■ 后端:主要考虑后端对业务逻辑的实现。

♢ 放在白盒测试部分介绍。

■ 中间件:主要考虑业务逻辑与中间件的结合。本文以消息队列为例:

常规用例:

• 上游消息的触发逻辑是否正确;

• 上游发送的消息体字段是否完整、正确;

• 上下游要求的字段格式是否一致(如上游传递格式为int32的字段,下游当做int8处理);

• 下游消息的处理逻辑是否正确;

进一步思考可补充的用例:

• 下游处理时是否做到了消息幂等;

• 判断幂等的逻辑是否合理;

• 是否有重发机制;

• 重发机制是否可正常使用等;

■ 数据库:主要考虑后端与数据库的交互和数据准确性。例如:

♢ 数据库操作有没有添加事务控制;

♢ 有新增字段时,字段的格式是否符合需求,是否有超长截断,或插入失败的风险等

③. 针对特殊场景、关联场景,进行用例的检查、补全。

■ 特殊场景。例如:

♢ 快速连续重复操作;

♢ 从内存中读写时是否需要加锁;

♢ 脚本间的执行顺序;

♢ 上下游执行操作的顺序等;

♢ 异常报警机制;

■ 关联场景。交互或逻辑复杂的系统,操作的影响范围广,需要考虑是否有关联的影响在case中没有体现。

④. 结合白盒设计方法精简用例,以及补充用例。

■ 设计方法:基本路径测试,逻辑覆盖等;

■ 精简用例。例如:

♢ 进行更加准确的等价类划分,删除掉冗余的等价类;

♢ 明确代码中逻辑判断的依据,不用再考虑关联因素的影响;

♢ 确认公共逻辑,不用重复测试抽离出的独立函数或接口。同时,如果多个功能存在相同的逻辑,但在代码中分别实现,这时要避免出现测试遗漏的情况;

■ 补充用例。阅读代码,检查是否存在遗漏的验证点,例如:

♢ 代码计算

• 是否可能出现算术溢出;

• 浮点数精度问题(如:1.23*100 != 123);

• 判断的逻辑是否合理、是否存在遗漏或多余等等(如:研发增加了需求中未提及的判断条件);

• 判断条件是否在各种情况下均可用(如:使用数据库中的字段A进行条件判断,但部分记录缺少字段A);

♢ 数据库操作

• 查询的表、字段是否正确;

• 联表的方式是否正确(如:应该用left join的位置,使用了inner join导致查询出的数据范围缩小);

• 新增数据库记录时,数据格式是否正确(需求:将浮点数四舍五入转为整数后入库。实现:把浮点数当作整数直接入库,导致小数部分被截断,仅实现了”四舍“,没实现”五入“);

♢ 其他

• 异常报警机制是否合理、完善(如:重要业务应当采用持续报警机制,而不是单次模式);

02

用例评审的工作项

用例评审时,除了常规的评审外,还可以做以下的工作:

• 针对三方未对齐的需求细节,自身对于需求的疑惑,在评审时进一步确认;

• 与研发探讨实现方式、变动范围,挖掘潜在的风险点;

• 了解可测性。针对常规方法不可测的内容,讨论是否有其他测试方式,并争取研发的合理协助,例如打印更清晰、全面的日志,单独编写专供测试使用的接口等;

• 明确产品期望的准出标准。判断是否有冗余的测试内容,或遗漏的测试内容;

• 确认排期。遇到排期超出预期的情况,可以考虑增加测试人员、提前提测部分内容、或延期部分需求;

测试执行

03

为了做好测试的具体执行工作,可以关注以下几点:

1

尽早找出关键问题

测试不可能发现全部的问题,在时间有限的情况下,测试工作最重要的意义是保障产品达到质量的底线,想要做好这一点,关键之一在于尽早找出系统中潜在的关键问题。

①. 尽早发现关键问题依赖合理的测试安排:

■ 恰当的测试安排:

♢ 测试准备。在正式测试之前,需要先做好测试前的准备。例如:

• 熟悉关联的业务逻辑,如上游造数流程;

• 熟悉测试用到的库、表;

• 准备好测试环境;

• 准备好测试数据;

♢ 冒烟测试。主要是准备好冒烟用例,提前提供给研发同事,并在提测后严格执行;

♢ 第一轮测试过程中,需要注意:

• 首先测试核心功能的核心场景,然后测试边缘功能及边缘场景;

• 这个过程中,对于发现的关键问题,随时与产研沟通;

• 对于模糊或边缘的细节问题做好记录,一轮结束,统一与产品确认是否有必要修改。

• 细节问题如果没有明确需求,不要依赖直觉判断,应当先与产品同事确认后再提bug,避免出现研发同事需要反复修改的情况。

♢ 第二轮测试过程,需要注意:

• 首先,整体回归,重点回顾一轮出现问题较多的功能;

• 之后,重新审视需求和case,检查验证是否有遗漏;

• 最后,还有时间的情况下,适当开展随机测试,可以发现一些想象力之外的问题;

■ 合理测试安排的达成并不是那么容易,实践中可能会出现下面的问题:

♢ 难以避免的个人习惯和偏好。例如:

• 严格按照case编写顺序进行测试;

• 习惯按照功能区域划分进行测试;

• 喜欢先测熟悉的模块,把陌生或者难以走通的case留到后面等;

♢ 边缘场景的遗漏。可能原因:

• 轻视边缘功能和场景;

• 时间精力不足,造成遗漏;

♢ 应对方案:

• 达成更加准确的测试估期;

• 分清主次,做好case执行记录;

• 养成好的测试习惯,安排每日测试计划时,依赖理性判断;

• 测试中期,要停下来想一想,有没有偏离原定的测试重点?测试重点有没有发生转移或需要矫正?

• 测试后期,要停下来想一想,核心功能是否已经得到保障?有没有出现越测越窄的情况?边缘功能有没有遗漏的发生?

②. 尽早发现关键问题还要利用好两个测试人员的优势:

■ 优势1:对于需求和实现的了解。

♢ 做好测试左移可以扩大这个优势,帮助我们更好地判断核心功能是否符合产品设计;

■ 优势2:对于潜在问题的敏锐度。

♢ 随着经验的积累,对于可能出现的问题能有更加及时、准确的判断。

2

更好地执行测试

实际的测试执行过程中,为了有较好的测试效果,我会注意以下几点:

■ 严格落实用例执行。

♢ 保障全部用例得到执行并通过,是最基础的工作内容;

■ 不断补充测试用例。

♢ 随着对被测系统和实现逻辑的了解加深,可能会发现一些遗漏的测试项,应当及时记录到用例当中,不要让灵感一闪而过;

■ 结合日志、代码开展测试。

♢ 测试前简单通读代码,测试过程中,结合具体的日志、代码,实现更加精准的测试。好处有:

• 结合日志信息,尽量定位具体问题,可以节省沟通成本;

• 查看研发对于问题的修复,判断问题原因和回归的范围;

• 开展推断式测试。以sql为例,针对待测逻辑,先按照自己的理解写一遍SQL,执行后与系统进行对比,在发现出入后,找到对应的日志和代码,观察研发如何取数,思考并跟进其中的差距。

■ 使用分层测试思维。

♢ 用例设计时已经采取了分层思维,执行时结合已有case进行拓展测试即可。例如,关注前端各种情况下的入参是否合理;

■ 采用脚本提效。

♢ 编写脚本可以帮助实现更好、更快的测试。项目中可以采用脚本提效的机会还是很多的,关键是具备编码能力,并及时意识到可以通过脚本更好地解决面临的问题。

3

写好bug描述

■ 为什么要写好bug描述?

♢ 好处1:一个好的bug描述,可以使得研发的工作效率更高;

♢ 好处2:bug描述是团队成员对我们工作印象的一大来源。好的bug描述,可以赢得更多信任,而这种信任又可以转化为支持和影响力。

■ 怎么写好bug描述?个人的经验教训有下面几点:

♢ 经验1:要确保提出的bug完整准确。想要认清一个问题的本质并不容易,不要在发现bug的第一时间就提交;

♢ 经验2:要包含必须的有效信息。测试数据,请求参数、接口返回,复现的关键步骤等等信息决定了研发是否能真正理解我们的bug。捕捉到问题的兴奋感或精力的过度消耗,有时会让我忘记填充足够的信息;

♢ 经验3:要提炼关键信息。有时候为了把问题描述全面,bug中记录了过多的信息,这样反而容易让研发捕捉不到关键信息;

♢ 经验4:更进一步,还要提升个人技术,争取提供更多定位上的帮助;

4

及时的风险预报

随着项目的推进,潜在的风险可能会逐渐显现,发现后我们需要足够警觉,尽快做出处理。可能的风险:

♢ case设计覆盖不全;

♢ 研发技术方案变更;

♢ 研发技术方案变更;

♢ 需求存在的遗漏或不合理;

♢ 种种情况导致的进度延迟;

♢ ......

结束语

在日常工作中,并没有固定的最佳实践。我们做出努力,只是为了在工作中碰到各种情况时,都能结合实际,找出更好的处理方式。

测试新人可以学习《测试人的 Python 工具书》书籍《性能测试 JMeter 实战》书籍