软件测试基础
一. 概述
二. 测试过程
三. 测试过程模型
四. 测试方法
一. 概论
1. 定义
软件测试:
测试分为软件测试
和硬件测试
,软件测试是本文章的主题。软件
由程序
和文档
组成,所以测试时,测试对象应包含程序测试
和文档测试
。
软件测试的目的是开发出高质量的可用软件,确保软件满足用户的需求。
BUG:
BUG 是软件中没有完全实现的需求 或 软件实现了用户不需要的功能。
大多数情况下,和 软件错误
一起出现的词语有 软件缺陷
、软件故障
、软件失效
。
-
软件错误 software error:Bug。开发人员在开发过程中始终会犯错,是隐患爆发之前的伏笔。所以软件错误是指在软件生命周期内的不希望或不可接受的人为错误,软件错误是一种人为过程,相对于软件本身,是一种外部行为。其结果是导致软件缺陷的产生。
-
软件缺陷 software defect:是存在于软件(文档、数据、程序)之中的那些不希望或不可接受的偏差。 其结果是软件运行于某一特定条件时出现软件故障,这时称软件缺陷被激活。
-
软件故障 software failure:指软件运行过程中出现的一种不希望或不可接受的内部状态。譬如,软件处于执行一个多余循环过程时,我们说软件出现故障。此时若无时当的措施(容错)加以及时处理,便产生软件失效。显然,软件故障是一种动态行为。
-
软件失效 software fault:指软件运行时产生的一种不希望或不可接受的外部行为结果。
综上:软件错误是一种人为错误。一个软件错误必定产生一个或多个软件缺陷。当一个软件缺陷被激活时,便产生一个软件故障;同一个软件缺陷在不同条件下被激活,可能产生不同的软件故障。软件故障如果没有及时的容错措施加以处理,便不可避免地导致软件失效;同一个软件故障在不同条件下可能产生不同的软件失效。
2. 软件测试分类
软件测试的目的是一致的,但什么时候、以何种方式执行测试是一个问题,所以将测试划分成不同种类的测试,实现区分在软件生命周期过程中的测试方式。
如果按照阶段
划分,贯穿整个软件的生命周期,可以划分为单元测试
、集成测试
、确认测试
、系统测试
、验收测试(alpha beta)
。其中每个阶段都还有子级测试,后续会详细介绍。
按照阶段划分是主要划分软件测试种类的方式,还有其它种类的测试可以稍作了解,按是否运行程序
可以划分为静态测试
、动态测试
,按是否查看源代码
可以划分为白盒测试
、黑盒测试
、灰盒测试
,按对象
种类可以划分 APP 测试
、WEB 测试
、物联网测试
、大数据测试
、AI 测试
等。
3. 测试的宗旨
-
测试应该尽早进行。错误发现得越晚,后续想要修正的耗费越大。
-
测试只能证明项目目前存在缺陷,而不能证明项目不存在缺陷。
-
穷举测试不可能实现,考虑经济因素,应在合适的时候停止测试。通常表现为准出原则
-
BUG 有集群现象,可以通过少数模块发现大部分的缺陷。
-
开发人员最好不要同时负责开发和测试,心理因素是首要原因。
-
测试是为发现错误而执行程序的过程。并且软件测试是一个破坏性的过程,甚至是一个施虐的过程
-
检查程序是否“未做其应该做的”仅是测试的一般,测试的另一半是检查程序是否“做了不应该做的”,所以测试时,不仅要考虑合理的输入,也要考虑不合理的输入。
-
应避免测试用例用后即弃,测试用例本身也是资源的一种。
4. 软件测试工具
市面上比较流行的软件测试工具,可能不太准确,很多公司会有自己的测试工具。
-
禅道:缺陷管理工具。
-
Jira:缺陷管理工具。
-
Git 类:版本控制工具。
-
Jmeter:主要用于 Web 应用程序的负载测试,还支持单元测试和有限的功能测试。
-
Loadrunner:性能测试工具。预测系统行为和性能的负载测试工具。
-
Selenium:Web 自动化测试工具。
-
QTP:Web 自动化测试工具,主要用于回归测试和测试同一软件的新版本。
-
Fiddler:自动化测试工具,开源,是一个常用的抓包工具。它是用C#写出来的,可以支持众多的http调试任务。
-
Appium:App 自动化测试,同时支持 IOS 和 Android 平台。
-
Postman:接口测试工具。提供功能强大的Web API和HTTP请求的调试。
-
SoapUI:用于SOAP和REST的开源API测试自动化框架。它还支持功能测试、性能测试、数据驱动测试和测试报告。
-
Monkey:稳定性测试工具。适用于 Android 和 IOS。
-
Robot Framework:WebUI自动化测试,接口测试 工具。
-
Jenkins:支持持续继承项目,自动化构建编译,部署,任务执行,测试报告,邮件通知等。
二. 测试过程模型
1. 简介
软件测试过程是一种抽象测试模型,用于定义软件测试的流程和方法。
在软件开发的历程中,开发研究人员总结了很多开发模型
,如 瀑布模型、螺旋模型、增量模型、原型模型、迭代模型、快速原型 等。但以上模型并未强调测试在开发过程中的作用,所以软件测试人员总结出了一些优秀的测试模型
来指导软件测试的进行,主要有 V模型、W模型、H模型、X模型。这些测试模型对指导测试工作进行具有重要意义,但模型不是完美的,应结合实际项目去使用。
2. V 模型
V模型,因模型构图形似字母 V,所以称为 V模型。V模型是软件开发瀑布模型的变种,反映了软件测试活动与软件开发过程的关系。
优点:
V模型 采用了包括 低层测试 和 高层测试 的软件测试策略,低层测试是为了保证源代码的正确性,高层测试是为了使整个系统可以满足用户需求。测试与开发工作串行执行。
缺点:
V模型 仅仅把测试过程作为在需求分析、系统设计及编码之后的一个阶段,忽视了测试对需求分析、系统设计的验证,即没有尽早介入测试,没有体现出“尽早地和不断地进行软件测试”的原则。另外,因为 V模型 是 瀑布模型的变种,所以 V模型也存在瀑布模型中存在的问题。
3. W 模型
W模型 的构图大体上由两个 V 组合起来,一个 V 表示的是开发过程,另一个 V 表示测试过程。两个 V 相交表明了 测试与开发的并行关系。
优点:
W模型 中测试活动与软件开发同步进行,相对于 V模型 更早地介入到项目中,且 W模型所测试的对象进一步增加,包含 需求、设计、代码 等。
缺点:
模型中,需求、设计、编码等活动被视为串行的,同时,测试和开发活动之间也保持着一种线性的前后关系,需要等待上一阶段完全结束,才可以正式开始下一阶段的工作,无法支持灵活的迭代开发模型。
另一方面,W模型 对于部分没有文档产生的项目,无法应用 W模型。
4. H 模型
H模型 提出将测试活动从开发中独立出来,形成一个独立的流程,贯穿整个软件周期。
优点:
H 模型揭示了软件测试除了执行测试之外,还有很多工作。
H模型指出软件测试要尽早准备,尽早执行;只要某个测试达到准备就绪点,测试执行活动就可以开展,并且不同的测试活动可按照某个次序先后进行,也可以反复进行,支持迭代,大大增加了测试的灵活性。
5. X 模型
X模型 是对 V模型的改进,X模型 提出针对单独的程序片段进行相互分离的编码和测试,此后通过频繁的交界,通过 集成,最终组合成为可执行的程序。然后再对这些可执行的程序进行测试。
一通过集成的成品可以进行封装并提交给用户,也可以作为更大规模和范围内集成的一部分。所以 X 模型的一个特征是不断迭代的测试,直到封版发布。
X 模型 定位了探索性测试,这是不进行事先计划的特殊类型的测试,往往能帮助有经验的测试人员在测试计划之外发现更多的软件错误。
多个并行的曲线表示变更可以在各个部分发生。
三. 软件测试流程
上面的软件测试过程是一种抽象测试模型,作为测试的指导。在这一部分,将讲述一个普遍的测试流程。
测试流程普遍流程是 文档评审、制定测试计划、编写测试用例(用例评审)、执行测试(Bug管理)、编写测试报告。
项目流程 和 项目流程 的意义并不等同。项目流程一般包括,需求分析、概要设计、详细设计、开发编码、测试分析与系统整合、运维 等。
文档评审
阶段,由产品经理讲述项目需求,其他组员听取需求并提出意见。
等产品经理完善需求规格说明书,测试组长或组员就可以根据需求说明书制定测试计划
。
测试人员根据测试计划开始编写测试用例
,对于测试用例,一般还要进行 用例评审 ,确保用例正确、合理。
等开发把代码发过来之前还要部署测试环境,然后才能用开发发过来的代码执行测试
,执行测试的过程中有 Bug 管理,执行测试过程中需要定位问题,有什么问题需要提交给相应的人员,代码问题找开发、数据库问题找DB、架构问题找架构师、环境问题找运维、、、,如果是在缺陷管理软件里,只需要提交 Bug 然后抄送给相应的人就可以了。
测试结束之后,需要输出测试报告
,内容一般包括在项目中发现了多少 Bug,修复的有多少,有什么不能修复 等等。
![](file:///home/guyan/Public/knowledge-base/学习/0.专业知识/02.软件工程/软件测试/img_softtesting/005.Bug生命周期.png?msec=1668309141771)
1. 文档评审
需求文档:在项目需求分析阶段,需要评审产品经理编写的需求文档,此时更多的是给编码人员讲解项目的需求,即这个项目要做什么,做成什么样子
测试计划:测试计划是测试人员的工作量预估,也是将来测试人工作考核绩效的重要依据。测试计划的内容包括 测试范围是什么、分为哪些阶段、什么时间点完成什么、测试的具体内容列表(流程、功能、接口)、测试资源的成本(人/天)等等。最终的测试过程和测试结果还是以 测试报告 为准。
2. 单元测试
定义:UT(unit testing),对软件中的最小可测试单元进行检查和验证(如c语言中的函数和Java中的类)
单元测试就是要写一个测试类或测试方法,调用开发的新增方法(新增肯定还要传值),并且在调用过程中模拟一些异常情况或者传输错误的值。所以单元测试一般由开发人员来完成
成熟的开发框架一般自带测试的组建和工具,如 Sprintboot 可以直接在 applicationcontext.xml 文件中引入 test 依赖,调用它来进行测试
3. 集成测试
定义:IT(integration testing),将已通过测试的单元模块逐步组装(自底向上或自顶向下)成子系统,再逐步进行测试,重点测试不同模块的 接口部分,检查各个单元模块结合到一起能否协同配合,正常运行、函数之间的参数传递是否正确、全局变量的使用等,也就是组件或系统之间的交互。
测试方法:
非增量式测试方法:直接将各各单元直接组装在一起,适用于体量小的软件
增量式测试方法:逐一把单元组装起来,每组装一个单元,对整个已集成部分进行一次测试
增量 - 自顶向下:开始,沿着软件的控制层次向下移动,逐渐把各个模块结合起来。在自顶向下组装过程中,可以使用深度优先策略或宽度优先策略。自顶向下集成测试法能够在测试阶段的早期验证系统的主要功能逻辑,越重要的控制模块,越能优先得到测试,但需要编写大量的桩程序
增量 - 自底向上:从底层模块(即软件模块结构图中最低层的模块)开始,逐步向上不断集成模块进行测试的方法。自底向上集成测试能够在最早时间完成对基础函数的测试。其它模块可以更早地调用这些基础函数,有利于提高开发效率,但需要创建驱动程序
与组件测试一样,在某些情况下,自动化集成的回归测试可以增强信心,因为即使产品有变更也不会破坏已有的接口、组件或系统 。
4. 系统测试
定义:ST(System Test),验证软件产品是否符合质量特性要求的测试,侧重于整个系统或产品的行为和能力 ,通常会考虑系统可开展的端到端任务和开展这些任务时所展现的非功能行为,包括性能测试、安全性测试、兼容性测试、易用性测试 等。
测试类型 | 描述 |
---|---|
以下为功能特性的测试 | |
功能测试 | Functional Test,在一段时间内运行软件系统的所有功能,以验证软件系统有无严重错误。(正常功能、异常功能、边界测试、界面测试、接口测试、安全测试、错误处理测试等) |
用户界面测试 | |
安装/卸载测试 | |
可用性测试 | 面向用户的系统测试,让代表性用户尝试对产品进行典型操作,观察员和开发人员在一旁观察、记录。 |
以下为非功能特性的测试 | |
性能测试 | Performance Testing,测试系统在正常负载的情况下的性能,性能测试是用来衡量系统占用资源和系统响应、表现的状态。如果系统用完了所有可用的资源,那么系统性能就会明显地出现下降、甚至死机。 |
负载测试 | 在一定软硬件环境下,通过不断加大负载的手段来确定在满足性能指标情况下所能承受的最大用户数。即负载测试的目的是为了获取最大用户数,此时一般不超过 CPU 的 80% |
压力测试 | 压力测试也叫强度测试,通过高负载(90%)的手段来使服务器资源处于极限的状态,测试该系统在极限状态长时间运行是否稳定。 |
易用性测试 | 试图发现人为因素或易用性的问题 |
安全性测试 | 系统和数据的安全程度,包括功能使用范围、数据存取权限等受保护和受控制的能力。 |
兼容性测试 | 软件从一个计算机系统移植到另一个系统或环境的难易程度,或者是一个系统和外部条件共同工作的难易程度。 |
配置测试 | 配置测试将验证软件与其所依赖软件环境的依赖程度。 |
健壮性测试 | 也叫容错测试。测试系统出错时,能否在指定的时间间隔内修正系统错误并重启系统。 |
文档测试 | 对系统提交的文档进行验证,要求检查系统的文档是否齐全。 |
5. 验收测试
定义:acceptance testing,在系统测试的后期,以用户测试为主,或有测试人员等质量保证人员共同参与的测试,它也是软件正式交给用户使用的最后一道工序。验收测试分为 Alpha 测试 和 Beta 测试
-
Alpha 测试:由用户、测试人员、开发人员共同参与的内部测试
-
Beta 测试:公测,完全交给最终用户的测试
6. 其它测试
冒烟测试:在每个版本进行大规模的系统测试前,先验证软件的基本功能是否实现,是否具备可测试性。这个测试不是非常严格,不需要测试用例,只需要关注软件能否完成基本业务。
回归测试: 部分代码所做的变更, 无论是修复代码,还是其他类型的更改,都可能会意外地影响到其它代码的行为,不管是在同一组件内,还是在同一系统的其他组件中,甚至在其他系统中。正中变更也可能包括环境的变化 ,例如操作系统或数据库管理系统的新版本。这种意外的副作用被称为回归。回归测试的目的是运行测试来检测这些意外的副作用,需要运行一次所有的测试用例。
随机测试:测试时,抛开测试用例,按照自己对需求的理解,对软件进行测试,目的是模拟用户的真实操作,并发现一些边缘性的问题。
探索性测试:探索性测试是敏捷开发中的一种重要测试方法,测试时也抛开测试用例,但是有更具体的思考方向,测试人员自主识别系统的目的、功能,找到系统可能不稳定的区域,对这些区域进行测试。探索性测试与随机测试相比,虽然都是抛开测试用例根据测试人员的主观进行测试,但探索性测试更突出思考的特性。
四. 测试方法
测试方法 用于 编写测试用例,而测试方法在大体上划分为黑盒测试
和白盒测试
,但这种划分方式并不绝对,有些测试方法既可以划分为黑盒测试,也可以划分为白盒测试,emmm,也有那种黑白参半的灰盒测试
。
1. 黑盒测试
黑盒测试也叫功能性测试,该类测试注重于测试软件的功能性需求。采用这种测试方法, 测试工程师 把测试对象看作一个黑盒子,完全不考虑程序内部的逻辑结构和内部特性,只依据程序的《需求规格说明书》,检查程序的功能是否符合它的功能说明。
单元测试主要采用白盒测试方法,辅以黑盒测试方法。白盒测试方法应用于代码评审、单元程序之中,而黑盒测试方法则应用于模块、组件等大单元的功能测试之中。
黑盒测试的方法主要有:等价类划分法、边界值分析法、决策表法、因果图法和场景法。
等价类划分法:
定义:穷举无法实现,试图找到一个测试数据,使它代替一类数据。
使用方法:把所有可能输入的数据分为若干个等价类,然后从每一个等价类中选取少量的、具有代表性的数据作为测试用例。注意划分有效等价类和无效等价类
如果一个变量在某一个范围内,给它一个有效等价类两个无效等价类
如果一个变量取值在某一个集合范围内,可在集合内取一个有效等价类在集合外取一个 无效等价类
如果一个变量的条件是“必须怎样”、“一定会是怎样”则去一个值满足“必须要”的条件再取多个不满足的从多个角度去违背这个条件
如果一个变量是布尔类型,则取一个对的一个错的
边界值分析法:
定义:对输入或输出的边界值进行测试
有效范围:最小的、比最小大一点的、正常值、比最大小一点、最大值
无效范围:比最小更小、比最大更大
共7个,再分单缺陷和多缺陷,这样设计测试用例的个数就会指数上升
决策表法(判定表):
定义:分析和表达多逻辑条件下执行不同操作的情况的工具,严格且具有逻辑性,适合于问题有多个条件,条件有多种组合执行不同操作(有很多if、else if、else),不能表达循环结构
选项 \ 规则 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
条件桩 | 条件桩1:疲倦? | Y | N | N | N |
条件桩2:感兴趣? | * | N | Y | Y | |
条件桩3:读不懂? | * | * | N | Y | |
动作桩 | 动作桩1:重读本章 | √ | |||
动作桩2:继续读 | √ | ||||
动作桩3:下一章 | √ | ||||
动作桩4:休息 | √ |
关于判定表的简化:
在写出基本的判定表之后,当某几个条件桩组合起来有唯一的动作桩,则可以将这些情况组合起来,类似于数据库的依赖关系。
选项 \ 规则 1 2 3 条件桩 条件桩1: Y Y N 条件桩2: N N Y 条件桩3: Y N N 动作桩 动作桩1: 动作桩2: √ 动作桩3: √ √ 上表中的情况 1、2 可以简化为一种。
选项 \ 规则 1 3 条件桩 条件桩1: Y N 条件桩2: N Y 条件桩3: * N 动作桩 动作桩1: 动作桩2: √ 动作桩3: √
因果图法:
定义:是一种利用图解法分析输入的各种组合情况,从而设计测试用例的方法,它适合于检查程序输入条件的各种组合情况
输入条件与输出结果之间的关系:
-
恒等:若原因出现,则结果出现;若原因不出现,则结果也不出现
-
非:若原因出现,则结果不出现;若原因不出现,则结果出现
-
或:若几个原因中有一个出现,则结果出现;若几个原因都不出现则结果不出现
-
与:若几个原因都出现,结果才出现;若其中有一个原因不出现,则结果不出现
输入与输出的约束关系:
-
与:若几个原因都出现,结果才出现;若其中有一个原因不出现,则结果不出现
-
包含(或):表示a、b、c这3个原因中至少有一个必须成立
-
唯一:表示a,b,c中必须有一个成立,且仅有一个成立
-
R约束(要求)):表示当a出现时,b必须也出现
-
M约束(强制、屏蔽) :若a=1,则b必须为0;而当a为0时,b的值不定
贴图待补
场景法:
用例场景用来描述用例流经的路径,从开始到结束遍历整条路径上所有的基本流和备选流。
• 基本流:按照正确的业务流程实现的一条操作路径(模拟正确的操作流程)。
• 备选流:导致程序出现错误的操作流程(模拟错误的操作流程)。
![](file:///home/guyan/Public/knowledge-base/学习/0.专业知识/02.软件工程/软件测试/img_softtesting/005.黑盒测试-场景法.jpg?msec=1668309141773)
上图生成的场景如下:
场景1:基本流
场景2:基本流 备选流1
场景3:基本流 备选流1 备选流2
场景4:基本流 备选流3
场景5:基本流 备选流3 备选流2
场景6:基本流 备选流3 备选流2 备选流1
场景7:基本流 备选流4
场景8:基本流 备选流3 备选流4
2. 白盒测试
白盒测试方法根据模块内部结构,基于程序内部逻辑结构,针对程序语句、路径、变量状态等来进行测试。
白盒测试可分为静态白盒测试和动态白盒测试
静态:
-
代码检查法(桌面检查,代码走查,代码检查3种方式)
-
静态结构分析法(以图形方式表现程序内部结构)
-
静态质量度量法(根据ISO质量模型为基础,构造质量度量模型来评估软件各个方面)
动态:
-
逻辑覆盖法(语句覆盖,判定覆盖或分支覆盖,条件覆盖,判定-条件覆盖,路径覆盖)
-
基本路径测试法
-
域测试
-
符号测试
-
Z路径覆盖
-
程序变异等
此处主要讲述 逻辑覆盖法。
逻辑覆盖法:
逻辑覆盖法:语句覆盖(SC)、判定覆盖(DC)、条件覆盖(CC)、条件判定覆盖(CDC)、条件组合覆盖(MCC)、路径覆盖
逻辑覆盖法:通过对程序逻辑结构的遍历实现对程序的覆盖,它是
一系列测试过程的总称
在实现逻辑覆盖时,首先分析程序源代码并根据程序的源代码画出对应的程序结构图。
语句覆盖(SC)
要求:若干测试用例,应使程序中的每个可执行语句至少被执行一次
判定覆盖(DC)
要求:若干测试用例,使程序中每个判断的取真分支和取假分区至少经历一次,即判断真假值均被满足
条件覆盖(CC)
要求:若干测试用例,使每个判断中每个条件的可能取值至少被满足一次
条件/判定覆盖(CDC)
要求:条件和判定覆盖的交集。若干设计有用例,使判断条件中的所有条件可能取值至少被执行一次,同时,所有判断的可能结果至少执行一次
条件组合覆盖(MCC)
要求:若干测试用例,使判断中每个条件的所有可能至少出现一次,并且每个判断结果
路径覆盖
要求:每条可能的路径至少执行一次
路径测试就是从一个程序的入口开始,执行所经历的各个语句的完整过程。从
广义的角度讲,任何有关路径分析的测试都可以被称为路径测试。
完成路径测试的理想情况是做到路径覆盖,但对于复杂性大的程序要做到所有
路径覆盖(测试所有可执行路径)是不可能的,特别是在包含循环结构的程序中
基本路径测试步骤:
-
以详细设计或源代码作为基础,导出程序的控制流图G
-
计算控制流图G的圈复杂度V(G),导出程序基本路径集中的独立路径数目,这是确定程序中每个可执行语句至少执行一次所必须的测试用例数目的上界
-
确定程序的基本路径
-
生成测试用例,确保基本路径集中每条路径的执行
各逻辑覆盖的关系
- 条件组合覆盖>判定覆盖>语句覆盖(即如果达到条件组合覆盖,就达到判定覆盖和语句
- 覆盖:如果达到判定覆盖,就达到语句覆盖,下面类似理解)。
- 条件组合覆盖>条件覆盖。
- 条件覆盖不一定包含判定覆盖、语句覆盖。
- 判定覆盖不一定包含条件覆盖。
- 路径覆盖,判定覆盖>语句覆盖
参考
-
软件测试艺术——Glenford J.Myers
-
软件测试 —— 朱少民