软件测试
什么是软件测试?软件测试的目的
软件测试是为了尽快尽早地发现在软件产品中所存在的各种软件缺陷而展开的贯穿整个软件开发生命周期,对软件产品(包括阶段性产品)进行验证和确认的活动过程。
软件质量模型
-
Bohm质量模型(1976年提出)
-
McCall质量模型(1979年提出)
-
ISO的软件质量模型
- 外部质量模型和内部质量模型
- 使用质量模型
外部和内部质量模型:
- 功能性:是指软件产品在指定条件下使用时,提供满足明确和
隐含要求的功能的能力。 - 可靠性:是指在特定条件下使用时,软件产品维持规定的性
能级别能力。 - 易用性:是指用户在指定条件下使用软件产品时,产品被用户理解、学习、使用和
吸引用户的能力。简单10个字:易懂、易学、易用、漂亮好看。 - 效率:是指在规定条件下,相对于所用资源的数量,软件产品
可提供适当的性能的能力。通常,效率就是我们常说的
产品性能。 - 维护性:是指产品可被修改的能力。这里的修改是指纠正、改进软件产品和软件产
品对环境、功能规格变化的适应性。 - 可移植性:是指软件产品从一种环境迁移到另外一种环境的能力。这里的环
境,可以理解为硬件、软件或组织等不同的环境。
测试工作流程
软件测试分类
- 测试是否执行程序
- 静态测试和动态测试
- 测试是否针对系统的内部结构和具体实现算法来完成测
试- 黑盒测试和白盒测试
- 从测试的对象和范围
- 单元测试、集成测试、系统测试、验收测试、回归测试、灰度
测试、文档测试
- 单元测试、集成测试、系统测试、验收测试、回归测试、灰度
- 测试的目标:
- 性能测试、安全性测试、兼容性测试、安装测试等
- 流量测试、电量测试、弱网络测试
- 测试方式:
- 手动测试、自动化测试
静态测试
不运行被测试程序,对代码通过检查、阅读进行分析。通过走查和审查两种方式。
评审通常在审查会后进行,审查小组根据记录和报告进行评估。
静态测试分类
- 代码静态测试:主要测试代码是否符合相应的标准和规范。
- 界面静态测试:主要测试软件的实际界面与需求中的说明是否相
符。 - 文档静态测试:主要测试用户手册和需求说明是否真正符合用户
的实际需求。
静态代码检查工具
- CheckStyle
- PMD
- FindBug
- SourceMonitor
- JTest
动态测试
指通过运行被测程序,检查运行结果与预期结果的差异,来分析软件质量(如功能性、效率、可靠性)的过程。
动态测试的步骤:
- 设计测试用例
- 搭建测试环境
- 编写测试程序(脚本)
- 执行测试
- 分析测试结果
白盒测试
通过分析被测单元的内部程序结构来设计测试用例
逻辑覆盖
- 语句覆盖:设计若干条测试用例,使程序中每条可执行语句至少执行一次。是最弱的覆盖。
- 判断覆盖(分支覆盖):设计测试用例,使程序中的每个逻辑判断的取真和取假的分支至少经历一次。无法检测判定内部的错误,仍是最弱的覆盖标准。
- 条件覆盖:设计若干条测试用例,使程序中每个判断中的每个条件的可能取值至少满足一次。
- 判断-条件覆盖:使判定中每个条件的可能至少满足一次,并且使每个判定分支至少执行一次。能同时满足判定、条件两种覆盖标准。
- 条件组合覆盖:使得每个判断表达式中的条件的各种组合都至少出现一次。
- 路径覆盖:设计足够多的测试用例,覆盖程序中的每条可能路径。
控制流图
流程图转化为控制流图
圈复杂度(Cyclomatic complexity Metric)
代码逻辑复杂度的度量,提供了被测代码的路径数量。(基本路径数的上界)复杂度越高,出错的概率越大。
- V(G) = 区域数量(由节点、连线包围的区域,包括图形外部区域)
- V(G) = 连线数量 - 节点数量 + 2
- V(G) = 分支节点+ 1
如何衡量测试效果
- 覆盖率是测试覆盖质量的一个重要指标,通过测试覆盖率的统计,可以帮助改善测试用例,提高测试
质量。 - 覆盖率检查的标准有逻辑覆盖、循环覆盖和基本路
径覆盖等。 - 需要通过工具对软件测试覆盖结果进行考察。
覆盖率分析工具
JUnit框架下有EclEmma、Jcoverage、Jcoco等;
在NUnit框架下有Ncover;
针对C/C++语言有与GCC配套的Gcov工具;
Eclipse IDE有Coverlipse插件;
Maven在调用测试代码和代码覆盖率分析方面有强大
的功能;
其他的还有Cobertura、Quilt和JCoverage等
代码覆盖率检测工具
Codecover
JaCoCo(EclEmma)
黑盒测试
把被测程序视为一个不能打开的黑盒子,在完全不考虑程序内部结构和内部特性的情况下进行的测试 。
分为功能性测试和非功能性测试。
等价类划分法
所谓等价类是指某个输入域的子集合。n等价类划分法是把所有可能的输入数据,即程序的输入域划分为若干部分(子集),然后从每一个子集中选取少数具有代表性的数据作为测试用例。等价类是输入域的某个子集合,而所有等价类的并集就是整个输入域。因此,等价类对于测试有两个重要的意义:完备性,整个输入域提供一种形式的完备性;无冗余性,若互不相交则可保证一种形式的无冗余性。
-
有效等价类:有意义的、合理的输入数据所组成的集合。能够检验程序是否实现了规格说明中预先规定的
功能和性能。 -
无效等价类:无意义的、不合理的输入数据所构成的集合。可以鉴别程序异常处理的情况,检查被测对
象的功能和性能的实现是否有不符合规格说明要求的地方。
在设计测试用例时,应同时考虑有效等价类和无效等价类测试用例的设计。
边界值分析法
选取正好等于、刚刚大于或刚刚小于边界的值作为测试数据,而不是选取等价类中的典型值或任意值。
判定表法
单元测试
单元测试是对软件基本组成单元进行的测试,一般在代码完成后由开发人员完成,QA人员辅助。
为何要进行单元测试?
- 尽早发现错误
- 错误发现越早,成本越低
- 发现问题比较容易
- 修正问题更容易
- 检查代码是否符合设计和规范,有利于将来代码的维护
单元测试的目标和任务
目标::单元模块被正确编码
任务:单元测试针对每个程序模块进行,解决以下五个方面的问题
- 模块接口测试
- 模块局部数据结构测试
- 错误处理检测
- 路径测试
- 模块边界条件测试
静态测试
- 设计测试用例
- 搭建测试环境
- 编写测试程序(脚本)
- 执行测试
- 分析测试结果
什么情况下使用MOCK对象
MOCK对象是真实对象在调试期间的替代品。
以下情况使用MOCK对象:
- 真实对象行为不确定(如股票行情)
- 真实对象很难被创建
- 真实对象的某些行为很难被触发
- 真实对象令程序的运行很慢
- 真实对象有(或者是)用户界面
- 测试含有回调函数
- 真实对象并不存在
MOCK对象工具:Jmock、EasyMock
性能测试
性能测试是为了发现系统性能问题或获取系统性能相关指标而进行的测试。
一般在真实环境、特定负载条件下,通过工具模拟实际软件系统的运行及其操作,同时监控性能各项指标,最后对测试结果进行分析来确定系统的性能状况。
性能具体指标
- 数据传输的吞吐量(Transactions)
- 数据处理效率(Transactions per second)
- 数据请求的响应时间(Response time)
- 内存和CPU使用率
- 连接时间(Connect Time)、发送时间(Sent Time)
- 处理时间(Process Time)、页面下载时间
- 第一次缓冲时间
- 每秒(SSL)连接数
- 每秒事务总数、每秒下载页面数
- 每秒点击次数、每秒HTTP 响应数
- 每秒重试次数
性能测试类型
- 性能验证测试,验证系统是否达到事先已定义的系统性能指标、能否满足系统的性能需求
- 性能基准测试,在系统标准配置下获得有关的性能指标数据,作为将来性能改进的基准线
- 性能规划测试,在多种特定的环境下,获得不同配置的系统的性能指标,从而决定在系统部署时采用什么样的软、硬件配置
- 容量测试,也可以看作性能的测试一种,因为系统的容量可以看作是系统性能指标之一
负载测试和压力测试辨析
负载测试的目标是测试在一定负载情况下,系统的性能;
实际中,我们常从较小的负载开始,逐渐增加模拟用户的数量,观察不同负载下,系统的响应时间,所耗资源,直到超时或资源耗尽,这就是所说的负载测试;
压力测试(Stress test),是模拟实际应用的软硬件环境及用户使用过程的系统负荷,长时间或超大负荷地运行测试软件,来测试被测系统的性能、可靠性、稳定性等。
前端测试工具
-
Fiddler(Microsoft)
-
ySlow-YAHOO
前端可以优化的点
- 静态资源无缓存,增加缓存;
- JS较大,无压缩,存在重复请求,压缩并去除重复请求,或合并;
- JS位置不合理,移动到页面加载的最末端;
- 外部CSS 依赖较多,尽量去除依赖,或放置到自己的服务器端;
- Banner图片较大,且多,无压缩,压缩并缩小图片大小;
- 后台接口请求较多,可以合并;
- 页面存在请求失败和跳转的外部资源,去除失败和跳转的外部资源连接;
- 外部依赖接口较慢,去除或缓存或优化;
- 页面请求数较多,主要是和重复加载,去除冗余的加载。
安全性测试
举例:
- 跨站点脚本(cross-site scripting,XSS)攻击;
- SQL注入式漏洞;
- URL和API的身份验证
- 缓冲区溢出;
- 不安全的数据存储或传递;
- 不安全的配置管理;
- 有问题的访问控制,权限分配有问题;
- 口令设置不严,包括长度、构成和更新频率
- 暴露的端口或入口;
安全测试的范围
- 系统级别的安全性
- 应用程序级别的安全性 (重点)
- 用户权限
- 数据输入验证
- 敏感数据加密
- 数据存储安全性
- 用户口令
- 验证系统的日志文件是否得到保护
- 安全功能测试 (Security Functional Testing):数据机密性、完整性、可用性、不可否认性、身份认证、授权、访问控制、审计跟踪、委托、隐私保护、安全管理等
- 安全漏洞测试 (Security Vulnerability Testing):从攻击者的角度, 以发现软件的安全漏洞为目的。安全漏洞是指系统在设计、实现、操作、管理上存在的可被利用的缺陷或弱点
安全性测试方法
-
基于漏洞的方法, 从软件内部考虑其安全性,识别软件的安全漏洞。如借助于特定的漏洞扫描器。
-
基于威胁的方法,从软件外部考察其安全性,识别软件面临的安全威胁并测试其是否能够发生
-
模拟攻击测试是一组特殊的、极端的测试方法,如Fuzzing,使用大量有效的数据作为应用程序的输入,以程序是否出现异常为标志,来发现应用程序中可能存在的安全漏洞
-
白盒方法
- 用商业的统计分析工具
- 对源码的内审
- 借助工具 Coverity /Fortify 等
-
黑盒方法
- 错误注入(Fault injection)
- Dumb Fuzzing
-
灰盒方法
- Smart Fuzzing / Intelligent fuzzing
web安全性测试
-
注入攻击(Injection)
-
跨站点脚本工具(XSS)
-
跨站点请求伪造(CSRF)
-
未能限制URL访问 (Failure to Restrict URL Access)
安全漏洞检测工具
- CppCheck
- Findbugs
- C++Test/Jtest
- Knocwork insight
- Metasploit
- WebScarab
- Fortify SSC
- Burp suite:用于攻击Web应用程序的集成平台
- Nikto:Web服务器扫描程序
- Paros proxy:web代理程序,可评估Web应用程序的漏洞
- TamperIE:小巧的XSS漏洞检测辅助工具
- Tripwire:常用的开放源码的完整性检查工具
- Wapiti:安全测试工具,直接对网页进行扫描
- Whisker/Wikto:使用LibWhisker的扫描程序(HTTP测试)
- 网络监控工具主要有Nessus、Wireshark、Snort、Netcat等
容错性测试
容错性测试是检查软件在异常条件下自身是否具有防护性的措施或者某种灾难性恢复的手段。如当系统出错时,能否在指定时间间隔测试包括两个方面:
- 输入异常数据或进行异常操作,以检验系统的保护性。如果系统的容错性好的话,系统只给出提示或内部消化掉,而不会导致系统出错甚至崩溃。
- 灾难恢复性测试。通过各种手段,让软件强制性地发生故障,然后验证系统已保存的用户数据是否丢失、系统和数据是否能尽快恢复。
故障转移测试
检查系统是否具备某种灾难性恢复的手段.。当系统局部或全部出错时,能否在指定时间内修正错误。 具有良好故障恢复的系统,当遇到软件原因或无法克服的自然原因时,能够进行故障的转移与恢复。使用户最低限度的感受到故障的发生。
在服务器的Failover测试中, 将包括多种情况, 如:
- 客户机或服务器掉电;
- 客户机与服务器网络中断;
- 服务器相关的程序CRASH;
- 系统中全部或部分CORE SERVER出现掉电/网络中断情况
兼容性测试
软件兼容性测试是指验证软件之间是否正确地交互和共享信息。
兼容性包括:
- 硬件兼容。
- 软件之间兼容。
- 数据之间兼容。
向前和向后兼容:
- 向后兼容是指可以使用软件的以前版本。
- 向前兼容指的是可以使用软件的未来版本。
缺陷管理
缺陷:最终产品同用户的期望不一致。
- 功能错误
- 功能遗漏
- 超出需求的部分
- 性能不符合要求
为了更好地分析缺陷,需要对缺陷在严重程度、优先级以及状态上加以区分。
- 缺陷严重程度;
- 致命的:造成系统获应用程序奔溃、死机、系统悬挂或造成数据丢失、主要功能完全丧失。
- 严重的:指功能或特性没有实现,主要功能部分丧失,次要功能完全丧失,或致命的错误声明。
- 一般的:不影响系统的基本使用,但没有很好地实现功能,没有达到预期效果。如次要功能丧失,提示信息不准确,或用户界面差,操作时间长等。
- 微小的:对功能没有影响,产品及属性仍可使用,如有个别错别字、文字排版不整齐等。
- 缺陷优先级;
- 立即解决(P1级):缺陷导致系统几乎不能使用或测试不能继续,需立即修复
- 高优先级(P2级):缺陷严重,影响测试,需要优先考虑
- 正常排队(P3级):缺陷需要正常排队等待修复
- 低优先级(P4级):缺陷可以在开发人员有时间的时候被纠正
- 缺陷状态;
严重程度高的软件缺陷具有较高的优先级吗?
- 一般是。严重程度高说明缺陷对软件造成的质量危害性大。
- 严重程度高优先级不一定高。
- 如果某个严重的软件缺陷只在非常极端的条件产生,则没有必要马上解决。
- 如果修正一个软件缺陷,需要重新修改软件的整体架构,可能会产生更多潜在的缺陷,而且软件由于市场的压力必须尽快发布,此时即使缺陷的严重性很高,是否需要修正,需要全盘考虑。
- 严重程度低优先级不一定低。
- 例:软件名称或公司名称的拼写错误。
如何进行缺陷管理
- 按照测试种类划分
- 按功能模块划分
- 按Bug生命周期划分
- 新建(new):由测试人员发现并提交
- 已分配(assigned):开发人员接收了该Bug
- 解决(fixed):开发人员解决了该Bug,并给测试人员回归测试;
- 关闭(closed):测试人员回归测试确认已经解决
- 重新打开(reopen)
缺陷报告
- 缺陷分布报告,允许将缺陷计数作为一个或多个缺陷参数的函数来显示,生成缺陷数量与缺陷属性的函数。如测试需求和缺陷状态、严重性的分布情况等。
- 缺陷趋势报告,按各种状态将缺陷计数作为时间的函数显示。趋势报告可以是累计的,也可以是非累计的;
- 缺陷年龄报告,显示缺陷处于活动状态的时间,展示一个缺陷处于某种状态的时间长短,从而了解处理这些缺陷的进度情况。
- 测试结果进度报告,展示测试过程在被测应用的几个版本中的执行结果以及测试周期。
缺陷管理工具
- 禅道
- TestIn