不测的秘密-精准测试
精准测试的九大要素
精准测试作用范围
- 快速、适用;
- 测试对象:测试源程序,目标程序,数据和相关文档;
一、差异化
- 目的:破全面回归,在保持质量的前提下,少测试一些内容,从而提升效率;
- 要旨:需求差异要明了,技术实现差异要更明了;
- 质量差异:需求差异+开发技术实现的差异
需求差异
方法
- 功能流图:使用图形方式表示功能与功能之间的关系以及功能走向关系;
- 数据流向图(DFD):从数据传递和加工的角度,以图形方式表示系统额逻辑功能,数据在系统内部的逻辑流向和逻辑变换过程;
- 状态变迁图(STD):指明外部事件的结果系统将如何运作=>分析出差异的状态处在什么样的位置。对其他状态的影响是什么;
技术实现差异
系统设计上的差异
- 首先从系统设计上理解技术实现的差异,如系统应用架构设计的差异;差异分析是从系统整体的架构图中定位局部架构变化差异在什么地方;
- 对于单个模块的实现细节,逐步分析差异的能力;
- 时序图:通过描述对象之间发送消息的时间顺序,显示多个对象之间的动态协作关系;
工程上的差异
- 代码、文件的差异
实用分析方法
- git-diff;
- 文件对比方法:编译后的文件对比是相对比较困哪的。即使完全相同的源码。
- 可通过反汇编的基本块跳转关系的二进制对比;
二、技术治理
- 目的:破耦合。耦合影响内容不能漏测,也不能多测,快速分析出耦合影响,人工精准就基本达到了;
- 要旨:快速精准的分析耦合的影响;
耦合
- 耦合:是对软件结构内各个模块之间互连程度的度量.(架构:高内聚,低耦合是被推崇的)
耦合的类别
内容耦合
- 一个模块直接访问另一个模块的内部数据;
- 一个模块不通过正常入口转到另一个模块内部;
- 两个模块有一部分程序代码重叠;(只会在汇编中)
- 一个模块有多个入口
公共耦合
- 若一组模块都访问同一个公共数据环境。(全局数据结构共享的同一内存的公共覆盖区)
控制耦合、标记耦合、数据耦合、非直接耦合
解决耦合
- 梳理业务模块和公共模块的关系;
- 先关注模块间的边界,这个边界包括同步调用,异步消息和内容耦合;
- 技术治理是为了搞清楚改了什么,影响什么问题;技术治理是一种递进关系(系统内治理,系统外治理,数据间的治理)
摸清函数调用关系(Doxygen)
- 设计一个数据库,把代码的调用关系存到数据库中,在做一个网页,能展示和查询调用的拓扑关系图;
三、度量及分析闭环
- 目的:破差异化的度量,代码覆盖率不仅仅作为质量的一个度量维度,更可以作为测试分析精准与否的一个质量手段;
- 要旨:代码覆盖率分析结果是精准测试的重要依据
四、知识库
- 目的:破函数和用例映射
- 精准测分核心是分析变更函数及影响到的用例(含新增),如有一库在手,任何变更来了,都可以分析的又快又准;
- 要旨:函数和用例关系库建设;
- 输入:变更的代码;
- 用例预分析:知识库->查找比变更对应代码->函数对应用例
- 输出:推荐测试用例
- 一个用例的执行从代码层面来看,可以看做一个函数调用链;
- 如果能在执行的用例和对应的函数调用链上建立关联就可以了;
- 获取函数的调用关系,无疑需要插桩,现行主流的获取函数调用关系就是程序插桩。
- 在保证被测程序原有逻辑完整性的基础上,在程序中插入批量的探针。通过探针的执行并抛出程序运行的特征函数,通过对这些数据进行分析,可以获得程序的控制流和数据流信息(如函数调用链数据,从而是实现测试的目的;)
测试精准度
- 执行的测试用例覆盖了多少测试需求
代码覆盖率
概念
- 使用衡量代码覆盖程度的一种度量方式;
- 语句覆盖;
- 判定覆盖;
- 条件覆盖:完全条件覆盖不能保证完全的判定覆盖;
- 路径覆盖:毎一个分支是否都被执行到;所有可能都执行一遍,有多个分支嵌套时,需对多个分支进行排列组合;
- 有利的手段:增量代码覆盖;
分析闭环
- 测试分析: 通过差异化的测试分析得到测试范围集合;
- 测试执行: 手工执行用例;
- 代码覆盖率统计: 工具自动收集;
- 覆盖率结果分析: 需要人工分析;
- 反馈调整;
分析代码覆盖率
不计入的代码覆盖率的类别
- try,catch类;
- 日志类;
- 空指针判断;
- 其他风险可控的不覆盖类型;(预埋逻辑:本次没有任何功能表现,只是为了长远考虑预埋的代码逻辑;冗余代码:历史遗留的冗余代码,没有任何功能可以进入;尚未使用的公共代码)
代码覆盖率工具原理
- 本质上来说时一个调试器,通过和被采集进程加挑选会话进行插扩和覆盖数据采集;
差异提测计算方法
- 跨版本覆盖结果合并;
- 覆盖率 = 覆盖行/有效行
- 合并覆盖率 = (平移覆盖U档次覆盖行)/有效行
五、用例预分析
- 目的:破人工分析变更影响用例,变更函数有了,知识库有了,自动分析影响用例还远吗;
- 要旨:函数变更自动分析出影响用例;
- 用例预分析系统应该是根据版本变更自动分析出需要验证的用例,推荐给用户,除了功能用例以外还包括性能、稳定性用例。
- 核心价值:用例分析和调度;
六、知识库优化
- 目的:破函数用例关联冗余,同一个函数内覆盖相同分支路径的用例去重;
- 要旨:函数和用例关系,细化到函数内分支级别;
- 不需要将该分支的重复用例都覆盖到;
- 不重复用例分为:1.用例和函数的某一分支对应,但当前分支的代码改动后,用例与这个修改函数分支关系已经无效,这部分用例应该删除;2.函数改动后,和其改动分支对应的测试用例任然有效且必须执行,才是应该与函数关联的。当函数改动时,这一类用例被推荐出来,这才是进准用例;
七、用例分析消振
- 目的:破推荐影响用例冗余,变更分析也细化到分支级别;
- 要旨:差异化分析细化到函数分支级别;
八、精准执行手段
- 目的:破系统应用,精准测分系统完成后,人工和自动化的配合;
- 要旨:人工和自动的取舍;
九、质量评估
- 目的:破精准之后的质量评估,从“你决定发不发”的角度,来全面阐述质量评估维度;
- 要旨:决策侧重;
测试覆盖的评估
- 对需求的覆盖:测试已覆盖的功能点+性能点/所有功能点+性能点;
产品版本发布标准
- 需求变更率:需求变更数/总需求数
- 需求提测延期率:提测延期需求数/总需求数;
- 交付测试通过率:需求测试通过测试数/需求提测总次数;
- 测试计划执行完成度:是否所有测试都按计划执行了;
- 测试实际投入偏差:计划的测试投入是否得到保障;
- 缺陷密度:缺陷数/变更代码行数:需求缺陷密度=需求数/变更代码行数;
- 不同的需求、不同的时间要求,不同的测试参与阶段;
单个测分的思路
- 什么类型的需求:独处需要精准测分的粒度要多大;
- 新需求:可能技术方案难易程度;需求变更风险大小;
- 增量需求:技术变更影响大小;可供快速测分参考的工具或资料是否完善;
- 假设:新需求->测试保证层;
- 项目对测试时长的期望->测试阶段->测试独占时长(开始:最后一个人需求提测时间;结束:测试报告发出时间)
Case: C;(黑盒用例数)
Time: N;(黑盒用例在测试独占时长内的回归次数N)
k: 每个bug的回归时间;
BugNum:单个黑盒用例执行时间;
测试独占时长=单个黑盒测试时长/黑盒测试总人数=(CaseNumb * N * 5 + BugNum * K)/PersonNum = (C*N*5+B*3)/P
如何降低测试是时长
根据公式(C*N*5+B*3)/P
如何降低我们的测试独占时长?
- 降低C=>黑盒用例数;
- 精准测分来缩减测试内容;
- 白盒测试手段;
- 开发阶段内,测试库-执行一部分黑盒用例
- 降低N=>黑盒独占时长内的回归次数;
- 精准测分来降低回归次数;
- 设计稳定可靠的自动化来降低;
- 降低B=>测试独占时长内为解决的bug数
- 可通过白盒测试手段来达到在开发阶段发现问题,从而减少测试独占时长的bug数;
- 更早得加入测试;
- K值降低=>回归时间
- 测试参与越早,测试占时长越短;
- 引入精准测分,测试独占时长可大幅度缩短;
- 精准测分平台,可帮助节省测试人员测分时长;
有关团队测分能力提升的破解思路
现状
- 100%黑盒业务测试;
人工精准测分阶段
- 80%日常
- 20%进行测分建设和提升;
- 拿到代码权限,可以开展代码测分;
- 分析出整个团队所有代码编译出来的所有模块全景图;
- 根据业务变更优先级,来排这些模块的优先级,对模块进行层次的梳理。得出该模块的整体架构。分功能的代码实现,核心逻辑实现;
- 增量需求的变更代码测分;
精准测分平台建设阶段
- 60%日常
- 30%测分
- 10%平台建设
高效团队阶段
- 40%日常
- 40%测分
- 20%平台建设
自动化测试的价值
传统自动化测试的价值
- 提高效率,缩短测试工作时间;
- 自动化与人工对比比较稳定;
- 加大测试回归力度,提升测试覆盖率;
- 可以执行,重复性;
传统自动化测试(ROI) => 成本与收益
- 自动化的收益=迭代次数全手动执行成本-首次自动化成本-维护次数维护成本 假设迭代次数和维护次数近似相等
- 自动化的收益=迭代次数*(全手动执行成本-维护成本)-首次自动化成本
- 传统的自动化测试=>测试过程被自动化(手工测试让机器去做)
广义的自动化测试
- 测试环境的搭建和管理;
- 测试环境的检查、监控和报警;
- 测试代码的静态检查,编译和构建;
- 测试场景的构建,测试数据的自动化准备;
- 测试用例的分发和执行;
- 测试结果的保存和管理;
- 测试报告的生成;
- 测试优先级的建议;
自动化测试类型
- 单元测试;
- 静态代码检查,文件检查,签名校验,证书检查;
- 接口自动化测试(本地接口,服务端接口);
- UI自动化
- 性能测试(本地,服务端)
自动化测试价值
- 帮助回归、节省人力;
- 构建人工测试无法构建的场景。数据准备或执行一些人工测试做不到的测试用例,有效提升测试覆盖率;
- 前置测试,让测试和开发又可能并行,提升项目敏捷度,降低测试独占时间;
方向
- 如何缩减回归测试的范围;
- 如何让不能测得用例变得能测,进而如何让自动化测试发挥最大价值;
- 测试独占周期(提测=>发布)
- 测试覆盖率:测试执行的用例总数/所有用例总数(需要真正被执行的总数)
测试方法
白盒测试-架构,设计,实现
- 语句覆盖:程序每一条语句至少执行一次;
- 分支覆盖或判断覆盖:程序中毎一个分支至少走查一次,即每一条分支语句的true/false的情况都要执行一次;
- 条件覆盖:当判定中含有多个条件时,要求每个条件的取值均得到检验;
- 判断/条件覆盖:同时考虑条件的组合及判断结果的检验;
- 路径覆盖:使程序运行所有可能的执行路径;
黑盒测试-需求,用户
- 等价类;
- 边界值;
- 场景分析;
- 因果图;
- 判定表;
- 错误推测;
- 正交试验设计;
- 功能图;
测试分析
- 定义:建立在对需求本身及对应的系统架构和实现细节的充分了解的基础上,通过对数据流,状态变化,逻辑时序,功能/性能/兼容性等方面进行分析,得到详细的测试关注点的过程;
- 测试分析=>修改的代码=>测试范围=>时间和效率的提升
全面认识测试分析
基于需求的测试分析
- 即对需求进行分解,考虑需求本身,以影响的功能模块=>规划处测试范围;
分析基础
- 对业务的熟悉;
- 对用户使用场景的了解;
- 产品功能矩阵;
分析方法
- 业务流程分析:描述业务的正向流程;
- 业务状态分析:描述业务对象的状态转换;
- 测试范围分析:需求本身的功能模块/受影响的功能以及模块;
基于开发实现的测试分析
- 理清用户需求/需求价值方向:分析者对于需求要解决什么问题有清晰的认识;在测试策略和测试关注点方面做出正确的判断;
- 清理架构/实现的细节:所有的需求经过理解转换为代码,代码的实现架构、实现的细节就是产品上面的提现,最后专为测试效率与质量上的提升;
分析测试关注点(界定内容,影响点)
功能测试详细分析
- 涉及模块(文件);
- 模块交互时序;
- 模块/类/函数涉及;
- 实现细节;
性能测试详细分析
基于系统资源的性能测试分析
- 性能测试相关点;
- 开发相关实现细节;
- 关键指标;
- 性能测试场景设计或已有的相关测试用例;
- 性能测试脚本设计;
- 基于相应时间的性能测试分析
接口测试分析
- 是否具备可测接口,需要描述清楚为什么要测以及测那些;
- 接口测试覆盖的接口定义描述
- 接口内部实现的相关逻辑细节;
- 接口测试设计的实现方案;
- 本次功能需求,是否有接口变更,分析变更影响范围及测试内容;
- 变更接口修改实现的相关逻辑细节;
- 变更接口(函数)对模块内功能影响分析;
- 变更接口(函数)对模块外功能影响分析;
稳定性测试分析
- 稳定性测试场景设计(用例)
- 稳定性测试脚本设计
兼容性测试分析
- 兼容性相关点;
- 开发相关实现细节;
- 兼容性场景涉及,测试环境说明(实验室或众测)
(Miao注:干货太多,每隔一段时间内看要点,都有新的领悟,工作上也给与了很大的帮助)