【功能测试】测试过程中如何提升测试质量
【功能测试】测试过程中如何提升测试质量
用例
一. 用例设计
1. 什么是好的测试用例?
我们举一个“池塘捕鱼”的例子,来理解什么是“好的”测试用例。
如果把被测试软件看作一个池塘,软件缺陷是池塘中的鱼,建立测试用例集的过程就像是在编织一张渔网。“好的”测试用例集就是一张能够覆盖整个池塘的大渔网,只要池塘里有鱼,这个大渔网就一定能把鱼给捞上来。如果渔网本身是完整的且合格的,但是捞不到鱼,就证明池塘中没有鱼,而渔网的好坏与池塘中是否有鱼无关。
-
定义
好的测试用例是一个完备的集合,它能覆盖所有等价类及各种边界值及边界条件,而与是否能发现缺陷无关。
-
好的测试用例的特征
- 整体完备性
- 等价类划分的准确性
- 保证所有可能的边界值和边界条件(包括各种极端情况和特殊场景,此类不是很少出现就不测试了,很多出现的问题都在此列)
2. 写出好的测试用例的前提是什么?
-
深入理解需求
写出好的测试用例的前提必须是深入的理解业务需求,只有真正的理解了业务的原始需求,才能从业务角度设计出针对性明确,从终端用户场景考虑的测试用例集。
测试虽然是最后一环,但不仅仅是只做执行者,对于需求的不明确和不理解都需要提出质疑,通过产品的解答和多方探讨,这样才能更加深入的了解需求及背景。
一些感悟: 1. 需求理解的 "记忆断层" 问题 需求及背景了解不深入的话,很难形成记忆,后续迭代测试过程中很容易产生漏测。【缺乏业务上下文支撑的记忆,本质是碎片化的信息堆砌】 2. 模糊需求的 "观察盲区" 风险 产品需求存在定义不明确的功能点或未明确的兼容问题,在测试过程通过现象来观察,发现的潜在问题未及时转化为为明确的需求,那么这个点在后续测试过程中很容易忽略掉。【未被系统化沉淀的临时认知】 不管产品需求还是技术设计,同理。
-
需要了解开发设计及表结构,其好处是什么?
产品思维,开发思维是不一样的,在开发过程中总是存在很多隐性需求。但是这些需求prd中不会呈现。
-
能更加深入的了解系统内部的交互,数据读取和存储过程。测试过程中更加具有针对性,减少漏测和重复测试。
-
提bug的时候能更加精准的定位bug产生的原因,并准确的对bug进行描述,从而提高开发修复bug的效率。
-
由于对bug产生的原因更加清楚,能更加精准的复现问题并快速的回归验证。避免了bug复现困难的或者不知道这个bug怎么产生的问题。
-
测试完成后,自己内心对质量也是有底气的,这个时候假设给你提出一个没有测试的场景,你可能已经知道这个场景的预期结果是什么了。这个是由于足够了解开发设计和内部实现的原因。
我的做法: 1. 大型项目一般有技术设计评审会议,测试会提前介入了解设计。【但是细节还需要找对应的开发了解】 2. 没有进行技术评审的需求,会在编码阶段找开发了解,并根据设计提出自己的疑问,防范于未然。 3. 根据需求及技术设计来编写用例。 4. 提测前用例评审。
-
-
应该站在不同的角度进行测试,如用户角度,测试角度,开发角度。最终目标必须是以用户为前提。
在了解开发设计和深入理解需求的前提下,还要站在用户的角度考虑问题,比如这样设计是否合理,作为用户是否会存在什么样疑问等。
3. 好的测试用例的设计方法是什么?
基本要求:
-
等价类划分法
-
边界值分析法
-
错误推断法(探索性测试):
定义:在执行测试过程中,也是在不断的学习被测系统,基于对被测软件的理解以及过往经验,直觉,同时结合自己的猜想和逻辑推理来推断软件可能存在的缺陷。
优点:能低成本的精准测试。
以此,可以根据以往经验建立缺陷检查表。
更高的要求:
(1)只有深入理解被测试软件的架构,才能设计出有的放矢的测试用例集,去发现系统边界以及系统集成上的潜在缺陷。作为测试工程师,切忌把整个被测系统看作一个大黑盒,必须对内部的架构有清楚的认识,比如,数据库连接方式、数据库的读写分离、消息中间件 Kafka 的配置、缓存系统的层级分布、第三方系统的集成等。
(2)必须深入理解被测软件的设计与实现细节,深入理解软件内部的处理逻辑。单单根据测试需求点设计的测试用例,只能覆盖“表面”的一层,往往会覆盖不到内部的处理流程、分支处理,而没有覆盖到的部分就可能出现测试遗漏。在具体实践中,测试人员可以通过代码覆盖率指标找出可能的测试遗漏点。同时,切忌以开发代码的实现为依据设计测试用例。因为开发代码实现的错误会导致测试用例也出错,所以应该根据原始需求设计测试用例。
(3)需要引入需求覆盖率和代码覆盖率来衡量测试执行的完备性,并以此为依据来找出遗漏的测试点。
作为测试人员,需要注意以下几点。
(1)需要明白,“好的”测试用例一定是一个完备的集合,它能够覆盖所有等价类以及各 种边界值,而能否发现软件缺陷并不是衡量测试用例好坏的标准。
(2)设计测试用例的方法有很多种,但综合运用等价类划分方法、边界值分析方法和错误推测方法,可以满足绝大多数软件测试用例设计的需求。
(3)在设计时,“好的”测试用例需要从软件功能需求出发,全面地、无遗漏地识别出测试需求。
(4)如果想设计一个“好的”测试用例,必须要深入理解被测软件的架构设计,深入理解软件内部的处理逻辑。
【引】《测试工程师全栈技术进阶与实践》茹炳晟
4. 测试策略,即测试的优先级是什么?
-
功能测试
- 主流程冒烟测试,首先保证主流程可用,防止有阻塞问题导致无法测试。
- 优先测试业务或代码复杂程度高的,以及需求点不是足够明确的或者出现争议讨论的点,往往最容易出问题。对于这些进行优先测试,好处是遇到问题能够提前暴露(中间可能存在未考虑的场景或方案重新设计等),防止问题过晚的暴露而延误工期。
- 服务层优先于页面,优先保证数据的业务逻辑正常。数据正常后,这个时候只需要关注不同的用户端即可。
缺点: 越是简单的越是容易漏掉。 用例设计的时候容易遗漏产品没有提及的且过于简单的。 有时候容易陷进复杂的逻辑里边持续验证,以求在复杂的逻辑里边发现更多的问题。 例如:质检重构(新增物品描述)需求 拍品获取质检模版的时候,仅仅给质检传了分类品牌,没有传系列导致获取的模版内容缺失。
-
兼容性测试
-
性能测试
二. 用例评审
-
统一理解
- 需求文档可能存在描述模糊的地方,评审阶段可以提前澄清,避免返工。
- 测试和开发可能会存在理解不一致的地方,提前发现能尽早避免因理解差异导致的问题。
-
用例查漏补缺,确定测试范围
站在开发的角度可能会提出更多细节的点需要验证,以及告知可能影响的范围。
-
精简用例,可以避免重复测试
根开发设计相关,但是对于测试工程师来说可能就是黑盒,用例设计会出现重复验证的情况,这个时候也可以部分了解开发设计。
三. 回归测试
-
为什么要回归?
-
技术再牛的测试也有未考虑到的点,可能考虑的问题比较深入,但是考虑的不一定全面,因此需要整体回归测试。
-
测试用例本身没有什么好坏,但是测试用例在编写和评审过程中难免有遗漏的点,测试用例集不一定完备。
-
-
回归需要划定回归范围
- 为了节省成本,基于代码变更的影响需要评估风险并缩小回归范围
- 重点业务流程全场景回归。
-
自动化支持
如果采用人工完全回归的方式,时间和人力成本过高。因此平时需要将核心业务加入到自动化中。
软件测试领域常见的一些理论
-
杀虫剂效应
-
本质:
测试人员按 “惯性思维” 执行测试,长期使用固有的测试用例,即使反复的执行,也很难发现新缺陷或变异缺陷。
-
场景:
- 长期使用固定的自动化测试脚本,未根据需求变更或代码修改更新用例。
- 手工测试人员依赖经验,反复执行相同的操作路径,忽略边界条件或异常场景。
-
避免方式:
- 探索性测试:不依赖预设用例,随机模拟用户操作,发现意外缺陷。
- 逆向测试:故意输入非法数据、中断网络连接等,验证系统容错性。
- 交叉测试:不同团队或人员交叉执行测试,避免 “惯性思维” 导致的漏测。
-
-
缺陷集群性效应
-
本质:
软件中的缺陷往往不是随机分布的,而是集中出现在少数高风险模块或代码区域,也就是常说的二八原则。
-
表现:
测试中常发现,在某个功能点首次发现缺陷后,深入测试该模块往往能挖掘出更多缺陷。
-
避免方式:
聚焦高风险模块,加强专项测试,对于功能设计复杂的模块出现的bug需要深度排查。
-
其他(以往具体测试经验分享)
1. 用例及时调整
- 不管在项目的什么阶段,用例都需要及时调整
- 测试过程也是对系统深入学习了解的过程,因此在对开发设计更加了解的情况下,用例也可能需要进行相应的调整
2. 数据安全方面
-
接口并发请求,模拟用户连续快速操作以及后端是否需要加锁处理
场景:订单重复支付,订单重复寄出等
实现:可以使用接口并发工具,如fiddler,charles,jmeter等工具
-
订单不同状态下,进行非该状态下操作,后端是否需要添加错误提示或者幂等
场景:如订单竞价中状态下操作寄出
实现:通过调用API实现
当然上边这个情况普通用户不可能操作到,如果时间紧的情况下仅考虑用户能操作到的场景即可,如交易完成时取消订单等。
-
分布式事物最终一致性
如一个对外接口里边同时调用了第三方接口并进行了数据存储,如果第三方接口失败,代码会怎么处理?
是否有重试或者调整实现方式来保证数据一致性等?
场景:下单完成后扣减库存
实现:可以让开发协助mock接口调用失败情况。
-
修改一些重要参数提交检查是否校验(接口数据与数据库不一致)
场景:类似于电商提交订单的时候,通过修改API金额参数后进行提交等。
实现:通过调用API实现
3. 快速提高测试效率
-
APP端数据mock
如果造数据繁琐而想要快速验证app的页面展示,可以使用fiddler,charles工具进行请求或响应拦截,并修改响应数据。
-
在了解开发设计及数据库的情况下,修改数据库数据达到快速验证的目的
-
通过接口自动化的方式快速造数据并测试对应的功能点
-
查看代码或者跟开发确认逻辑
如上边提到的订单不同状态下进行非该状态下操作问题,例如寄出状态是3,那么代码是否!=3的情况下直接报错提示,这个时候只需要看一个操作拦截即可。
最后
以上,虽然只是功能测试
过程中
如何提高软件质量的方式。
但是测试介入其实涵盖了项目的不同阶段。除此之外,还要养成业务逻辑整理的习惯,及时更新接口和UI自动化脚本进行辅助测试等等。
整个测试架构还包含更多,如代码覆盖率工具如JaCoCo,微服务模式的灰盒测试,性能与安全测试等等。
维度 | 测试左移 | 测试右移 |
---|---|---|
阶段 | 需求分析、设计、开发前期 | 部署、生产环境、用户使用阶段 |
核心目标 | 预防缺陷、降低早期风险 | 验证真实环境表现、优化体验 |
关键活动 | 需求评审、单元测试、静态分析 | 生产监控、性能测试、用户反馈 |