一.几个案例
火星:缺少集成测试,没有合在一起
骑士集团:缺乏代码审查
AWS宕机:缺乏审查和测试
预定酒店:系统缺陷
Uber:令牌管理不善
二.正反两方面争辩
一方面通过测试来保证质量,另一方面又要改进测试方法和提高软件测试的效率,两者应该相辅相成。
三.软件测试与开发的关系
V模型说明软件测试活动和项目是同时启动的,软件测试的工作很早就开始了,避免了瀑布模型所带来的误区一软件测试是在代码完成之后进行。 在V模型中相对能够准确地反映测试与开发之间的关系。左边是软件定义和实现的过程(包括分析设计和编程),右边是对左边所构造的东西进行验证的过程,测试与开发有一对一的关系。
第二章 软件测试基本概念
一.软件质量模型六个特性
功能性(首要):当软件在指定条件下使用时,软件产品提供满足明确和隐含需求的功能的能力。
可靠性:在指定条件下使用时,软件产品维持规定的性能级别的能力。
易用性:在指定条件下使用时,软件产品被理解、学习、使用和吸引用户的能力。
效率:在规定条件下相对于所用资源的数量,软件产品可提供适当性能的能力。
可维护性:软件产品可被修改的能力。
可移植性:软件产品从一种环境迁移到另外一种环境的能力。
二.软件缺陷定义
软件产品的问题表现为用户所需要的功能没有完全实现
三.软件缺陷的产生
技术问题、软件本身、团队工作
四.软件缺陷的构成
需求定义是软件缺陷出现最多的地方。
原因: (1)用户一般是非计算机专业人员,软件开发人员和用户的沟通存在较大困难,对要开发的产品功能理解不一致。
(2)由于软件产品还没有设计、开发,完全靠想象去描述系统的实现结果,所以有些特性还不够清晰。
(3)需求变化的不一致性。用户的需求总是在不断变化的,这些变化如果没有在需求定义文档中得到正确的描述,容易引起前后文、上下文的矛盾。
(4)对需求定义文档不够重视,在需求定义与分析上投人的人力、时间不足。
(5)没有在整个开发队伍中进行充分沟通。
五.修复软件缺陷的代价
缺陷发现的越迟,修复成本越高。
六.静态测试与动态测试
1.静态测试:不是运行程序代码,而是通过人工检查或使用工具来分析源代码、设计文档等来确定潜在的问题。测试的方法包括代码审查、代码静态代码分析和软件度量等。
静态测试内容包括多个方面。例如:
• 代码走查:开发人员或测试人员阅读源代码,查找可能的错误或不符合编码标准的地方。
• 技术评审:这是一个更为正式的过程,通常由一组专家进行,他们会仔细检查设计和代码,以确保它们符合预定的技术标准和规范。
• 代码审查:这是一种更为深入的检查方法,通常涉及多人会议,参与者会逐行审查代码,讨论最佳实践和潜在的改进方案。
• 静态代码分析:使用自动化工具来检查源代码,这些工具可以识别出潜在的错误、安全漏洞、代码风格问题等。
• 软件度量:通过度量软件的各种属性(如复杂度、可维护性等),来评估软件的质量。
静态测试可以不涉及编写传统意义上的“测试用例”,其重点是检查文档、设计规格、代码标准和编程实践,而不是验证程序运行时的行为。
2.动态测试:指在软件运行过程中进行的测试,它涉及到执行程序并观察其行为和输出,目的是确保软件在实际运行时能够满足预期的功能和性能要求。
通常,单元测试、集成测试、系统测试、性能测试和用户接受测试等,均涉及到采用动态测试的方法。 动态测试能够检测软件在实际运行环境中的表现,包括功能性缺陷、性能问题、安全漏洞等。动态测试通常需要准备测试数据和测试用例,并且测试结果受到测试覆盖率
的影响。
• 设计测试用例:根据软件的需求和设计,创建一系列的测试用例,每个用例旨在测试特定的功能或条件。
• 编写测试代码:通常需要根据具体情况选用适用的测试工具/框架。
• 执行测试:使用这些测试用例来运行程序,并观察其行为。这包括输入数据、执
行操作和接收输出结果。
• 分析输出结果:将程序的实际输出与预期输出进行比较,以验证程序的正确性、
效率和健壮性。
• 测试效果评估:涉及到测试覆盖率等。
设计用例:如黑盒方法、白盒方法,详见课本第三章。以下是编写动态测试用例的一般步骤:
- 理解需求:首先,彻底理解软件的需求文档,包括功能需求、性能需求、安全需求等。这是编写有效测试用例的前提。
- 定义测试目标:明确你要通过测试用例验证什么。这可能是一个特定的功能、一个错误修复、一个性能改进等。
- 确定输入数据:为每个测试用例确定必要的输入数据。这些数据应该是代表性的,并且能够覆盖不同的测试场景。
- 设计测试场景:基于需求,设计一系列测试场景来验证软件的行为。每个测试场景都应该有一个明确的目标和预期结果。
- 编写测试步骤:详细描述执行测试所需的步骤。这些步骤应该清晰、简洁,并且易于理解和执行。
- 定义预期结果:对于每个测试步骤,定义你期望的结果。这将是后续验证测试是否通过的依据。
- 考虑边界条件:确保测试用例涵盖了所有重要的边界条件和极端情况,如最大值、最小值、空输入等。
- 准备测试环境:确保测试环境与生产环境尽可能相似,以便测试结果具有参考价值。
- 执行测试:按照测试用例执行测试,并记录实际结果。
- 比较和评估:将实际结果与预期结果进行比较,评估软件是否按预期工作。
- 记录和报告:记录测试结果,并在发现问题时提供详细的报告,以便于后续的问题追踪和修复。
- 复审和更新:随着软件的发展,定期复审和更新测试用例,确保它们仍然有效并且与当前的需求相符。
3.产品评审
(1)需求评审:审查需求文档是否完整、正确、清晰。
(2)设计和代码评审
4.验证和确认
(1)验证:验证是否正确地构造了软件?验证开发过程是否遵守好已定义好的内容。
(2)确认:是否正在构建用户所需要的功能。
七.主动测试和被动测试
1.主动测试:测试人员主动向被测试对象发送请求,发生直接相互作用的关系,被测试对象完全受测试人员控制,被测试对象处于测试状态,而不是实际工作状态。所以被测试对象受人为因素影响较大,不适应产品在线测试。测试人员需要设计测试用例,设法输入各种数据。
2.被动测试:软件产品运行在实际环境中,测试人员不干预产品的运行,而是被动监控产品运行。适合性能测试和在线监控,或者为了节省成本。系统运行过程中各种数据自然产生,测试人员不需要设计测试用例,但数据完整性得不到保证。
八.黑盒测试和白盒测试
1.白盒测试
定义:已知产品的内部工作过程,按照程序内部的运行路径检验每条通路是否按照预定要求工作。
基本原则:(1)先考虑代码行和分支被覆盖
(2)再考虑完成所有逻辑条件分别为真值和假值的测试
(3)如果需要,流程图所有独立路径至少被运行一次
(4)检查内部数据结构,确保测试有效性
2.黑盒测试
定义:完全不考虑程序内部结构和内部特性的情况下,测试人员直接进行测试,即不关注软件内部结构而是着眼于程序外部用户界面
3. 1)白盒测试方法:
语句覆盖;判定覆盖/分支覆盖;条件覆盖;判定-条件覆盖;条件组合覆盖;路径覆盖;基本路径覆盖。
(2)黑盒测试方法:等价类划分法;边界值分析法;判定表法;因果图法/因果分析法;正交试验法;功能图法。
九.软件测试的层次
单元测试、集成测试、系统测试、验收测试
第三章 软件测试方法
一.基于直觉和经验的方法
1.自由测试:强调测试人员根据自己的经验,不受测试用例束缚,放开思想进行测试
2.ALAC(像客户那样做):是基于客户使用产品的知识开发出的测试方法,对常用的功能进行测试。
3.错误推测法:根据工作经验和直觉推测出可能存在的错误,而有针对性地进行测试。
二.黑盒
1.等价类划分:用一组有限的数据去代表近似无限的数据
举例:某企业招工,要求登记求职者的年龄,必须是6
位数字
,要求出生日期在1980-2000年之间
,前四位表示年
,后两位表示月
。
(1)确定输入条件。
(2)为每个输入条件划分等价类。
2.边界值分析法:边界最容易发生错误,在边界上验证系统功能
上点:边界上的点(刚好等于)
离点:离边界最近的点(刚好大于最大值、刚好小于最小值)
内点:在有效范围内任意一个点
边界值分析法设计测试用例步骤:
- 分析需求,确定输入数据类型。
- 使用规则划分有效和无效等价类。
- 确认上点、离点、内点。
- 设计用例,覆盖有效等价类。
- 设计用例,覆盖无效等价类。
举例:某学生成绩管理系统,要求录入全体学生的成绩,在[0, 100]范围内,要求针对分数设计测试用例,验证录入功能。
3.判定表法:对多个条件的组合进行分析,从而设计用例
条件桩:列出问题的所有条件。
条件项:针对条件桩给出的条件,列出所有可能的取值。
动作桩:列出问题规定的可能采取的操作。
动作项:列出在条件项的各组取值情况下应采取的动作。
判定表优缺点:
优点:它能把复杂的问题按各种可能的情况一一列举出来,简明而易于理解,也可以避免遗漏。
缺点:不能表达重复执行的动作,例如循环结构。
举例:某学生成绩管理系统,要求对平均成绩在90分以上,且没有不及格科目的学生,或班级排名在前5位的学生,在程序中将学生的姓名用红色标识,请建立该场景的判定表。
列出条件桩和动作桩
确定规则的个数(判定表列数)。2三次方=8条
填入条件项和动作项
适用范围:判定表驱动法适用于复杂系统和需要覆盖多个条件组合的测试场景,它可以提供一种结构化和系统化的方法来设计和执行测试用例,以增强测试的覆盖率和效果。
4. 因果图法
- 定义:通过将问题的各个因素和可能的原因按照因果关系进行可视化,帮助识别问题的根本原因并找到解决方案。
- 适用条件:当输入的条件过多时,适用判定表会产生大量的测试用例,而且也不能表达条件之间的各种关系。在这种情况下,更适合适用因果图法。因果图法的优点在于它可以帮助团队以一种可视化和结构化的方式分析问题,找到潜在的原因,并促进创造性的解决方案。
- 因果关系:是指软件系统中事件或行为之间的因果依赖关系,通过识别这些关系可以确定输入值或条件变化时系统的响应或输出变化的关联关系。
- 约束关系:是指软件系统中事件或行为之间的限制关系,通过识别这些关系可以确定系统中的约束条件或规则,这些条件或规则对系统的行为或输出具有限制或影响。
三.白盒
1.语句覆盖
语句覆盖要求测试用例至少执行一次每个语句(或代码行)。它关注测试用例是否覆盖了代码的每个语句,无论该语句是否有分支。
2.判定覆盖
判定覆盖要求测试用例覆盖每个判定点的所有可能取值。判定点是指代码中的条件语句,包括if语句、switch语句等。
判定覆盖关注的是每个判定点的真假分支是否都被覆盖到。
3.条件覆盖
条件覆盖要求测试用例覆盖每个条件表达式的所有可能取值。条件表达式是指条件语句中的单个条件,如if语句中的每个条件。
条件覆盖关注的是每个条件的真假取值是否都被覆盖到。
4.判定-条件覆盖
判定/条件覆盖要求测试用例同时满足判定覆盖和条件覆盖的要求。即测试用例需要覆盖每个判定点的所有可能取值,并且覆盖了每个条件表达式的所有可能取值。
5.条件组合覆盖
条件组合覆盖要求测试用例覆盖每个条件表达式的所有可能取值组合。它关注的是条件之间的组合情况,通过考虑多个条件的交叉取值来设计测试用例。
6.路径覆盖(最强)
路径覆盖要求测试用例覆盖代码中的每个可能路径。路径是指从程序的入口到出口的完整执行路径。路径覆盖关注的是测试用例是否能够覆盖所有可能的路径,包括循环、条件语句和分支等。
路径覆盖实际上考虑了程序中各种判定结果的所有可能组合,但它未必能覆盖判定中条件结果的各种可能情况。因此,它是一种比较强的覆盖标准,但不能替代条件覆盖和条件组合覆盖标准。
7.基本路径测试法
基本路径测试法的核心思想是通过识别软件系统的基本路径集合,以确保这些路径都被测试覆盖到。
基本路径是指一个程序中的独立路径,它覆盖了所有可能的执行路径,从程序的入口到出口。
基本路径测试法设计测试用例的步骤:
- 根据程序结构,导出程序的控制流图。
- 求环路复杂性V(G)。
- 确定线性独立路径的基本集合,即基本路径集 (不超过V(G)条)。
- 生成测试用例,确保每条路径执行。
区域:控制流图中由结点和边组成的闭合部分,包括图的外部(二维平面被分成几部分)
独立路径:至少包含一条在其他独立路径中从未包含过的边(每次都包含新边)
环路复杂性:度量程序的逻辑复杂程度。
三种计算方法:
- 设m为边数,n为结点数,则 V(G)=m-n+2
- 设P为判定结点的个数,则 V(G)=P+1
注:if,while,for:P=1
case型多分支语句:P=可能的分支数 - 1
- V(G)=流图的区域数
例题
第四章 软件测试流程和规范
一.软件测试过程
软件工程过程:需求评审、设计评审、单元测试、集成测试、系统测试、验收测试
管理角度:测试计划、测试设计、 执行与监控、结果分析与评估、项目总结
二.W模型
(1)测试过程和开发过程是同时开始、同时结束的,两者保持同步的关系。
(2)测试过程是对开发过程中阶段性成果和最终的产品进行验证的过程,所以两者是相互依赖的。前期,测试过程更多地依赖于开发过程,后期,开发过程更多地依赖于测试过程。
(3)测试过程中的工作重点和开发工作的重点可能是不一样的两者有各自的特点。不论在资源管理,还是在风险管理,两者都存在着差异。
W模型在V模型的基础上进行了扩展,将测试活动分为两个独立的轨道,分别是验证轨道和确认轨道。
验证轨道关注是否按照规范和需求进行开发,包括需求验证和系统验证等测试活动。
确认轨道关注软件是否满足用户的实际需求,包括验收测试和系统集成测试等活动。
特点:W模型强调了早期的验证和规范的测试,以及后期的确认和实际需求的测试。
优点:结合了V模型和迭代模型的优点,强调早期的迭代开发和测试;更好地适应需求变更和持续集成。
缺点:需要有效的沟通和协调;对项目管理和资源调度要求较高;忽略了迭代活动,可能导致在开发后期无法适应变更需求。
适用:适用于较小规模、需求相对稳定的项目。
三.TMap
四.敏捷测试
1.概念
为了适应敏捷开发而特别设计的一套完整的软件测试解决方案,单元测试是敏捷测试的基础。
2.与传统测试的区别
第五章 单元测试
一.概述
单元测试是软件开发过程中的一项测试活动,用于验证和确保代码中的最小可测试单元(通常是函数或方法)的功能和正确性。它是一种自动化测试,针对单个代码单元进行测试,隔离测试对象,以便更容易定位和修复问题。
二.重要性:
- 提供快速反馈:当引入新的代码或修改现有代码时,运行相关的单元测试可以快速发现问题,帮助开发人员迅速定位和修复错误,减少调试时间。
- 确保代码质量:通过单元测试,可以验证代码的正确性、可靠性和稳定性。
- 支持重构和维护:单元测试为重构和代码修改提供了安全网。当进行代码重构或修改时,运行相关的单元测试可以确保代码的行为没有改变,没有引入新的错误。
- 促进团队协作:单元测试作为一种规范和共享的实践,促使团队成员编写更可测试的代码,并提供可靠的测试套件。
- 提高软件稳定性:单元测试可以发现并解决潜在的缺陷,减少软件中的错误。通过及时修复和预防问题,可以提高软件的稳定性和可靠性。
- 降低成本和风险:通过在早期发现和修复问题,单元测试可以降低后续阶段的成本和风险。它可以减少集成测试和系统测试阶段的问题数量,提高整体测试效率。
三.单元测试任务:
模块接口:数据是否能正确流入、流出模块。
局部数据结构:检查局部数据结构完整性。
独立路径:检查每一条独立执行路径。
错误处理:预见、预设的各种出错处理是否正确有效。
边界条件:检查临界数据处理的正确性。
四.单元测试环境
建立原因:建立单元测试环境是为了在进行单元测试时能够提供一个独立、可控、可重复以及高效的环境,以便有效地执行单元测试并获取准确的测试结果。
1.桩模块:桩模块是一个简化或模拟的替代组件,用于代替系统中的某个真实组件或外部依赖。桩模块主要用于解决以下问题:
- 隔离测试:将被测试的单元与其依赖的其他模块分离开来,使测试集中在单个单元上。
控制测试环境:通过桩模块,可以模拟各种情况和条件,以验证被测试单元在不同环境下的行为。
- 提供可控的返回结果:桩模块可以返回预定义的结果,以便测试人员可以验证被测试单元对不同结果的处理。
2.驱动模块:驱动模块是一个用于调用被测试单元的组件,它负责触发被测试单元的执行并提供必要的输入数据。驱动模块主要用于解决以下问题:
- 激活被测试单元:驱动模块通过调用被测试单元的函数或方法来触发其执行,以验证其行为和输出结果。
- 提供测试数据:驱动模块可以提供测试所需的输入数据,以覆盖被测试单元的不同路径和情况。
- 捕获和分析结果:驱动模块可以捕获被测试单元的输出结果,并进行断言和验证,以判断测试是否通过。
单元测试中用来模拟实现被测模块需调用的其他功能模块的是桩模块
单元测试中用来模拟被测模块调用者的模块是驱动模块
软件测试过程中的集成测试主要是为了发现概要设计阶段的错误。
五.单元测试策略
- 孤立的测试策略:
优点:可以更集中地测试单个模块的功能,容易定位和解决问题,独立于其他模块的影响。
缺点:无法测试模块间的交互和依赖关系,可能导致整体系统问题的遗漏。
- 自顶向下的测试策略:
优点:从系统的最高级别开始测试,可以尽早发现系统级别的问题和交互问题。
缺点:依赖于子模块或子组件的实现或可用性,可能需要使用桩模块或驱动模块模拟未实现或不可用的部分。
- 自底向上的测试策略:
优点:从系统的最低级别开始测试,可以尽早发现单个模块的问题和逻辑错误。
缺点:依赖于父模块或父组件的实现或可用性,可能需要使用桩模块或驱动模块模拟未实现或不可用的部分。
六.集成测试分为渐增测试和非渐增测试
第六章 系统测试
一.功能测试
- 概念:根据产品设计规格说明书来检验被测试的系统是否满足各方面功能的需求
- 过程:
- 明确质量要求和测试目标
- 确定测试范围并分解出测试项
- 进行质量风险分析
- 确定重点测试项
- 确定采用的方法和策略,设计测试用例
- 准备测试数据,搭建测试环境,执行测试用例
- 分析测试结果,编写测试报告
二.回归测试
1.概念
回归测试就是重新运行现有测试用例测试原有功能,以便确定变更是否达到了预期的目的,检查变更是否损害了原有的正常功能。每当软件发生变化时就应进行回归测试
2.方法
- 再测试全部用例
- 基于风险选择测试
- 基于操作剖面选择测试
- 再测试修改的部分
第七章 性能测试
性能测试是度量软件质量的一种重要手段,他从响应速度、稳定性、兼容型、可移植性等方面检测软件是否满足用户需求。
一. 性能测试
1.概述:使用性能测试工具模拟正常、峰值及异常负载状态,对系统的各项性能指标进行测试活动。
2.作用:验证软件是否达到了用户期望的性能需求,同时也可以发现系统中可能存在的瓶颈及缺陷,从而优化系统的性能。
3.目的:
(1)验证系统性能是否满足预期的性能需求;
(2)分析软件系统在各种负载水平下的运行转态,提高性能需求和效率;
(3)识别系统缺陷,寻找系统中可能存在的性能问题;
(4)系统调优,探测系统设计与资源之间的最佳平衡,改善并优化系统的性能。
二.性能测试的指标
性能测试常用的指标包括响应时间、吞吐量、并发用户数、TPS等。
1.响应时间:系统对用户请求做出响应所需要的时间。
2.吞吐量:单位时间内系统能完成的工作量,他衡量的是软件系统服务器的处理能力。
3.并发用户数:同一时间请求和访问的用户数量。
4.TPS:系统每秒钟能够处理的事务和交易的数量。
5.点击率:用户每秒向Web服务器提交的HTTP请求数,这个指标是Web应用特有的一个性能指标。
6.资源利用率:软件对系统系统资源的使用情况,是分析软件性能瓶颈的重要参数。
三. 性能测试的种类:性能测试是一个统称,包含多种类型。主要有:
1.负载测试
逐步增加系统负载,测试系统性能的变化,并最终确定在满足系统性能指标的情况下,系统能够承受的最大负载量。
2.压力测试
逐步给系统增加压力,测试性能变化,使系统某些资源达到饱和或系统崩溃的边缘,从而测定系统所能承受的最大压力。
ps:负载测试与压力测试的区别
例如:软件系统正常的响应时间为2s,负载测试时确定访问量超过1万时响应时间变慢。
压力测试则继续增加用户的访问量,当用户增加到4万时,系统崩溃。则可以确定,最大负载是1万人(开始影响性能),最大压力4万人(系统撑不住了)
3.并发测试
4.配置测试
5.可靠性测试
6.容量测试
四.性能测试流程
- 分析性能测试需求
- 制定性能测试计划
- 设计性能测试用例
- 编写性能测试脚本
- 测试执行及监控
- 运行结果分析
- 提交性能测试报告
五.性能测试工具
常用:LoadRunner和JMeter
第九章 测试自动化
一.自动化概述
1.什么是自动化概述
自动化测试,是把以人为驱动测试行为转化为机器执行的过程。实际上就是模拟手工测试过程。
实施自动化测试之前,需要对软件开发过程进行分析。需要满足的条件有:
- 项目需求变动不频繁
- 项目周期足够长
- 自动化测试脚本可重复使用
2.自动化测试的基本流程
- 分析测试需求
- 指定测试计划
- 设计测试用例
- 搭建测试环境
- 编写并执行测试脚本
- 分析测试结果、记录测试问题
- 跟踪测试Bug
3.自动化测试实施策略:追求敏捷开发导致许多团队采用金字塔策略。
- 单元测试
要求开发中对每个功能模块进行测试,通常采用白盒测试,主要对代码内部结构进行测试。
- 接口测试
对数据传输、数据库性能等进行测试,通常使用白盒加黑盒的相结合形式进行。
- UI测试
以用户体验为主,不是完全通过自动化测试。
- 自动化测试的优势和劣势
自动化测试只是众多测试中的一种,并不比人工测试更高级更先进。
二.自动化测试常见技术
1.代码分析
2.脚本测试
脚本测试是测试计算机程序执行的指令集合。测试脚本主要有以下几种:
(1)线性脚本
(2)结构化脚本
(3)数据驱动脚本
(4)关键字驱动脚本
3.对象识别:UI自动化测试
采用自动化测试脚本将用户在被测应用的用户界面上的操作转变为一系列自动化操作,然后验证输出结果是否正确。页面识别是核心技术。
4.接口调用:API测试
通过调用各种形式的软件API,按照一定格式输入请求,验证返回的响应结果是否正确。
5.自动比较技术
预期输出是事先定义的或插入脚本中的,然后在测试过程中运行脚本,将捕获的结果和预先准备的输出进行比较,从而确定测试用例是否通过。
第十一章 测试用例的构成及其设计测试用例设计步骤:
一.考虑因素
- 具有代表性、典型性
- 寻求系统设计、功能设计的弱点
- 需要考虑正确的输入
- 多考虑用户实际使用场景
二.基本原则
- 避免含糊
- 尽量将相似功能抽象并归类
- 避免冗长复杂
第十三章 软件缺陷