Bobi.ink
2019-07-10
原文链接: Types Of Software Testing: Different Testing Types With Details
文章为意译,并且在原文的基础之上进行演绎和扩展
文章篇幅较长,阅读完大概20min,读完会有收获。欢迎点赞收藏关注
有多少软件测试类型呢?
我们作为测试人员了解很多种不同的软件测试类型,例如功能测试(Functional Test)、非功能测试、自动测试、敏捷测试、以及它们的各种子类型. 尽管在我们的测试过程中会接触很多种测试类型, 或者听说过某些测试类型,但是很少人敢说精通所有的测试类型.
每个测试类型都有自己的特点、优势和劣势。所以我写这篇文章,科普一下我们今天最常用的测试类型.
下面是软件测试的通用类型列表
来看看这些测试类型的细节
顾名思义, A/B测试就是准备两个(A/B)或两个以上的版本,让不同的用户来随机访问这些版本,收集各群组的用户体验数据和业务数据,最后分析、评估出最好版本,正式采用。如上图,谷歌使用A/B测试来决定导航应该是红色还是蓝色。
Alpha测试这是软件工程中很常见的测试类型。它的目标就是尽可能地在发布到市场或交付给用户之前找出所有的问题和缺陷。
Alpha测试一般在开发的末段且在Beta测试之前进行。在这个测试过程中可能会驱动开发者进行一些小(minor)的设计变动. Alpha测试一般在开发者网站进行,即只对开发者或内部用户开放,一般可以为此类测试创建内部虚拟的用户环境。
一般大型的软件项目都有规范化的软件版本周期:
举一个典型的例子, 最近把我坑得有点惨的iOS13的发布计划:
June 3: iOS 13 beta 1 and first look at WWDC 2019 # -> WWDC后就可以装的,相当于pre-alpha或Alpha阶段吧
June 17: iOS 13 beta 2 launched for developers
June 24: iOS 13 public beta release date for adventurous testers # -> 公开Beta版本,相当于上面说的Beta阶段
July 3: iOS 13 developer beta 3 launch with some new features
July 8: iOS 13 public beta 2 release date
Early September 2019: iOS 13 Golden Master (final dev beta) # -> 九月初,该发最终Beta版本了,相当于进入RC阶段了
Mid-September 2019: iOS 13 likely to launch with new 2019 iPhones # -> 正式版本
现在很多开源项目,已经淡化了瀑布式的软件版本周期,变成一种持续(Continuous)的、常态化的行为, 例如Firefox:
验收测试通常是部署软件之前的最后一个测试操作, 也称为交付测试, 由最终客户执行,他们会验证端到端(end to end)的系统流程是否符合业务需求,以及功能是否是满足最终用户的需求。只有当所有的特性和功能按照期望的运行,客户才会接受软件
这是测试的最后阶段,在验收测试之后,软件将投入生产环境. 所以它也叫用户验收测试(UAT)
举个例子,验收测试就相当于收快递, 包裹是软件、你就是客户,是验收方,如果货物不符合你的要求,是要退货的。
Ad-hoc中文应该理解为临时的意思。顾名思义,这种测试是在临时基础上进行的, 有时候也称为随机测试。即没有参考测试用例、没有针对该测试的任何计划和文档。Ad-hoc测试的目的就是通过执行随意的流程或任意的功能来找出应用的缺陷和问题
Ad-hoc测试一种非正式的方法,可以由项目中的任何人执行。尽管没有测试用例很难识别缺陷,但是有些时候在Ad-hoc测试期间发现的缺陷可能无法使用现有的测试用例来识别, 也就是说它一般用来发现‘意外’的缺陷.
可访问性测试的目的是确定软件或应用程序是否可供残疾人使用。残疾是指聋人,色盲,智障人士,失明者,老年人和其他残疾人群体。这里会执行各种检查,例如针对视觉残疾的字体大小测试,针对色盲的颜色和对比度测试等等。
不同平台、不同应用类型对可访问性支持情况不太一样,比如iOS相比其他操作系统则更重视可访问, 而国外比国内更重视可访问性。
上文Alpha测试已经提及Beta测试, Beta测试是一种正式的软件测试类型,在将产品发布到市场或者实际最终用户之前,由客户在真实的应用环境中执行。
执行Beta测试目的是确保软件或产品中没有重大故障,并且满足最终用户的业务需求。当客户接受软件时,Beta测试才算通过。
通常,此类测试由最终用户或其他人完成。这是在将应用发布作为商业用途之前完成的最终测试。通常,发布的软件或产品的Beta版本仅限于特定区域中的特定数量的用户。 所以最终用户实际使用软件后会将一些问题反馈给公司。公司可以在全面发布之前采取必要的措施。
Beta测试在正式版本之前也可能会迭代进行多次.
前端应用输入的数据,一般都会存储在数据库,所以针对数据库的这类测试称为数据库测试或者后端测试. 市面有不同的数据库,如SQL Server,MySQL和Oracle等。数据库测试会涉及表结构,模式,存储过程,数据结构等。
后端测试一般不会涉及GUI,测试人员通过某些手段直接连接到数据库,从而可以容易地运行一些数据库请求来验证数据。通过后端测试可以发现一些数据库问题,比如数据丢失、死锁、数据损坏。这些问题在系统投入生产环境之前进行修复至关重要
这是兼容性测试的子类型,由测试团队执行. 浏览器兼容测试主要针对Web应用,用于确保软件可以在不同浏览器或操作系统中运行; 或者验证Web应用程序是否支持在浏览器的所有版本上运行, 以确定应用最终兼容的范围.
浏览器兼容测试是前端开发者绕不开的坑。
我们有很多策略来应对浏览器兼容性,比如渐进增强或者优雅降级, 还有制定浏览器兼容规范;
为了抚平浏览器之间的差异,我们会使用各种特性检测工具(Modernizr), 还有各种polyfill(CSS Normaliz, polyfill/shim, css-autoprefixer);
当然为了测试跨浏览器兼容性,还要一些辅助工具,例如BrowserStack, 对于我们这些小团队,只能下一堆Portable(Portable浏览器运行时相互隔离的, 所以不会存在配置文件等冲突问题) 浏览器,手工测试了。
向后兼容测试, 用于验证新开发或更新的软件是否能在旧版本的环境中运行。
比如向后兼容测试会检查新版软件是否可以正确地处理旧版本软件创建的文件格式。例如新版的Office 2016是否可以打开2012创建的文件。
同理也可以检查新版本是否可以兼容旧版本软件创建的数据表、数据文件、数据结构、配置文件。
任何软件更新应该在先前版本的基础之上良好地运行
黑盒测试不考虑软件的内部系统设计,它基于需求和功能进行测试, 只关心系统的输入/输出以及功能流程。
换句话说黑盒测试从用户的角度出发针对软件界面、功能及外部结构进行测试,而不考虑程序内部逻辑结构.
黑盒测试下面有很多子类,例如集成测试、系统测试、大部分非功能性测试
关于黑盒测试的优缺点以及测试类型可以看这里
边界值测试, 测试应用处于边界条件(boundary level)的行为。很多边界条件开发者是很难考虑周到的,所以才有一个专门的测试类型来验证这种情况
边界值测试检查应用处于边界值时是否存在缺陷。边界值测试通常用于测试不同范围的数字, 每个范围都有一个上下边界,边界测试则是针对这些边界值进行测试。
比如数字范围为1-500, 那么边界值测试会在这些值上进行验证: 0、1、2、499、500、501
这是白盒测试的子类型,在单元测试中实施. 顾名思义,分支测试表示测试要覆盖程序代码的各种条件分支, 避免遗漏缺陷。分支覆盖是单元测试覆盖率的一个指标之一
比较测试,将产品的优点和弱点与旧版本或者同类(竞品)产品进行比较.
比如类似王自如这种数码测评栏目,评测一个手机或者其他数码产品时,一般会横向和友商产品进行比较,有时候也会纵向和上一代产品比较.
还有一种比较典型的例子就是和行业的领导者比较,比如我们做IM的,会经常和微信比较: ‘你这个应用的启动速度怎么比微信慢这么多?’
这是一个大类, 兼容性测试用于验证应用在不同环境、web服务器、硬件、网络条件下的行为。兼容性测试确保软件可以在不同的配置、不同的数据库、不同的浏览器,以及它们不同的版本下运行。兼容性测试由测试团队实施
组件测试(此组件非GUI组件, 取组合测试可能更好理解一点),一般也称为模块测试(Module Testing), 一般由开发者在完成单元测试后执行。组件测试将多个功能组合起来作为单一的整体进行测试,目的是发现多个功能在相互连接起来之后的缺陷。
组件测试可大可小,小到函数级别或者类级别的组合,大可以大到几个单独的页面、模块、子系统的组合。 举一个前端例子,将多个页面路由组合起来,测试它们的流程跳转,就属于组件测试。
端到端测试也是一种黑盒测试类型,类似于系统测试. 端到端测试在模拟的、完整的、真实应用环境下模拟真实用户对应用进行测试,比如应用会和数据库交互、会使用网络通信、或者在适当的情况下和其他硬件、应用、系统进行交互. 端到端是指从一个端点到另一个端点的意思,所以端到端测试重点用于测试模块和模块之间的协调性。
当应用是分布式系统或者需要和其他外部系统协同时,端到端测试扮演着非常重要的角色, 它可以全面检查以确保软件在不同平台和环境产品能准确地交互。端到端测试有以下目的:
前端也有很多自动化的端到端测试工具,比如nightwatch,通过它们可以模拟用户对页面进行操作,从而检验整个应用流程是否正常和符合需求:
因为和系统测试很相似,所以它们也被经常拿来比较
等价划分, 这是一种黑盒测试的测试技术. 通过等价划分,可以将所有的输入数据合理地划分为多个分组,我们只需在每个分组中取一个数据作为测试的输入条件, 这样可以实现用少量代表性的测试数据取得较好的测试结果.
所以说这个测试的目的: 是在不导致缺陷的前提下,移除指定分组中的重复的用例, 简化测试的工作
比如一个程序应用接受-10到+10之间的值,使用等价分区方法可以划分为三个分组: 0、负值、正值. 接下来的测试只需从这个三个分组中取一个成员进行测试, 而不需要-10到+10每个成员都测试一遍.
It means real-time testing. Example testing includes the real-time scenario, it also involves the scenarios based on the experience of the testers.
实例测试意味着实时测试。实例测试包含了实时场景、另外还涉及基于测试人员经验的场景。
? 这里不是特别能理解这个测试类型,所以贴上原文。知道的告诉我呀
探索性测试有点类似于Ad-Hoc测试. 探索性测试是由测试团队进行的非正式测试。此测试的目的是探索应用并查找应用中存在的缺陷。像探险一样,在测试期间是有一定几率发现的重大、甚至可能导致系统故障的缺陷.
在探索性测试期间,建议跟踪记录好测试的流程、以及开始该流程之前的活动记录, 方便复现bug.
探索测试不需要任何文档和测试用例.
功能测试是一个大类, 又称为行为测试, 功能测试会忽略内部实现而关注组件的输出,目的是验证是否符合需求,这是一种面向功能需求的黑盒测试类型。关于功能测试的细节请看这里
功能测试是相对非功能测试而言的, 功能测试需要关心功能或者业务,需要业务耦合程度高;而非功能测试则是通用的,比如压力测试、负载测试,这些测试都有通用的工具来支持,不需要或很少定制化操作.
GUI测试的目的是根据业务需求验证GUI。在详细设计文档和GUI模型(UI设计文档)中一般会提到应用期望的GUI.
常见的GUI测试包括测试屏幕上显示的按钮和输入字段的大小、表格中所有文本、表格或内容的对齐规则等等. 如果团队有UI设计规范,还会验证是否符合设计规范
大猩猩测试是由测试人员执行的测试类型,有时也由开发人员执行。在大猩猩测试中,对模块中的一个模块或功能进行了彻底和严格的测试。原文没有说出大猩猩测试的精髓,大猩猩测试会对一个功能或模块进行重复‘上百次’的测试, 人类根本受不了这样子的测试方式,所以大猩猩测试的另一个别名是‘令人沮丧的测试(Frustrating Testing)’
这种测试的目的是检查应用程序的稳健性(robustness)
乐观路线测试的目标是在正常流程上成功测试应用。它不会考虑各种负面或异常情况。重点只关注于验证应用在有效和合法输入的条件下生成期望的输出. 比如银行付款,只考虑账户有钱的正常状态?
增量集成测试是一种自下而上的测试方法,即在添加新功能时立即集成应用程序进行连续测试。应用程序功能和模块应该足够独立,以便单独测试。这通常由程序员或测试人员完成。
安装和卸载测试是在不同硬件或软件环境下的不同操作系统上的进行完整/部分的安装、升级、卸载、回滚等测试. 常用于桌面端应用
集成测试是指将所有模块集成之后,验证合并后的功能. 模块通常是代码模块、单个应用、网络上的客户端和服务器应用等等。
集成测试一般在单元测试之后,所以单元测试是集成测试的基础,没有进行单元测试的集成测试是不靠谱的。所以最简单的形式是:’把两个已经测试过的单元组合成一个组件,测试它们之间的接口’。也就是说集成测试在单元测试的基础之上,将单元测试中独立的单元合并起来,验证它们的协调性, 合并后的组件又是一个新的‘单元’,这样逐步合并测试,最终形成完整的应用程序。
这种类型的测试常用于B/S软件和分布式系统。
它是一种非功能性测试,负载测试的目的是检查系统可以承受多少负载而不会降低性能, 或者说确定最大工作负载是多少。
负载测试有助于查找特定负载下系统的最大容量以及导致软件性能下降的任何原因。可以使用JMeter,LoadRunner,WebLoad,Silk执行程序等工具执行负载测试。
负载测试经常和性能测试、压力测试、稳定性测试等联系在一起。如上图(来源于淘宝性能白皮书). 其中TPS(Transation Per Second)指的是每秒钟系统可以处理的交易或事务的数量; Server Resource指的是系统资源占有.
另外也推荐阅读<<大型网站技术架构>>这本书
猴子测试是由测试人员进行的,即把自己当成猴子,在没有任何知识背景或者理解应用前提下,随意输入和操作。
猴子测试的目标是通过提供随机输入值/数据来检查应用程序或系统是否崩溃。 猴子是随机执行的,没有测试用例, 也没有必要了解系统的全部功能
变异测试(或者说可变性测试)是一种白盒测试,这是一种和单元测试反着来的测试类型。
通常单元测试的思路是通过测试用例来验证代码是否有效可靠,而变异测试是反过来. 它首先更改其中一个程序的源代码,再跑单元测试,如果单元测试通过则可能说明测试用例没有效果,或者测试用例没有覆盖到这处代码变异.
所以说变异测试可以反过来验证你的测试用例是否有效, 还有可以帮助我们找出一些无法被当前测试所防止的潜在错误.
悲观测试和乐观路线测试相反, 它要求测试者要具有“打破”常规的态度,考虑各种异常情况, 使用各种邪恶的?、不怀好意、不合法的操作来测试系统。悲观测试会使用不正确的数据、无效数据或输入来进行验证。它验证系统是否可以识别异常情况,并按预期运行。
每个大型的组织都有一个独立的团队,通常称为非功能测试(NFT)团队或性能团队。
非功能性测试涉及测试非功能性需求,如负载测试、压力测试、安全性、容量,恢复测试等等. NFT测试的目标是确保软件或应用程序的响应时间是否满足业务需求。
例如加载任何页面或系统都不应该花费太多时间,并且在负载峰值期间应该维持良好运行状态。
这个术语通常与“压力”和“负载”测试互换使用。性能测试用于检查系统是否满足性能要求。它会使用不同的性能和负载工具来执行此测试。
性能测试这个范围比较大,广义上的性能测试包括了上文提到的负载测试、压力测试、稳定性测试、容量测试等等。狭义的性能测试则是指在特定资源条件下,测试系统能否达到期望值, 也就是基线测试(Baseline Test).
总结一下性能测试的类型:
恢复测试用于验证应用或系统中崩溃或灾难中恢复的程度. 确定系统是否能够在灾难发生后继续运行。
比如应用通过网络电缆接收数据,突然断开了网络电缆的连接, 过一段时间,再插上网线, 系统应该开始恢复由于网络电缆拔出而丢失连接的数据
在修改任意模块或者功能后,将应用作为一个整体进行测试,称为回归测试。回归测试的目的就是验证在软件原有的功能变动后是否保持完整性.
有观点认为回归测试就是回归测试是指重复执行以前的全部或部分相同的测试工作, 其实不是不无道理。而且因为局部修改而牵一发动全身的意外在平时开发中并不少见,这种意外性就是回归测试的存在的目的.
因为在回归测试中很难覆盖所有系统,通常最好使用自动化测试工具进行这些类测试。比如每次修改完代码,跑单元测试来确保不影响确保其他软件单元。
在前端中组件快照测试(Snapshot Testing)和一些CSS UI测试,都是属于回归测试类型,它们的原理都是和上一次测试生成的结果进行比对,以确保没有意外的修改:
在基于风险的测试中,功能或需求将根据其优先级进行测试。基于风险的测试会优先测试高度关键的功能,因为这些功能对业务影响最大或者故障概率非常高. 而优先级由业务需求决定,因此一旦为所有功能设置了优先级,则应该首先执行高优先级功能或测试用例,然后再执行低优先级功能。 低优先级功能可以在时间充裕时测试,或者不测试。
基于风险的测试应该在‘不够时间来测试整个应用,但是又要按时交付软件’的情况下执行,通常还需要客户和高级管理层的讨论和批准之后才进行
完整性测试用于确定一个新的软件版本是否可以开始进行正式的测试,如果一个应该在一开始使用时就崩溃,那么就说明系统还不够稳定,没有必要进行下一步测试。这种情况应该打回给开发,以免浪费时间
以我们公司为例:
这么做的目的之一就是为了降低测试团队的工作负担,因为他们要对接多个开发团队的测试任务。
安全也是一个庞大的学科,而且知识每天都在更新,所以安全测试一般由特殊的安全团队执行,他们以各种黑客手段对系统进行渗透测试。
安全测试旨在确保应用或网站免受内部和外部威胁的侵害。这个测试包括预防恶意程序、病毒; 检验授权和身份验证过程的安全性。
它还会检查软件对任何黑客攻击和恶意程序的反应方式,以及在遭到黑客攻击后如何维护软件以保护数据安全
冒烟测试,每当开发团队提交新的构建时,软件测试团队就会先验证构建, 并确保不存在重大问题, 如果存在重大问题会直接打回开发团队.
如何通俗地理解冒烟测试呢?这个属于来源于硬件行业,对一个硬件或硬件组件进行更改或修复后,直接给设备加电。如果没有冒烟,则该组件就通过了测试。举个例子,给三星Note7加电,如果没爆炸,就说明通过了‘冒烟测试’(感觉当手机测试者不容易,容易有生命危险?)?
测试团队在确保构建稳定后才会进一步执行详细的测试。 冒烟检查会检查构建中是否存在中断缺陷(stopper defect, 即影响继续测试的缺陷),这将阻止测试团队进一步详细测试。 即如果测试人员发现主要功能不能工作,他们会拒绝这次构建,并退回给开发团队。
冒烟测试一般在回归测试或其他详细测试之前进行
静态测试有点类似于代码Review,在不执行任何代码的情况下执行(也就是不运行应用),它涉及对可交付成果审查(inspection)、review和演练(walkthrough). 比如检查代码语法、命名约定、项目组织。
静态测试不仅适用于代码, 也适用于测试用例、测试计划和设计文档. 如果在静态测试阶段发现缺陷,可以将缺陷成本降到最低。比如在设计阶段就发现问题,相比到开发阶段甚至到生产环境出现问题要好解决
举前端的例子,静态测试可能包括:
通过压力测试,模拟系统受到超出其规格的压力时失败的方式和时间, 找出系统的崩溃点. 这个测试在高负载情况下执行的,例如存取超过容量限制的数据、执行复杂的数据库查询、连续暴力输入到系统或加载到数据库。
系统测试在完整的集成系统上进行测试,也就是说系统测试一般在集成测试之后进行,集成测试之后系统成为了一个整体,系统测试在这个基础上、在真实的运行环境中验证系统是否符合业务需求。 这是一种黑盒型测试,基于总体需求规范,涵盖系统的所有组合部分。
系统测试其实不是一个具体的测试技术,而是一个测试阶段。 这个阶段会进行很多种测试,一般公司的测试团队的工作就集中在这一块。 一般包含:
归纳一下系统测试的目的:
其实系统测试和上文说的端到端测试很像,它们要求系统作为一个整体进行测试。可以简单展开对比一下
系统测试 | 端到端测试 | |
---|---|---|
测试范围 | 一般针对被测应用本身 | 一般针对被测应用以及其依赖的其他系统。正如其名,端到端,即从一端点到另一端点。重点关注前端、后端以及中间件之间的处理流程 |
测试类型 | 包含功能测试和非功能测试 | 一般涵盖所有源系统和目标系统之间的接口级别的测试 |
测试时机 | 一般在集成测试之后 | 一般在系统测试之后 |
测试独立的软件单元或模块称为单元测试。它通常由开发者完成,而不是由测试人员完成,因为它需要详细了解内部程序设计和代码。
单元测试是和我们开发者最密切相关的测试类型。它的测试对象是软件单元。软件单元可以是一个函数/方法、一个类或者一个GUI组件等。
这是一种白盒测试,所以要求由开发者自己进行,因为只有开发者才知道单元的内部实现。单元测试一般会使用测试覆盖率来验证单元测试的完成度.
前端常见的单元测试工具有Jest、Mocha、Jasmine等等. 下面是典型的BDD风格的单元测试组织:
可用性测试用于检测应用的用户友好程度(User-friendliness). 它会验证新用户受可以轻松理解应用流程,如果用户陷入麻烦,测试人员要记录好并提供帮助。可以认为可用性测试是在检查系统的导航性(navigation)
漏洞测试,涉及识别软件、硬件和网络中的漏洞。如果漏洞容易受到攻击,或者容易受到病毒和蠕虫感染,黑客或恶意程序就可以控制系统。
因此有必要在投入生产环境之前检查这些系统是否存在漏洞。
容量测试是由性能测试团队执行的一种非功能测试。容量测试会检查应用程序遇到大量的数据时的系统行为和响应时间。这种大量数据可能会影响系统的性能和处理时间的速度。
白盒测试, 它也被称为玻璃盒测试、结构测试、逻辑驱动测试或基于代码的测试, 基于应用程序代码的内部逻辑。即测试人员应该知道内部软件和代码是如何工作的, 对所有的逻辑路径进行覆盖测试。上面提到的单元测试和静态测试就是典型的白盒测试, 基本上白盒测试可以等价于单元测试
逻辑路径包括语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、条件组合覆盖和路径覆盖等等.
上面提到的软件测试类型只是测试中的一部分,实际有超过100种的测试类型,但是并非所有测试类型都会被所有项目使用,所以我这里只是列举一些比较常见的软件测试类型。
另外不同的组织中可能会有不同的定义或过程,但是基本概念在任何地方都是相同的。当项目、需求和范围发生变化时,这些测试类型、过程及其实现方法会不断演变
Please enable JavaScript to view the comments powered by Disqus.