软件测试学习笔记
定义
在规定的条件下对程序进行操作,以发现程序错误,衡量软件质量,并对其是否能满足设计要求进行评估的过程。
测试就是发现错误而执行程序的过程。
原则
- 保证测试的覆盖度,但是穷举测试是不可能的。
- 所有的测试都应该追溯到用户。
- 越早测越好,测试过程与开发过程应该是互相结合的。
- 测试的规模 从小到大,从单元测试到系统测试。
- 不能为了便于测试而擅自修改程序。
- 既应该测试软件能做什么,也应该测试软件不能做什么。
度量
- 测试覆盖率
- 缺陷发现率
- 测试成功率(或者说用例通过率)
测试做到什么程度并没有一个固定答案。只要满足两个显式条件和一个隐含条件就要一直进行。
显式条件:
- 项目风险
- 项目经费
隐含条件:
- 老板们从当前的测试结果已经获得了足够的信心,或者彻底摧毁了信心。只要他们还在犹豫咱就得继续干活。
测试的原则🌟
测试只是展示缺陷
测试只能表明缺陷存在,却不能证明没有缺陷。测试能降低未发现缺陷留存的概率,却 不能证明软件是绝对正确的。 正如某些数学命题,你可以穷举 1-n,证明其正确,却依然无法证明对于 n+1 仍然正确。
**穷尽测试是不可能的**测试所有的输入和条件组合是不可能的,除非是极其简单的情况。可以取而代之的是基 于风险和优先级的测试。 当不懂装懂的老板要求你彻底测试一个软件的时候,这是你反驳的最好支持,当然要说 的委婉一点。
早期测试
要较早发现缺陷,就要在软件周期尽可能早的时候开始测试,而且要专注于已定义的测 试目标。 尽早开始测试!这句话估计早就把大家的耳朵磨起茧了。为什么要早?因为越早发现问 题,解决的代价就越小。
缺陷簇生
要对缺陷发现率高的模块投入更多的测试。少量的模块往往隐藏了大部分的缺陷。 这不仅仅是所谓的物以类聚。缺陷发现率高的模块往往于需求不清,设计不当,编码复 杂度高等内在原因关联,所以从风险的角度来看必然较高,多花些时间绝对值得。
杀虫剂悖论
相同的测试再重复多次后就无法再找到缺陷了。要克服“杀虫剂悖论”,测试用例要不断评审修改,不断添加新的和不同的测试,就有可能找到更多缺陷。 随着对系统的加深理解,必然会有更多的测试用例产生。另外缺陷本身也是新用例的很 好来源。
测试是上下文相关的
测试在不同上下文环境中的执行是不同的。比方说 安全关键系统 (safety critical system)和电子商务网站的测试方法就有很大不同。 这个原理相对难理解。这里其实强调的是不能用相同的态度和手段来测试不同类型的系 统。安全关键系统的概念要到高级大纲中才出现,指的是对系统安全要求苛刻的系统, 较之一般的电子商务系统的测试要求更为严苛。
无错谬论
假如建立的系统不稳定或不能满足用户需要和期望,那么发现和修复缺陷就毫无帮助了。 缺陷数量往往用来评估某软件的质量,但要是系统本身背离了用户要求,那就算缺陷再 少也没用,因为没有人会去用它。所以测试时要注意验证(verification)和确认(validation)的区别。需求规格说明和其他文档只是需求的不完全载体。文字说明必然有遗漏和偏差, 而各人的理解更有可能出错。要不断通过各种途径保证所生产的的确就是用户需要的。 常用的方式就是邀请领域专家或用户尽可能多地参与到开发活动来,特别是需求评审和 演示(Demo)。
测试的标准
- 测试的标准是用户的需求。
所有的软件测试都应该追溯用户的需求,测试人员要始终站在用户的角度去看问题、去判断的软件缺陷的影响,系统最严重的错误是那些导致程序无法满足用户需求的缺陷。
测试主要步骤
- 计划与控制
- 分析与设计
- 实施与执行
- 评估出口准则和报告
- 测试结束活动
测试流程
- 熟悉产品/项目
- 需求评审
- 测试需求
- 测试计划
- 测试用例
- 预测试
- 第一轮测试
- 第二轮回归测试
- 第三轮测试
- 测试报告
- 测试总结
为什么要避免测试自己的程序?
由于心理因素,人们潜意识都不希望找到自己的错误。基于这种思维定势,人们难于发现自己的错误。
软件测试的要素
- 质量:
软件质量是软件测试的目标,也是软件测试工作的中心,一切从质量出发,也就是一切从客户需求出发。任何违背质量的东西都是问题,测试就是要找出这些问题。
- 人员:
人是决定的因素,测试人员的态度、素质、能力决定着测试的效果,对测试产品的质量也有很大的影响。测试人员因素包括测试组织结构、角色和责任的定义。
- 技术:
软件测试技术,包括方法、工具。
- 资源:
主要是指测试环境中所需要的硬件设备、网络环境,甚至包括测试数据。另外一个重要因素就是测试时间,时间也是测试的资源,但测试人员不能看做资源,每个人的能力千差万别,不同的测试人员担任不同的角色,不能相互代替。这也是软件图书的经典之作——《人件》的作者反对将人作为资源对待的原因。
- 流程:
从测试计划和测试用例的创建、评审到测试的执行、报告,设定每个阶段的进出标准。
软件质量
软件产品质量评价国际标准ISO 14598
把软件质量定义为:软件特性的总和,软件满足规定或潜在用户需求的能力。上述定义反应如下3个方面的问题:
- 软件需求是度量软件质量的标准;
- 软件人员必须遵循软件过程过程的规范;
- 如果软件只是满足规定的需求,而不能满足可能存在的隐含需求,软件质量也不能保证。
软件团队的责任
- 发现软件程序、系统或产品中“所有”的问题
- 尽早地发现问题
- 督促和协助开发人员尽快地解决程序中的缺陷
- 帮助项目管理人员制定合理的开发计划
- 对缺陷进行跟踪、分析和分类总结,以便让项目的管理人员和相关的负责人员能够及时、清楚地了解产品当前的质量状态
- 帮助改善开发流程、调高产品开发效率
- 促进程序编写的规范性、易读性、可维护性等
缺陷发现率
缺陷发现率DDP是另一个衡量测试工作效率的软件质量成本的指标。

缺陷发现率DDP=Bugs(tester)/ (Bugs(tester)+ Bugs(customer))
缺陷发现率越高,也就是测试者发现的错误多,发布后客户发现的错误就越少,降低了外部故障不一致成本,达到节约总成本的目的,可获得较高的测试投资回报率。
测试分类
黑盒测试
-
又称功能测试或数据驱动测试,是针对软件的功能需求/实现进行测试,通过测试来检测每个功能是否符合需求,不考虑程序内部的逻辑结构。
-
方法:
- 功能划分
- 等价类划分
- 边界值划分
- 因果图(鱼骨图)
- 错误推测
白盒测试
-
白盒测试也称结构测试或逻辑驱动测试,必须知道软件内部工作过程,通过测试来检测软件内部是否按照需求、设计正常运行。
-
方法:
对应于程序的一些主要结构:语句、分支、逻辑路径、变量;
- 语句覆盖方法
- 分支覆盖方法
- 逻辑覆盖方法
单元测试
- 定义: 又称模块测试,是针对软件设计的最小单位程序模块进行正确性检查的测试工作;可以从程序的内部结构出发设计测试用例,多个模块测试可以平行地独立进行测试;
- 目的:发现模块内部可能存在的差错;
- 内容:模块接口测试(数据流入流出)、局部数据结构测试、路径测试、错误处理测试、边界测试。
- 步骤:利用设计文档设计测试用例;创建被测模块的桩模块或驱动模块;利用被测试模块、驱动模块和桩模块来建立测试环境,进行测试。
集成测试
-
定义:又称组装测试或联合测试,在单元测试的基础上,将所有模块按概要设计和详细设计进行组装。
-
目的:发现模块连接中的接口可能存在的各种差错
-
内容:
-
穿越模块之间的数据是否会丢失;
-
一个模块组装后是否会对另一模块或其他模块存在影响
-
各个子功能组装在一起是否会达到预期的父功能
-
全局数据结构是否有问题;
-
单个模块的错误累积起来是否会放在。
-
-
组装方法:包括一次性组装方式、增殖式组装方式两种组装方法
-
完成标志:成功地执行了测试计划中规定的所有测试用例;修正了所发现的错误;测试结果通过专门小组的评审
系统测试
- 目的:验证和确认系统是否达到其原始目标,而对集成的硬件和软件系统进行的测试
- 测试内容:在真实或模拟系统运行环境下,检查完整的程序系统能否和系统(硬件设备、网络、系统软件)正确配置、连接,满足用户需求
验收测试
-
测试目的:在用户环境中进行测试,以确定系统和产品是否能够满足合同或用户所规定的需求
-
测试内容:根据任务书或合同、供需双方约定的验收依据文档进行对整个系统的测试与评审,确认是否接收或拒绝系统
Alpha测试
- 属于验证测试。模拟运行。由开发人员与测试的测试人员。
Beta测试
- 属于验收测试。由软件的最终用户在一个或多个用户场所来进行的,开发者通常不在现场,用户记录测试中遇到的问题并报告给开发者。
静态测试
- 静态测试又称为静态分析技术,不执行被测试软件,对需求分析说明书、软件设计说明书、源程序做结构检测、流图分析、符号执行等找出软件的错误。
动态测试
- 通过输入一组预先按照一定的测试准则构造的实例数据动态运行程序,而达到发现程序错误的过程。
如何进行单元测试
- 完成最小的软件设计单元——模块验证工作。
- 确保模块的正确编码
- 使用过程设计描述作为指南,对重要的控制路径进行测试以发现模块内错误。
- 通常情况下面向白盒的
- 对代码风格和规则、程序设计结构、业务逻辑等进行静态测试,及早地发现和解决不易显现的错误。
- 单元测试的内容
- 接口测试
- 内部数据结构
- 全局数据结构
- 边界
- 语句覆盖,错误路径
自动化测试
自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程。
- 在设计了测试用例并通过评审之后,由测试人员根据测试用例中描述的规程一步步执行测试,得到实际结果与期望结果的比较。在此过程中,为了节省人力、时间或硬件资源,提高测试效率,便引入了自动化测试的概念。
手工和自动化
- 手工测试缺点在于测试工作量大,重复多,回归测试难以实现
- 自动测试利用软件测试工具自动实现全部或部分测试工作:管理、设计、执行和报告;节省大量的测试开销,并能够完成一些手工测试无法实现的测试
-
手工完成测试的全部过程无法保证测试的科学性与严密性:
- 修改缺陷越多,回归测试约困难
- 没有人能向决策层提供精确的数据以度量当前的工作进度及工作效率
- 反复测试带来的倦怠情绪及其他人为因素使得测试标准前后不一
- 测试花费的时间越长,测试的严格性也就越低
-
自动测试将测试人员从反复、烦杂的测试执行中解放出来,用更多的时间进行测试设计和结果分析
- 软件测试不可能全部自动化
- 不能完成所有手工测试任务
- 无创造性,且灵活性差,不能改进测试的有效率
- 过程中可能会遇到很多想不到的问题,尤其是在软件不稳定的情况下
- 测试脚本的维护高
测试用例设计原则
-
单个用例最小化原则
-
这条原则是所有这四条原则中的“老大“,也是在工程中最容易被忘记和忽略的,它或多或少的都影响到其它几条原则。
-
测试用例的覆盖边界定义更清晰,则测试结果对产品问题的指向性更强。
-
测试用例间的耦合度最低,则彼此之间的干扰也就越低。
-
-
上述这些优点所能带来直接好处是,测试用例的调试、分析和维护成本最低。每个测试用例应该尽可能的简单,只验证你所要验证的内容。
-
测试用例替代产品文档功能原则
- 通常我们会在开发的初期(Scrum每个Sprint的头两天)用Word文档或者OneNote的记录产品的需求、功能描述、以及当前所能确定的任何细节等信息,勾勒将要实现功能的样貌,便于团队进行交流和细化,并在团队内达成对产品功能共识。但随着产品开发深入,团队会对产品的功能有更新的认识,产品功能也会被更具体细化,在一个迭代或者Sprint结束的时候最终实现的功能很可能是A+。如此往复,在不断倾听和吸收用户的反馈,多个迭代过后,原本被描述为A的功能很可能最终变为了Z。这是时候再去看看曾经的Word文档和OneNote页面,它们仍然记录的是A。之所以会这样 ,是因为很少有人会去以及能够去不断地去更新那些文档,以准确地反映出功能当前准确的状态。
-
单次投入成本和多次投入成本原则
- 成本永远是任何项目进行决策时所要考虑的首要因素,项目中的测试也是如此,对成本的考虑也应该客观和全面的体现在测试的设计、执行和维护的整个阶段中。
- 测试中的成本按其时间跨度可以分为:单次投入成本和多次投入成本。例如:编写测试用例可以看作是单次投入成本,因为编写测试用例一般是在测试的计划阶段进行(Scrum每个Sprint的开始阶段)的,虽然后期会有小的改动,但绝大多数是在一开始的设计阶段就基本上成型了;
-
使测试结果分析和调试最简单化原则
- 这条原则实际上是单次投入成本和多次投入成本原则 – 针对自动化测试用例的扩展和延续。在编写自动化测试代码时,要重点考虑如何使得测试结果分析和测试调试更为简单,包括:用例日志、调试辅助信息输出等。
测试用例方法
- 等价类划分
- 等价类划分
- 错误推测
- 因果图
- 判定表驱动分析
- 正交实验设计
- 场景设计法
- 状态转换图
测试用例内容
测试用例主要包括用例编号、用例描述、前提条件、输入数据、测试步骤和期望结果6项关键内容:
-
用例编号
用例的组织要方便测试人员执行测试用例,应设计一套良好的用例编号体系。
-
用例描述
用例描述应使用最精简的文字,描述出用例的全貌。让测试人员不用看测试步骤,只看这个描述就可以知道这个用例是描述哪个场景、哪个功能点。
-
前提条件
一个测试用例一般是针对一个特点的场景,而需要测试的场景发生时通常会有一些铺垫场景,即测试用例的前提,如软硬件环境配置、权限设置,数据准备。
-
输入数据
一个测试用例可以有一个或多个输入数据,也可以无输入数据。
-
测试步骤
测试步骤是测试用例的主体,一个测试用例由一个或多个步骤组成,每个步骤之间有一定的前后关系。每个步骤必须表述详细,描述清晰,用于规范、严谨而又客观,最基本的要求是能够使其他人理解,并能正确的执行编写者希望的操作。
-
期望结果
期望结果是测试执行对执行结果进行对比的标尺,是测试是否通过的判断依据。测试结果必须保证其正确性。
测试计划
根据项目相关文档,需要定义测试范围、测试策略、人员分配、软硬件配置、进度表以及测试过程每个阶段需要达到的目标。
查询遗漏问题的方法
-
说明书是基础和标准
测试的执行,通常按测试用例来进行,但测试用例的设计编写是依据产品规格说明书、需求规格说明书、界面设计规范等。写测试用例时难免有考虑不到的地方,因此反复阅读说明文档,也许会有一些新的思路和启发。在项目后期,回归测试阶段,容易思维定势、疲惫,这是可以把这些文档拿出来,再看一下功能点是否覆盖,覆盖到的是不是和需求一致,没有偏差。
-
相关变动邮件,讨论记录
变动是一个项目过程中不可少的部分,而这些变动,通常是通过讨论的方式定下来的,因此会有一些文档记录和邮件。反复阅读这些邮件和文档记录,可以更深入的理解项目。
-
不定期阅读别人的缺陷
每个人的思路、考虑的角度和操作习惯各不相同,因此发现的问题就会不一样。多阅读别人的缺陷可以拓宽思路,看多了,也会不自觉把多种思路集中到一起,慢慢得应用到测试实践中了。
-
多和开发人员沟通
功能测试对测试人员来说大多是黑盒测试,只有开发人员最清楚哪个函数调用哪个函数、哪块单元测试不够充分、哪个逻辑结构比较复杂,多和他们沟通,可以知道哪里还需要多关注一下。
-
有选择的重新验证以前的缺陷
特别在回归测试、验收测试阶段,除了验证前面发现的缺陷,还要重视那些与缺陷相关的模块。一个底层参数的变动,可能会引起很多相关功能的问题,继而造成缺陷的遗漏。
-
关注变化
一段代码的改动,需要开发人员和测试人员去识别。开发人员知道改动的地方会被哪些模块调用或者会引起哪些模块的变化,但由于时间紧、任务重、很难做好单元测试,因此开发人员要通知测试人员需要关注的测试点。
-
简单思维方式,一主线为主,减少大遗漏
一个项目的成功不是把缺陷全报出来,而是在有限的代价下达到预期的质量。按计划进行的项目,主要功能的质量在一定程度上决定了产品的好坏。在项目工期紧张时,全部走完所有测试用例是很难的,可以基本功能为主线,做好相关测试用例的执行,保证不会发生大的质量事故。
在测试后期,测试人员可能对质量已经很有信心,受思维和经验的局限性,可能仅限于此。若此时,在产品发布之前,调动其他组的员工参与限时测试并给予奖励,必然能有效减少软件缺陷带来的风险,提高产品质量。
软件缺陷(bug)
软件缺陷是指系统或系统部件中那些导致系统或部件不能实现其应有功能的缺陷。一般定义缺陷有以下5条原则:
-
软件未实现产品说明书要求的功能。
-
软件出现产品说明书指明不应该出现的错误。
-
软件实现了产品说明书未说明的功能。
-
软件未实现产品说明书虽未明确提及但应该实现的目标。
-
软件难以理解,不易使用,运行速度慢,或者软件测试员认为最终用户会认为不好。
提交缺陷(bug)的要求

Bug描述的基本要求是分类准确、叙述简洁、步骤清楚、实际结果描述准确、复杂问题有据可查(截图或其他形式的附件)。基本要求如下:
-
问题描述一般格式:模块或功能点=>测试步骤=>期望结果=>实际结果=>其他信息
-
单一:尽量一个bug只针对一个软件缺陷
-
简洁:每个步骤尽量简单明了
-
再现:问题必须能在自己机器上重现方可上报(个别严重问题重现不了也可上报,但必须标明)
-
复杂问题:附截图补充说明或直接通知指定的修改人,截图文件格式建议用JPG或GIF
-
报告中不允许使用抽象的词语:“有错误”,“有时候”之类的不确定语句