软件测试

3 阅读19分钟

什么是测试用例

测试用例(TestCase):是为了项目的需求而编制的一组测试输入、执行条件以及预期结果,以便测试某个程序是否满足客户需求;是每一个测试点的数据设计和步骤设计

为什么要写测试用例?

  1. 测试用例是软件测试的核心
  2. 评估测试结果的基准
  3. 保证测试的时候不遗漏测试功能点。
  4. 在编写测试用例的过程,也可以熟悉需求,对系统架构或者业务流程有一个整体的了解
  5. 好的测试用例不仅方便自己看,还方便别人看,而且还能帮助设计的时候考虑的更加周全,因此测试用例的写作和设计一样重要;

测试用例组成的8大要素

  1. 用例编号:产品名称-测试阶段-测试项-xxx功能模块的首字母加数字
  2. 功能模块:对应的功能模块(细分功能)
  3. 测试标题:直接对测试点进行细化得到;输入内容+结果,同意功能模块标题不能重复
  4. 重要级别(优先级):高、中、低
  5. 预置条件:需要满足哪些前提条件,否则用例没有办法执行
  6. 测试数据:需要加工的输入信息,要跟步骤结合起来一定要具有指导性意义
  7. 操作步骤:明确给出每一步的描述,让陌生人也可以根据该步骤完成执行工作
  8. 预期结果:根据预期输出对比实际结果,来判断被测对象是否符合需求(预期结果是唯一的,不能出现模棱两可的情况)

什么样的用例是好的用例?

  1. 准确性--测试用例的设计确实符合测试需求,必须准确的说明测试的内容;
  2. 简洁性--测试用例的设计中必须包含完成测试必要的步骤要素,不需要加入多余的可有可无得步骤要素;
  3. 可重用性--测试用例的设计要求测试是可控的,它能够使任何人在任何时间进行测试都能获得同样的结果
  4. 适用性--测试用例对于当前的测试环境和测试者而言是可以执行的
  5. 纯净性--不会因为执行该测试用例而影响其他测试用例的执行,用例中应该说明如何将应用系统恢复到最初状态从而不因为后续的执行进行

测试用例编写(黑盒测试方法):

等价类(有效等价类、无效等价类)把全部输入数据合理划分为若干等价类,在每一个等价类中取一个数据作为测试的输入条件,就可以用少量有代表性的测试数据去的比较好的测试结果

  1. 等价类划分原则1:如果输入条件规定了取值范围或取值的个数,则可以确定一个有效等价类和两个无效等价类
  2. 等价类划分原则2:在规定了输入数据必须遵循的规则情况下,可确立一个有效等价类(符合规则)和若干个无效等价类(从不同角度违反规则)
  3. 等价类划分原则3:在输入条件是一个布尔值是(要么是真要么是假,没有第三种情况出现),可确定一个有效等价类和一个无效等价类
  4. 等价类划分原则4:在规定了输入数据的一组值(假设输入2个),并且程序要对每一个输入值分别处理的情况下,可确定2个有效等价类和一个无效等价类或者没有无效等价类
  5. 等价类划分原则5:如果我们已知,已划分的某个等价类的各个元素,在程序中的处理方式是不同的,则应将此等价类进一步划分更小的等价类
  • 有效等价类:有效等价类是程序规格说明有意义,合理的输入数据
  • 无效等价类:无效等价类是程序规格说明无意义,不合理的输入数据

边界值:假设大多数的错误是发生在各种输入条件的边界上,如果在边界上的取值不会导致程序错误,那边界外其他的取值导致程序错误的可能性也会更小

  • 边界值也是对等价类方法的一种补充;
  • 边界值的分析基本思路:正好等于、刚刚大于、刚刚小于边界的值作为测试数据

因果图:是从需求中找出因(输入条件)和果(输出或程序状态的改变),通过分析输入条件之间的关系(组合关系,约束关系)及输入和输出之间的关系绘制出因果图,再转化为判断表,从而设计出测试用例的方法;该方法主要适用于各种输入条件之间存在某种相互制约关系或输出结果依赖于各种输入条件的组合情况

  1. 所有的输入输出条件的相互制约关系以及组合关系
  2. 输出结果对输入条件的依赖关系。也就是什么样的输入组合会产生怎样的输出结果;

判定表:适用于描述处理判断条件比较多,各条件又相互组合,有多种决策方案的情况。是把作为条件的所有输入的各种组合值(因)以及对应输出值(果)都罗列出来而形成的表格。它能够将复杂的问题按照各种可能的情况全部列举出来,简明并可以避免遗漏。因此利用判定表能够设计出完整的测试用例集合。

判定表分析步骤:

  1. 分析需求,把条件列到条件桩中,把输出列到动作桩中;
  2. 把所有的条件和条件之间的组合关系,列到条件项中,确定规则的个数;N个条件,每个条件2种取值,则有2的N次方列;
  3. 根据需求,计算出动作的取值,并写到动作项中,得到初始的决策表;
  4. 化简判定表(判定表合并)
  5. 把判定表的每一列设计为一个测试用例(每一规则写一条测试用例)

状态图:又叫做状态迁移图;首先要找出所有的状态,然后再分析各个状态之间的转换(什么时候变成什么状态)

  1. 分析步骤:分析需求,从中提取出系统的所有的状态,并画出来;
  2. 把可以转换的状态,用箭头线标出来;
  3. 把所有的转换关系标上触发;
  4. 把状态迁移图变成状态树;
  5. 根据状态转换树,设计测试用例(路径覆盖、事件覆盖、状态覆盖)

场景法:是将软件系统的某个流程看成路径,用路径分析的方法来设计测试用例。根据流程的顺序依次进行组合,使得流程的各个分支都能走到。这是从白盒测试中路径覆盖分析中推广到黑盒测试中来的测试分析方法;

  1. 场景法分析步骤:先根据业务执行顺序,画出业务流程图;
  2. 根据业务流程图,确定测试路径(可以同时确定主选和备选路径)
  3. 选取测试数据,构造测试用例,覆盖每一条测试路径;
  • 基本流:没有任何差错,程序从开始直接执行到结束(模拟正确的操作流程)
  • 备选流:各种异常情况(模拟错误的操作流程)

测试环境(Test Environment简称TE):

为了运行被测软件完成测试工作所必须得硬件、软件和网络环境的集合; 稳定可控的测试环境可以使测试人员花费较少的时间完成测试用例执行,并且可以确保测试过程的结果准确可靠; 测试环境包括:硬件环境、软件环境(测试数据、测试工具)

测试环境设计的原则:

  1. 尽可能真实的环境,或模拟真实的环境;尽可能少用模拟器(安卓系统)和虚拟机(电脑系统);正常用户去测试或者极端测试(超出规定范围的情况查看应用)
  2. 底线是符合软件运行的最低要求(兼容性测试)如:app:最少能够支持的安装版本(当前最新版本往下走三四个版本)ios:当前手机往下走三四个版本,再选一个最低版本;web:最低能够支持的浏览器版本(win10,win7,win8,winxp)根据项目的不同,可能还需要考虑其他测试环境;
  3. 优先选择主流的广泛普及的操作系统(win/mac)和软件平台
  4. 测试环境要干净、独立、排除干扰;

HTTP超文本传输协议(Hypertext transfer protocol):

传输过程分为三步:

  1. 建立连接:三次握手
  2. 进行传输:客户端发起请求;服务器做出响应
  3. 断开连接:四次挥手

建立连接:三次握手

客户端和服务器传输数据之前,必须先建立连接才可以,建立连接的过程,叫做三次握手。

  1. 第一次握手:客户端主动给服务器发送消息,请求连接(其中会携带一些数据作为这次连接的识别符)
  2. 第二次握手:服务器收到消息后,给客户端回应一个消息,表示已经收到要连接的请求(其中会携带两部分数据,一部分是第一次的识别符,另一部分是这次响应的识别符)
  3. 第三次握手:客户端收到服务器的消息后,给服务器再次发送消息,表示收到服务器响应的消息(其中要携带响应的识别符)

进行传输:请求

http协议中规定,客户端发起请求的请求信息,要遵循请求报文的格式,请求报文规定请求信息分为4个部分:

  1. 请求行:请求信息原始界面中的第一行就是请求行;
  2. 请求头
  3. 请求空行
  4. 请求体
请求行中包含三个内容:**Method(方法/方式)**  + **空格** + **Path(路径)**  + **空格** + **HTTP Version(版本)**
如:GET / HTTP1.1
请求方式:GET 客户端对服务器发起不同的请求方式,服务器有不同的识别规则和回应。
请求路径:/
请求的协议以及版本:HTTP1.1;常见的协议有:http/https/ssh/ftp/sftp/mongodb/mysql/....

请求头:代表发起请求的信息中,一些键值对,可以说明这次请求的一些信息
请求空行:请求头和请求主体之间要有一个空行。好截取内容
请求主体:客户端想服务器发起请求的时候可以给服务器携带一些参数;
get请求的请求主体是带在url中https://www.bilibili.com?spm_id=333&vd_sour&p=3
post请求的请求主体,不在url中显示,必须打开浏览器的payload中才能看到:
请求头中的一些内容:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 # 告诉服务器当前客户端可以接收的文档的类型。其实这里包含了*/*,就表示什么都可以接收;
Accept-Encoding: gzip, deflate, br # 客户端支持的编码
Accept-Language: zh-CN,zh;q=0.9 # 当前客户端可以支持的语言,在浏览器的工具->选项中可以得到相关信息
Cache-Control: max-age=0 # 缓存机制
Connection: keep-alive # 客户端支持的连接方式,保持一段连接,默认为3000ms
Host: localhost:3000 # 请求的主机名为localhost:8080,url中的host部分,包含hostname和port
Sec-Fetch-Dest: document # 告诉服务器 浏览器如何使用获取的数据
Sec-Fetch-Mode: navigate # 表示这是一个浏览器的页面切换请求
Sec-Fetch-Site: none # 表示一个请求发起者的来源与目标资源来源之间的关系,因为直接敲回车打开的,所以没有目标来源
Sec-Fetch-User: ?1 # 表示导航请求由用户激活触发(鼠标点击/键盘)
Upgrade-Insecure-Requests: 1 # 表示这个请求不安全,可以跟服务器协商升级为https协议
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 # 告诉网站服务器,访问者是通过什么工具来请求的,其中包含系统和客户端信息
sec-ch-ua: "Google Chrome";v="107", "Chromium";v="107", "Not=A?Brand";v="24" # user-agent的补充,怕user-agent泄漏客户端信息而做出的补充
sec-ch-ua-mobile: ?0 # 是否是移动设备
sec-ch-ua-platform: "Windows" # 系统

请求方式:get post put delete

get:参数会暴露在地址栏;数据有大小限制,最大4kb;数据只能进行url编码;get请求会被记录在历史记录;可能会被浏览器缓存。语义用于获取服务器端数据。常见的get请求包括:

  • 在地址栏输入数据敲回车
  • 点击a标签跳转
  • html中引入图片、引入css、引入js、引入html地址
  • form默认的提交方式,也可以设置get提交方式

post: 参数不会暴露在地址栏;数据大小没有限制;数据可以不经过url编码,可以是其他格式数据;post不会被记录在历史记录;不会被浏览器缓存。语义用于给服务器提交数据。常见的post请求:form标签的post提交方式;

put: 语义用于请求服务器修改数据

delete: 语义用于请求服务器删除数据

响应:

http规定:服务器接收请求后,要对客户端进行相应。http规定响应信息必须遵循响应报文的规则 响应报文规则包含3部分:响应行 响应头 响应主体

响应行:包含3部分:协议和版本+状态码+状态描述
比如:HTTP/1.1 200 OK
协议和版本号:HTTP/1.1
状态码:200;http协议规定用来描述这次请求,服务器给出响应的状态;
状态描述:OK;每个状态码,都有一个描述对应,更详细的说明这个状态码的含义;

参考网址:developer.mozilla.org/zh-CN/docs/…

http请求共有5种响应状态:

  • 1XX:代表请求已被接受,需要继续处理;
  • 2XX:代表请求已成功被服务器接收、理解、并接受;
  • 3XX:代表需要客户端采取进一步的操作才能完成请求;
  • 4XX:代表了客户端看起来可能发生了错误,妨碍了服务器的处理;
  • 5XX:代表了服务器在处理请求的过程中有错误或者异常状态发生;
响应头是一些键值对,来描述响应信息:
Date: Sun, 27 Nov 2022 02:11:46 GMT # 响应时间;
Connection: keep-alive # http1.1版本可以允许客户端和服务器持续连接,下次请求可免除重复断开请求的过程,节省连接效率;
Keep-Alive: timeout=5 # 表示这个持续的连接可以保持5秒;
Content-Length: 18 # 服务端给客户端的数据长度;
响应主体:响应主体是服务器给客户端响应的主要数据;

断开连接:四次挥手

当客户端和服务器结束这次请求后,需要断开连接。断开连接也叫作四次挥手。

  • 第一次挥手:客户端主动对服务器发起断开请求(携带这次请求的标识符)
  • 第二次挥手:服务器回应收到这次请求,并做断开准备(携带对这次请求的标识符,表示对这个请求做回应)
  • 第三次挥手:服务器做好断开准备后,通知客户端,可以断开了,当客户端断开后,服务器将销毁这次请求的信息,不再回应(携带对这次请求的标识符,表示对这个请求做回应)
  • 第四次挥手:客户端告诉服务器已经断开(携带回应的标识符)

Bug的概况:

软件缺陷:通常又被叫做Defect或者Bug。即为软件或程序中存在的某种破坏正常运行能力的问题或者错误。

从产品内部看,缺陷是软件产品开发或维护过程中存在的错误异常等各种问题; 从产品外部看,缺陷是系统所需要实现的某种功能的失效或违背用户的需求; 总结:软件中任何不满足用户需求的问题都可以认为是缺陷;

来自软件本身:

  1. 系统结构复杂,无法设计成一个很好的层次结构或组件结构;
  2. 对程序逻辑路径或数据范围的边界考虑不够周全;
  3. 对一些实时应用,时间同步不一致;
  4. 没有考虑系统崩溃后的自我恢复或数据的本地备份;
  5. 系统运行环境复杂(系统是多系统交互)
  6. 通信端口多,存取和加密手段的矛盾性;
  7. 新技术的采用;

Bug的组成

  1. 缺陷编号:测试管理系统自动生成;
  2. 缺陷标题:用简短精确的话语来描述你的bug(尽量唯一)
  3. 缺陷类型:代码错误、设计缺陷、界面优化...
  4. 缺陷等级:致命、严重、一般、建议(高、中、低)
  5. 缺陷优先级别:立即修改、高优先级、正常排队
  6. 缺陷状态:新提交的bug一般为新建或激活状态;
  7. 缺陷所属的模块:细分功能模块方便统计问题;
  8. 发现缺陷的版本:当前版本号
  9. 缺陷复现的步骤:操作步骤预期结果实际结果
  10. 缺陷的发现日期:系统自动生成
  11. 备注信息:截图、视频、log等信息

Bug的等级

针对缺陷,一般划分为三级或四级,也有分五级的。如果等级越高,那么可能被修复的等级也会高一些,有的公司会根据你提的缺陷数量和缺陷等级来考核你的绩效;

如何来判断缺陷的等级(严重程度)

一级Bug:致命错误

  1. 常规操作引起的系统崩溃死机死循环
  2. 造成数据泄露安全性的问题,比如恶意攻击造成的账户私密信息泄露;
  3. 涉及到金钱的问题
  4. 主要功能完全丧失等(功能缺失)

二级Bug:严重错误

  1. 功能或特性没有实现
  2. 主要功能部分丧失,次要功能完全丧失
  3. 错误的波及面广,影响到其他重要功能正常实现:功能交互
  4. 非常规操作导致的程序崩溃死机死循环
  5. 外观难以接受的缺陷
  6. 密码明文显示

三级Bug:一般错误不影响产品的运行不会成为故障起因,但对于产品外观和下道工序影响较大的缺陷;

  1. 次要功能没有正常实现
  2. 用户界面差,操作时间长
  3. 查询错误,数据错误显示
  4. 简单的输入现在未放在前端进行控制
  5. 删除操作未给出提示或提示信息不准确

Bug的状态

  1. 激活或打开(New or Open or Active):新建的bug,等待处理的状态;
  2. 已修复(Fix or Resolved):开发工程师对缺陷进行了修复,需要测试工程师进行确认
  3. 以后解决(Later):缺陷将在以后发布的版本中解决,当前版本暂不修复
  4. 重新打开(Reopen):测试验证后依然还存在的缺陷,等待开发进一步修复
  5. 关闭(Close):测试验证问题已经修复成功,就把bug关闭
  6. 不修复(Wontfix):报告中描述的缺陷确实存在,但是由于各种原因并不进行修复
  7. 不是问题(NAB):报告中描述的缺陷经过确认不存在或不是缺陷
  8. 已重复(Duplicate):提交的缺陷已经存在,重复缺陷
  9. 需要更多信息(WorkSforme):根据报告的描述无法重现的缺陷,需要提供更多的信息

Bug的类型(禅道系统为例,可自定义)

  1. 代码错误
  2. 设计缺陷
  3. 界面优化
  4. 性能问题
  5. 配置相关
  6. 安装部署
  7. 安全相关
  8. 标准规范
  9. 测试脚本
  10. 其他
  11. 其他划分:功能类、界面类、性能类、易用性、兼容性类...

怎样规范记录Bug?

  1. 保证缺陷可以重现:让其他技术人员依据报告内容去操作,简单迅速的重现出缺陷就是好的缺陷报告;
  2. 将重现缺陷的操作步骤组织成列表的形式,方便开发和自己快速理解和解决
  3. 每一份报告中只描述一个缺陷:一份报告描述多个缺陷,容易造成缺陷的遗漏
  4. 客观准确便于阅读和理解:陈述事实,不要做主观臆断

复现率低的Bug怎么处理?

可再现的缺陷,就是存在一系列明确的操作步骤条件和数据使得缺陷的反复出现,一定要报告; 不可再现的缺陷:找不到明确的步骤条件和数据可以让缺陷反复出现,缺陷对的出现看起来是随机和不确定的,慎重处理; 不可再现的缺陷如何处理:

  1. 记录下来但不要报告名字后续的测试中特别留意,找到其可能出现的稳定的路径
  2. 转化为可再现的缺陷时,再报告;
  3. 千万不要忽视不可再现的缺陷;