文章目录
一、软件危机
(一)概念
** 软件危机是指在计算机软件的开发和维护过程中所遇到的一系列严重问题**。概括地说,软件危机包含下述两方面的问题:如何开发软件,以满足对软件日益增长的需求;如何维护数量不断膨胀的已有软件
具体的说,软件危机主要有以下一些典型表现:
- 对软件开发成本和进度的估计常常很不准确
- 用户对“已完成的”软件系统不满意的现象经常发生
- 软件产品的质量往往靠不住
- 软件常常是不可维护的
- 软件通常没有适当的文档资料
- 软件成本在计算机系统总成本中所占的比例逐年上升
- 软件开发生产率提高的速度,远远跟不上计算机应用迅速普及深入的趋势
(二)产生软件危机的原因
在软件开发和维护的过程中存在这么多严重问题,一方面与软件本身的特点有关,另一方面也和软件开发与维护的方法不正确有关
软件不同于硬件,它是计算机系统中的逻辑部件而不是物理部件。由于软件缺乏“可见性”,在写出程序代码并在计算机上试运行之前,软件开发过程的进展情况较难衡量,软件的质量也较难评价,因此,管理和控制软件开发过程相当困难。此外,软件在运行过程中不会因为使用时间过长而被“用坏”,如果运行中发现了错误,很可能是遇到了一个在开发时期引入的在测试阶段没能检测出来的错误。因此,软件维护通常意味着改正或修改原来的设计,这就在客观上使得软件较难维护
目前相当多的软件专业人员对软件开发和维护还有不少糊涂观念,在实践过程中或多或少地采用了错误的方法和技术,这可能是使软件问题发展成软件危机的主要原因。而与软件开发和维护有关的许多错误认识和作法的形成,可以归因于在计算机系统发展的早期阶段软件开发的个体化特点。错误的认识和作法主要表现为忽视软件需求分析的重要性,认为软件开发就是写程序并设法使之运行,轻视软件维护等
(三)消除软件危机的途径
为了解决软件危机,既要有技术措施(方法和工具),又要有必要的组织管理措施。软件工程正是从管理和技术两方面研究如何更好地开发和维护计算机软件的一门新兴学科
二、软件过程模型
(一)软件生命周期概念
一个软件从定义、开发、使用和维护,直到最终被废弃,要经历一个漫长的时期。这就如同一个人要经过胎儿、儿童、青年、中年和老年,直到最终死亡的漫长时期一样。我们通常把软件经历的这个漫长的时期称为软件生命周期,如图:
软件有生命周期,那么就会有针对生命周期设计的执行模型,模型中规定了把生命周期划分成哪些阶段及各个阶段的执行顺序,因此也称为过程模型/开发模型
(二)软件开发模型
1. 瀑布模型
瀑布模型的设计其实就是按照软件生命周期一步一步进行的,一步一文档。它是所有其他模型的基础框架
- 特点:线性的开发流程,不能够应对需求的变化
- 缺陷:测试后置
- 风险往往在后期的测试阶段才显露,失去了及早纠正的机会
- 要有足够的时间预留给测试活动,否则将导致测试不充分,从而把缺陷遗留给用户
最大的缺陷在于可以运行的产品很迟才能看到
- 适用场景:需求固定的小项目
2. 螺旋模型
螺旋模型是在瀑布模型的基础上在每一步都引入了风险分析,每次分析完成之后会生成一个新的原型
- 优点:风险分析能力和产品遗留的风险是成反比的,因此使 用这种模型会极大降低产品遗留的风险
- 缺陷:时间拉长,人力、资金会存在更多的消耗
- 适用场景:规模庞大、复杂度高、风险大的项目
3. 增量模型和迭代模型
这两个模型对比非常明显,因此放在一起介绍
** 增量模型是将一整个项目分成多个部分,同时进行开发,一个部分开发完成,就能让客户使用,以后每完成一部分,就在原有的基础上进行集成。这种方式听起来很好,既能及早的看到项目,也能针对一个模块及早发现问题。但是构建如何集成在一起,对于开发人员是个极大的挑战,一旦出问题,很可能整个项目都毁于一旦
** 迭代模型:与增量模型不同的是,迭代模型就是把项目看作一个整体,由开发人员先开发一个基础版本,但是功能比较简陋,之后多次进行版本迭代优化
增量模型
4. 敏捷模型
敏捷宣言
- 个体与交互重于过程和工具
- 可用的软件重于完备的文档
- 客户协作重于合同谈判
- 响应变化重于遵循计划
在每对比对中,后者并非全无价值,但我们更看重前者
四句宣言表达了敏捷模型的一个特点:轻流程、轻文档、重目标、重产出,而这种方式,感觉更适合互联网公司
敏捷开发有很多种,其中scrum是比较流行的一种
scrum
三个角色
- 产品经理:收集用户的需求,编写需求文档,对产品负责的人
- 项目经理:负责召开各种会议,协调项目,为研发团队服务,也就是在研发团队后面催着赶工期的人
- 研发团队:开发人员、测试人员等
五个会议
首先,项目组里会有一个需求待办列表,即需求池,里面专门放没有实现的用户需求,由产品负责人进行整理
- 发布计划会议:产品经理从需求池里选取几个需求,开展发布计划会议,介绍需求内容,具体要实现哪些功能
- 迭代计划会议:将发布计划会议中的所有需求进行分配,并明确负责人,初步估计完成工时
- 每日例会(每天,持续2~4周):时间很短,就是让团队成员说明一下自己昨天做了什么,今天计划做什么,有什么问题。做到及时了解项目进度、预知风险并规避
- 演示会议:需求完成,这个时候只有项目组的成员会使用,因此需要负责人进行演示,期间把大家的反馈记录下来,进行总结,形成新的需求,进入需求池
- 回顾会议:项目团队对本期迭代进行总结,发现不足,制定改进计划,以达到持续改进的效果
三、测试的一些基本概念
(一)什么是软件测试
测试在我们日常生活中是很常见的一个现象,而对软件而言,最常见的理解就是:软件测试就是找bug,发现缺陷。就是验证软件产品特性是否满足用户的需求
特点:软件测试只是一个样本试验,具有不可穷尽性
(二)软件测试和调试的区别
- 目的不同
- 调试:找出并解决bug
- 测试:找出bug
- 参与角色不同
- 调试:开发人员
- 测试:测试人员和开发人员(开发人员会进行单元测试等)
- 执行阶段不同
- 调试:一般在开发阶段
- 测试:贯穿整个软件开发生命周期
(三)需求概述
在多数软件公司里,会有两部分需求,一部分是用户需求,一部分是软件需求
- 用户需求:甲方的需求,往往比较简略
- 软件需求:具体描述开发人员必须要实现的功能。要将用户需求转变为软件需求需要进行技术可行性研究和市场可行性分析等等
(四)bug概述
1. 概念
** 当且仅当规格说明是存在的并且正确,程序与规格说明之间的不匹配才是错误**,当需求规格说明书没有提到的功能,判断标准以最终用户为准:当程序没有实现其最终用户合理预期的功能要求时,就是软件错误
2. 如何描述一个bug
一个合格的 bug 描述应该包括以下几个部分:
- 标题
标题要用尽量短的话说明bug出现环境和bug的表现 - 问题出现的环境。
环境分为硬件环境和软件环境。web项目需要告知操作系统、浏览器类型与版本等;app项目则需要描述机型、分辨率、操作系统版本等 - 发现问题的项目版本。
开发人员需要知道出现问题的版本,才能获取对应版本的代码来重现故障 - 错误重现的步骤
描述问题重现的最短步骤。某些bug如果操作步骤不同,可能bug不一定会出现,因此需要说清每一步的操作步骤 - 用户或软件需求中期望看到的结果
要让开发人员知道正确的结果应该是什么样的,尤其要以用户的角度来描述程序的行为是怎样的。如果是依据软件需求报告提出的问题,最好写明需求来源 - 错误结果展示
描述错误的现象。比如登录界面登录按钮消失可以截图 - 其他
包括bug类型、bug等级等等
3. bug的级别
不同公司对bug等级的描述是不同的,我们这里只是列举一种描述bug等级的方式,这也就要求我们如果作为测试人员进入公司,就要先阅读公司关于bug等级的说明。具体bug等级包括以下四类:
- 1级bug(致命错误)
阻碍开发或测试工作的问题;造成系统崩溃、死机、死循环、导致数据库数据丢失、与数据库连接错误、主要功能丧失、基本模块缺失等非常严重的问题 - 2级bug(严重错误)
系统主要功能丢失;错误的波及面很广、数据保存后数据库数据信息错误、密码明文显示、页面空白等等 - 3级bug(一般错误,该问题实际测试中出现最多)
功能没有完全实现但不影响使用,功能菜单存在缺陷但不会影响系统稳定性。如:操作等待时间长、查询时间长、格式错误、数据库中字段过多等问题 - 4级bug(次要错误)
一般是页面排版显示的问题,不影响操作功能的执行,可以优化性能的方案等。如:错别字、界面格式不规范、页面显示重叠、文字排版不整齐等等
4. bug的生命周期
与bug的级别一样,不同公司对bug生命周期的定义都是不一致的,这里只是说一种常见的例子。测试人员应该跟踪一个bug的整个生命周期,从Open到Close的所有状态。我们先介绍一下各个状态的定义
- New:测试人员新发现了一个bug
- Open:开发人员拿到bug的说明文档后,经过评审认定它就是一个bug
- Rejected:经过评审认定它不是一个bug,拒绝修改
- Delay:虽然认定是一个bug了,但是认为暂时不需要修改或者暂时不能修改,即选择延后修改
- Fixed:开发人员进行修改后标识这个bug为修改状态,表示已修改,让测试人员进行回归测试验证
- Reopen:测试人员经过验证发现bug仍然存在,则需要重新打开bug,让开发人员进行修改
- Closed:修改状态的bug经测试人员的回归测试验证通过,则关闭bug
(五)测试用例
** 测试用例(Test Case)是为了实施测试而向被测试的系统提供的一组集合。这组集合包含:测试环境、操作步骤、测试数据、预期结果等要素**。主要是为了解决两大问题:测什么和怎么测
设计测试用例的要素:测试环境,测试步骤、测试数据、预期结果等
1. 设计测试用例的万能思路
* 功能测试
* 界面测试
* 性能测试
* 兼容性测试
* 易用性测试
* 安全测试
例如设计水杯的测试用例
2. 设计测试用例的方法
-
基于有需求的案例来设计测试用例
大概的设计就是根据需求进行分析有哪些功能,确定测试哪些点,设计测试用例,比如可以通过穷举法 -
等价类法
概念:针对需求输入范围划分成若干个等价类,从每个等价类中随机选取一个用例,若该用例通过,则认为它所代表的那个等价类也是通过的
等价类的理解参考图书馆的图书摆放,一类的书一定是放在一块儿的,因此我们如果要找某一类的书,我们只需要随便拿起一本看这片地方的书是什么类型的来判断这块儿地方是不是我们要找的那一类的书籍,而不需要一本一本一个一个进行查找 -
边界值法
边界值法是对等价类法的补充,我们如果只通过等价类法进行测试,势必会易漏很多需要重点关注的点
比如:2月14日活动截止,那么我们设定正确标准的写法应该是"time <= 2.14 23:59:59"或"time < 2.15 00:00:00",因此2.14 23:59:59就是我们的边界值,而2.14 23:59:58 和 2.15 00:00:00就是我们的次边界值 -
判定表法
判定表是一种表达逻辑判断的工具,适用场景:需要考虑输入之间的组合关系,不同的组合关系对应的输出结果不同
判定表设计测试用例的步骤:- 确认输入条件和输出条件
- 找出输入条件和输出条件之间的关系
- 画判定表
- 根据判定表编写测试用例
-
正交法
特点:- 每一列中,不同的数字出现的次数相同
- 任意两列之间数字的排列方式齐全且均衡
正交表我们要寻找到两个参数,因素数和水平数;因素数是指输入的条件,水平数是指每个输入条件能选择的值或行为(例如注册时选择电话是否填写
设计正交表很麻烦,我们可以利用allparis工具进行自动生成
通过正交法设计测试用例的步骤(L4(23)),其中L是指正交表,4是试验次数,3是因果数,2是水平数- 找到因果数和水平数
- 用allparis工具来生成正交表
- 根据正交表来编写测试用例
- 补充测试用例(allparis工具生成的测试用例可能不完整,一些特殊测试用例需要我们手动添加)
-
场景设计法
分为基本事件流和多个备用事件流,正常情况下我们应该按照哪个流程进行活动称为基本事件流,其他可能遇到的意外情况就是备用事件流。编写测试用例时要求我们根据基本事件流和备用事件流的数量进行逐个设计 -
错误猜测法
这个方法纯靠测试人员的个人工作经验和积累
(六)软件测试生命周期
- 可行性研究
站在用户的角度:查看需求逻辑是否正确,是否符合用户的需求和行为习惯;站在开发人员的角度:思考需求是否可以实现,或者实现起来难度大小 - 需求分析
制定测试计划(包括但不限于测试的工时,人力的安排等等) - 测试设计与测试开发
设计测试用例,经验丰富的测试人员可以进行白盒测试 - 测试执行
参考测试用例来执行测试 - 测试评估
测试人员需要记录测试,做好缺陷管理,然后进行测试的评估
因此我们说,软件测试贯穿于软件的整个生命周期!
(七)测试模型
1. V模型
V模型的过程和软件生命周期几乎一样
概要设计阶段是指设计整体架构和框架,详细设计模块与模块之间的详细设计
单元测试阶段和集成测试阶段通常由开发人员来执行
- 特点:
- 明确标注了测试的类型
- 明确标注了测试阶段和开发阶段之间的关系
- 缺点:测试后置
2. W模型(双V模型)
** 最重要的也是最大的优点就是测试从获取用户需求阶段就开始介入了**
缺点:
- 上一个阶段完成下一个阶段才能开始
- 开发模型和测试模型也保持着一种前后的线性关系
也因为这种模型重文档,重过程,因此不支持敏捷开发
(八)测试分类
1. 按照测试对象划分
-
界面测试
界面测试(简称UI测试),指按照界面的需求(一般是UI设计稿)和界面的设计规则,对我们软件界面所展示的全部内容进行测试和检查,一般包括如下内容:- 验证界面内容显示的完整性,一致性,准确性,友好性。比如界面内容对屏幕大小的自适应,换行,内容是否全部清晰展示;
- 验证整个界面布局和排版是否合理,不同板块字体的设计,图片的展示是否符合需求
- 对界面不同控件的测试,比如,对话框,文本框,滚动条,选项按钮等是否可以正常使用,有效和无效的状态是否设计合理;
- 界面的布局和色调符合当下时事的发展
** 常见的界面错误包括:重叠,截断,文字不合理自动换行等**
-
可靠性测试
可靠性即可用性,是指系统正常运行的能力或者程度
可靠性 = 正常运行时间/(正常运行时间 + 非正常运行时间)* 100%
系统非正常运行的时间可能是由于硬件,软件,网络故障或任何其他因素(如断电)造成的,这些因素能让系统停止工作,或者连接中断不能被访问,或者性能急剧降低导致不能使用软件现有的服务
** 可用性指标一般要求达到4个或者5个9,即99.99%或者99.999%** -
容错性测试
容错性测试是指系统能够处理异常,用户的错误操作而不至于系统崩溃,从而能够提高系统的可用性
容错性测试包括下面几个方面:- 输入异常数据或进行异常操作,以检验系统的保护性。如果系统容错性好,系统只给出提示或内部消化掉,而不会导致系统出错甚至崩溃。比如数据级测试、校验测试、环境容错性测试、界面容错性测试
- 灾难恢复性测试。通过各种手段,让软件强制性地发生故障,然后验证系统已保存的用户数据是否丢失,系统和数据是否能尽快恢复
-
文档测试
文档包括开发文件,用户文件,管理文件等。- 开发文件:可行性研究报告,软件需求、数据要求、概要设计、详细设计、数据库设计说明书,模块开发卷宗等。
- 用户文件:用户手册、操作手册、用户文档的使用
- 管理文件:项目开发计划、测试计划、测试分析报告、开发进度月报、项目开发总结报告
文档测试的关注点: - 文旦的术语
- 文档的正确性
- 文档的完整性
- 文档的一致性
- 文档的易用性
-
兼容性测试
明确要测试的兼容环境,考虑软硬件的兼容 -
易用性测试
- 标准型和规范性
- 直观性
- 灵活性
- 舒适性
-
安装卸载测试
- 软件不同的安装和卸载方式
- 应用是否可以在不同的系统、版本下安装
- 安装或者卸载过程中是否可以手动暂停,或者取消
- 安装空间不足时系统是否会有提示
- 是否可以正常的卸载、以及应用软件的各种卸载方式
- 卸载和安装过程中出现环境问题,软件是否可以正常并且合理的应对。比如死机、断电、断网等
-
安全测试
系统常见的安全漏洞和威胁如下:- 输入域,如输入恶行或者带有病毒的脚本或长字符串
- 代码中的安全性问题,比如:SQL/XML注入
- 不安全的数据存储或者传递
- 数据文件、邮件文件、系统配置文件等里面有危害系统的信息或者数据
- 有问题的访问控制,权限分配等
- 假冒ID:身份欺骗
- 对数据的恶意修改,破坏数据的完整性
常用的安全测试方法包括代码评审、渗透测试、安全运维等
-
性能测试
常见的性能问题:- 资源泄露
- 资源瓶颈
- 线程死锁,线程阻塞
- 查询速度慢或效率低
- 受外部系统影响越来越大
衡量一个系统性能好坏的关键性指标有:用户响应时间,事务平均响应时间(TPS),吞吐率,每秒点击次数,内存和CPU使用率等等
-
内存泄漏测试
常见内存泄漏问题:- 分配完内存忘记回收
- 程序写法有问题,造成没办法回收(如死循环造成无法执行到回收步骤)
- 某些API函数的使用不正确,造成内存泄漏
内存泄露的检测方法: - 人工静态法:代码走读,人工查找未被回收的内存
- 自动工具法:借助相应测试内存泄漏的工具,如Visual Leak Detector,记录每次内存分配,清楚告诉用户内存是如何泄漏的
2. 按是否查看代码划分
- 黑盒测试
** 黑盒测试就是在完全不考虑程序逻辑和内部结构的情况下,检查系统功能是否按照需求规格说明书的规定正常使用、是否能适当的接收输入数据而输出正确的结果,满足规范需求**,因此黑盒测试又称之为数据驱动测试,只注重软件的功能
优点:- 不需要了解程序内部的代码以及实现,不关注软件内部的实现
- 从用户角度出发设计测试用例,很容易的知道用户会用到哪些功能,会遇到哪些问题,锻炼测试人员的产品思维
- 测试用例是基于软件需求开发文档,不容易遗漏软件需求文档中需要测试的功能
** 缺点就是不可能覆盖所有代码**
** 黑盒测试的测试方法包括:等价类,边界值,判定表,正交法,场景法,错误猜测法等等**
- 白盒测试
** 白盒测试又称为结构测试或逻辑测试,它一般用来分析程序的内部结构,针对程序的逻辑结构来设计测试用例进行测试**
** 白盒测试的测试目的是,通过检查软件内部的逻辑结构,对软件中的逻辑路径进行覆盖测试;在程序不同地方设立检查点,检查程序的状态,以确定实际运行状态与预期状态是否一致**
** 白盒测试主要包含六种测试方法:语句覆盖,判定覆盖,条件覆盖,判定条件覆盖,条件组合覆盖,路径覆盖** - 灰盒测试
灰盒测试就是介于黑盒和白盒之间的测试,多用于集成测试阶段,不仅关注输出、输入的正确性,同时也关注程序内部的情况
3. 按开发阶段划分
- 单元测试
针对系统最小单元(人为规定)进行测试,一般是由开发人员来测试 - 集成测试
完成单元测试之后,将模块和模块之间进行集成,按照功能来进行测试,一般也是由开发人员来负责 - 冒烟测试
集成测试完成之后,需要交给软件测试人员,由测试人员来检查系统主要功能和主要的流程是否正常,评估软件/系统是否具备可测试的条件/可测试的标准,如果不具备,则直接打回 - 系统测试
这一步是测试人员真正进行测试的阶段,测试人员需要准备项目环境,将软件看作一个整体,对程序/系统进行系统测试,保证系统功能符合产品规格说明书的要求 - 回归测试
对历史版本、历史功能进行测试,保证功能符合要求。随着功能迭代越来越多,版本越来越多,回归测试的难度相对大一些,需要借助自动化测试来进行回归测试 - 验收测试
通常指的是用户来进行验证测试,目的就是为了验证产品/程序符合用户的需求。实际上主要是由产品/运营人员来进行验收
4. 按测试实施组织划分
-
α测试
α测试是由一个用户在开发环境下进行的测试,也可以是公司内部的用户在模拟实际操作环境下进行的测试。α测试的目的是评价软件产品的FLURPS(即功能、局域化、可使用性、可靠性、性能和支持)
注意:α测试不能由程序猿或测试员完成 -
β测试
β测试是一种验收测试,由软件的最终用户们在一个或多个场所进行
α测试和β测试的区别
- 测试的场所不同:Alpha测试是指把用户请到开发方的场所来测试;beta测试是指在一个或多个用户的场所进行的测试
- Alpha测试的环境是受开发方控制的,用户的数量相对比较少,时间比较集中;beta测试的环境是不受开发方控制的,用户数量相对比较多,时间不集中
- Alpha测试先于beta测试执行。通用的软件产品需要较大规模的beta测试,测试周期比较长
5. 按是否运行划分
- 静态测试
不运行被测软件,只是静态地检查程序代码、界面或文档可能存在的错误的过程 - 动态测试
实际运行被测程序,输入相应的测试数据,检查实际输出结果和预期结果是否相符
6. 按是否手工划分
- 手工测试
由人来一个一个的输入用例,然后观察结果
优点:自动化无法替代探索性测试,发散思维结果的测试
缺点:执行效率慢,量大易错 - 自动化测试
在预设条件下运行系统或应用程序,评估运行结果,预先条件应包括正常条件和异常条件。比如功能测试自动化、性能测试自动化、安全测试自动化
7. 按测试地域划分
- 国际化测试
- 本地化测试