概述
在不短不长的7年多研发生涯中,听过无数个软件测试概念:单元测试、功能测试、白盒测试、黑盒测试、自动化测试、契约测试、基准测试、性能测试、集成测试、渗透测试、接口测试、UI测试、端到端测试、E2E测试……
恰逢在准备系统架构设计师软考高级,里面也有不少软件测试相关考题。
本文试图做一个关于软件测试的总结性的综述。
软件测试:
使用人工或自动的手段来运行或测定某个软件系统的过程,其目的在于检验它是否满足规定的需求或弄清预期结果与实际结果之间的差别。
测试金字塔
提到软件测试,不能不知道Mike Cohn提出的这个概念。
Mike提出的测试金字塔由以下三层组成(自下往上分别是):
- 单元测试
- 服务测试
- 用户界面测试
在不同的软件开发模式或系统架构下,需要的测试工作不尽相同,需要的测试场景和案例也大相径庭。但是这个测试金字塔的理念是重要且适用的,根据具体场景做适当的调整。
在软件测试中:
- 单元测试具备快速、简单且容易维护的特点,大量的单元测试可以保证系统的健壮性
- 需要适量的集成测试,以确保多个组件之间的协同工作
- 需要少量的UI测试,覆盖最核心的功能,或面向用户的UI体验等
分类
分类有助于得到一个对系统进行拆分,进而统一的理解。从不同的角度理解,软件测试也有不同的分类维度。
按阶段划分
- 单元测试
- 系统测试
- 集成测试
- 验收测试
是否查看源代码
- 黑盒测试
- 白盒测试
- 灰盒测试
按是否运行分类
- 静态测试
- 动态测试
按是否自动化划分
- 人工测试
手工测试就是由人去一个一个的输入用例,然后观察结果,和机器测试相对应,属于较原始但是必须的一个步骤。执行效率低,工作量大。 - 自动化测试
就是在预设条件下运行系统或应用程序,评估运行结果,预先条件应包括正常条件和异常条件。简单说自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程。
自动化测试比如功能测试自动化、性能测试自动化、安全测试自动化。
根据国家标准GB/T 15532-2008,软件测试可分为单元测试、集成测试、配置项测试、系统测试、验收测试和回归测试等类别。
单元测试
是指对软件中的最小可测试单元(方法、函数、类等)进行检查和验证,一般由程序员自己完成,属于白盒测试、静态测试。
也称为模块测试,测试的对象是可独立编译或汇编的程序模块、软件构件或面向对象软件中的类(统称为模块),其目的是检查每个模块能否正确地实现设计说明中的功能、性能、接口和其他设计约束等条件,发现模块内可能存在的各种差错。单元测试的技术依据是软件详细设计说明书。
策略
单元测试策略主要包括:
- 自顶向下的单元测试:先测试上层模块,再测试下层模块。测试下层模块时由于它的上层模块己测试过,所以不必另外编写驱动模块。
- 自底向上的单元测试:自底向上的单元测试先测试下层模块,再测试上层模块。测试上层模块由于它的下层模块已经测试过,所以不必另外编写桩模块。
- 孤立测试:不需要考虑每个模块与其他模块之间的关系,逐一完成所有模块的测试。由于各模块之间不存在依赖性,单元测试可以并行进行,但因为需要为每个模块单独设计驱动模块和桩模块,增加额外的测试成本。
- 综合测试:上述三种单元测试策略各有利弊,实际测试时可以根据软件特点和进度安排情况,将几种测试方法混合使用
集成测试
也称为组装测试、联合测试(对于子系统而言,则称为部件测试)。它将已通过单元测试的模块集成在一起,主要测试模块之间的协作性。从组装策略而言,可以分为一次性组装测试和增量式组装(包括自项向下、自底向上及混合式)两种。集成测试计划通常是在软件概要设计阶段完成的,集成测试一般采用黑盒测试方法。
集成测试时,一般是对接口进行测试
集成测试的目的是检查模块之间,以及模块和已集成的软件之间的接口关系,并验证已集成的软件是否符合设计要求。集成测试的技术依据是软件概要设计文档。
系统测试
常见的系统测试主要有恢复测试、安全性测试、压力测试、性能测试、可靠性测试、可用性测试、可维护性测试和安装测试。不包括路径测试。
- 配置项测试的对象是软件配置项,配置项测试的目的是检验软件配置项与软件需求规格说明的一致性。
- 确认测试主要验证软件的功能、性能和其他特性是否与用户需求一致。验收测试是指针对软件需求规格说明,在交付前以用户为主进行的测试。
- 回归测试的目的是测试软件变更之后,变更部分的正确性和对变更需求的复合型,以及软件原有的、正确的功能、性能和其他规定的要求的不损害性。
测试一个模块时,可能需要为该模块编写一个驱动模块和若干个桩模块。驱动模块用来调用被测模块,它接收测试者提供的测试数据,并把这些数据传送给被测模块,然后从被测模块接收测试结果,并以某种可见的方式将测试结果返回给测试人员;桩模块用来模拟被测模块所调用的子模块,它接受被测模块的调用,检验调用参数,并以尽可能简单的操作模拟被调用的子程序模块功能,把结果送回被测模块。顶层模块测试时不需要驱动模块,底层模块测试时不要桩模块。
系统测试的对象是完整的、集成的计算机系统,系统测试的目的是在真实系统工作环境下,验证完整的软件配置项能否和系统正确连接,并满足系统/子系统设计文档和软件开发合同规定的要求。系统测试的技术依据是用户需求或开发合同。
验收测试
涉及源代码
白盒测试
测试程序内部逻辑结构及相关信息,检查程序源代码。控制流测试和数据流测试属于白盒测试方法。
黑盒测试
black-box testing,数据驱动测试,完全不考虑程序内部结构和内部特性,注重于测试软件的功能需求,只关心软件的输入数据和输出数据。
黑盒测试可以发现如下几类错误
- 功能问题或遗漏
- 界面错误
- 数据库访问或处理错误
- 性能问题
优点/缺点
- 优点
测试人员不需要了解实现得细节,包括特定的编程语言(没有编程经验的人也可以设计测试用例)
测试人员和编程人员是相互独立的(黑盒测试用例设计与程序如何实现无关)
从用户的角度进行测试,很容易被接受和理解
有助于暴露任何与规格不一致或者歧异的地方 - 缺点
不能测试程序内部特定部位
如果程序未执行的代码无法发现
不可能做到穷举测试
分类
黑盒测试一般包括功能测试和性能测试
- 功能测试
是黑盒测试的一方面,它检查实际软件的功能是否符合用户的需求- 逻辑功能测试
- 界面测试
- 易用性测试
- 安装测试
- 兼容性测试
- 性能测试
是软件测试的高端领域,性能测试工程师的待遇和白盒测试工程师不相上下- 时间性能(事务响应时间等)
- 空间性能(系统资源消耗)
- 一般性能测试
- 稳定性测试
- 负载测试
- 压力测试
灰盒测试
灰盒测试,介于白盒测试与黑盒测试之间的一种测试,既可保证黑盒的关注点又可掌控白盒的内部结构,但不会去对内部程序功能和运作做详细了解,灰盒测试结合了白盒测试和黑盒测试的要素。
运行
静态测试是指被测试程序不在机器上运行,而采用人工检测和计算机辅助静态分析的手段对程序进行检测。对文档的静态测试主要以检查单的形式进行,而对代码的静态测试一般采用桌前检查(Desk Checking)、代码走查和代码审查。
动态测试
dynamic testing,指实际运行被测程序,输入相应的测试数据,检查实际输出结果和预期结果是否相符的过程。
动态测试方法是指通过运行被测程序,检查运行结果与预期结果的差异,并分析运行效率、正确性和健壮性等性能。这种方法由三部分组成:构造测试用例、执行程序、分析程序的输出结果。
动态测试需要运行被测试系统,并设置探针,向代码生成的可执行文件中插入检测代码,可用于软件的覆盖分析和性能分析,也可用于软件的模拟、建模、仿真测试和变异测试等。
静态测试
static testing,指不实际运行被测软件,而只是静态地检查程序代码、界面或文档中可能存在的错误过程。
静态测试是指被测试程序不在机器上运行,而采用人工检测和计算机辅助静态分析的手段对程序进行检测。
静态测试工具可用于对软件需求、结构设计、详细设计和代码进行评审、走查和审查。
静态测试工具可对软件的复杂度分析、数据流分析、控制流分析和接口分析提供支持。
静态测试包括对文档的静态测试和对代码的静态测试。对代码的静态测试包括控制流分析、数据流分析、接口分析和表达式分析。
- 控制流分析。控制流分析是指使用控制流程图检查被测程序控制结构的过程。例如,可检查被测程序是否存在没有使用的语句或子程序、是否调用并不存在的子程序,以及是否存在无法达到的语句等。
- 数据流分析。数据流分析是指使用控制流程图分析数据各种异常情况的过程,包括数据初始化、赋值或引用过程中的异常。例如,引用未定义的变量、对以前未使用的变量再次赋值等程序差错或异常情况。
- 接口分析。接口分析主要包括模块之间接口的一致性分析、模块与外部数据库及其他软件配置项之间的一致性分析、子程序和函数之间的接口一致性分析等。例如可以检查函数形参与实现的数量、顺序、类型和使用的一致性。
- 表达式分析。表达式分析用于检查程序代码中的表达式错误。如,括号不配对、数组引用越界、除数为零,以及浮点数变量比较时的误差等错误。
功能测试
UI测试
界面测试,测试用户页面布局是否合理,配色是否合理,整体风格是否一致,界面文字是否正确,命名是否统一,页面是否美观,文字,图片组合是否完美等等,其实就是检测页面上的所有内容。
兼容性测试
指要测试的软件在不同的硬件平台上、不同的应用软件之间、不同的操作系统中、不同的网络环境中是否可以正常的运行、有无异常的测试过程。即是通常说的软件的可移植性。
常见的兼容性:
- 浏览器
可以使用第三方工具:推荐IEtester、SuperPreview和Browsershots - 操作系统
- APP
- Android:涉及到不同安卓设备机型、安卓版本、系统版本、屏幕分辨率、屏幕大小尺寸、屏幕形状。实际中,测试面可能非常大,测试工作重复且繁杂。可以考虑使用收费的百度众测平台和云测平台
- iOS:涉及各型号
注:上面的枚举可能不太严谨,操作系统和App存在部分交集
性能测试
对系统的各项性能指标进行测试,比如页面的响应时间,页面的并发量,或者软件架构是否合理等。
压力测试
给软件不断加压,强制其在极限的情况下运行,观察它可以运行到何种程度,从而发现性能缺陷,包括内存、CPU、磁盘空间和网络带宽。
负载测试
逐步增加系统负载,测试各种系统性能指标的变化,并最终确定在满足性能指标的情况下,系统所能承受的最大负载量的测试。
并发测试
主要指当测试多用户并发访问同一个应用、模块、数据时是否产生隐藏的并发问题,如内存泄漏、线程锁、资源争用问题。
其它分类
安全测试
检查系统对非法侵入渗透的防范能力:渗透测试、流量攻击、SQL注入、跨域攻击
回归测试
是指软件被修改后重新进行的测试,重复执行上一个版本测试时的用例,是为了保证对软件所做的修改没有引入新的错误而重复进行的测试。
随机测试
随机测试主要是对被测软件的一些重要功能进行复测,也包括测试那些当前的测试用例没有覆盖到的部分。另外,对于软件更新和新增加的功能要重点测试。重点对一些特殊点情况点、特殊的使用环境、并发性、进行检查。尤其对以前测试发现的重大Bug,进行再次测试,可以结合回归测试(Regressive Testing)一起进行。
冒烟测试
测试前的测试,检查软件是否有可测试性。
冒烟测试目的是确认软件基本功能正常,冒烟测试的执行者是版本编译人员。
探索性测试
探索性测试可以说是一种测试思维技术。它没有很多实际的测试方法、技术和工具,但是却是所有测试人员都应该掌握的一种测试思维方式。探索性强调测试人员的主观能动性,抛弃繁杂的测试计划和测试用例设计过程,强调在碰到问题时及时改变测试策略。
探索性测试自动化暂时无法代替。
埋点测试
埋点测试数据采集的一种术语,而数据采集是提供给运营工作人员去了解手机app对于某些模块、场景的用户使用情况,进行的一个触发埋点,将埋点采集到的数据到的数据进行上报的过程。采集数据只是起点,将数据进行分析、整理、汇总以及报表展示,最终得出用户对app普遍对使用行为,从而实现app面向用户的改良。
打桩测试
在进行单元测试时,单元本身无法构成一个切实可运行的程序系统,所以需要为单元测试来开发桩模块和驱动模块。
APP专项测试
- 弱网测试:模拟软件在不同网络下的表现(2G/3G/4G/5G/WIFI/热点/飞行模式/断网),不同网络实质是网速不同,可以通过软件进行模拟(Fiddler,Charles)
- 权限测试:不给某个权限时,软件是否能正场运行(禁止使用相机权限时,看app是否正常运行)
- 安装、卸载、更新测试
- 当客户端有新版本时,是否有更新提示
- 用户取消版本更新时,老版本是否可以正常使用,下次启动应用时,是否出现更新提示
- 当有新版本时,不删除客户端的情况下,老版本是否可用
- 保留新版客户端的前提下,使用老版本安装包能否正常安装(要求不能安装,版本不可逆)
- 出现跨版本更新的时候,是否可以更新成功
- 场景交互测试:是指一个功能正在执行过程中,同时另外一个事件或操作对该过程进行干扰的测试。
- 多个APP同时运行是否影响正常功能
- APP运行时前/后台切换是否影响正常功能
- APP运行时拨打/接听电话、发送/接收信息/邮件
- APP运行时切换网络(2G、3G、4G 、 5G 、 Wi-Fi)
- APP运行时浏览网络
- APP运行时使用蓝牙传送/接收数据
- APP运行时使用相机、计算器等手机自带设备。
- 单手模式、分屏使用
- 资源争用测试:(多个app同时使用某一功能,比如手机喇叭,谁的优先级更高的测试)
- 消息推送测试:(消息推送都是消息服务器在推送,与app无关)
消息推送是否成功、顺序是否正确 - 资源监控测试:测试CPU、硬盘、内存、流量、电量使用情况是否合理,一般采用求平均值方法。
- 兼容性测试
- 易用性测试
- UI测试
- 稳定性测试