软件测试52讲 - 笔记(一)- 测试基础知识

测试基础知识

01 | 你真的懂测试吗?从“用户登录”测试谈起

总结

  • 用例设计需要考虑功能、性能、安全及兼容性等

对于高质量的软件测试,用例设计不仅需要考虑明确的显式功能性需求,还要涉及兼容性、安全性和性能等一系列的非功能性需求,这些非功能性需求对软件系统的质量有着举足轻重的作用;

  • 需要宽广的测试面

测试工程师目标是保证系统在各种应用场景下的功能是符合设计要求的,因此,需要考虑的测试用例就需要更多、更全面。优秀的测试工程师必须具有宽广的知识面,才能设计出有针对性、更易于发现问题的测试用例。

  • 测试用例的不可穷尽

软件测试的用例设计是不可穷尽的,工程实践中难免受制于时间成本和经济成本,所以优秀的测试工程师需要兼顾缺陷风险和研发成本,采用基于风险驱动的模式,有所侧重地选择测试范围和设计测试用例,以寻求缺陷风险和研发成本之间的平衡

案例

功能

用户登录

测试用例

基础功能用例(基于等价类和边界值设计)
  1. 输入已注册的用户名和正确的密码,验证是否登录成功;

  2. 输入已注册的用户名和不正确的密码,验证是否登录失败,并且提示信息正确;

  3. 输入未注册的用户名和任意密码,验证是否登录失败,并且提示信息正确;

  4. 用户名和密码两者都为空,验证是否登录失败,并且提示信息正确;

  5. 用户名和密码两者之一为空,验证是否登录失败,并且提示信息正确;

  6. 如果登录功能启用了验证码功能,在用户名和密码正确的前提下,输入正确的验证码,验证是否登录成功;

  7. 如果登录功能启用了验证码功能,在用户名和密码正确的前提下,输入错误的验证码,验证是否登录失败,并且提示信息正确。

可添加功能用例(经验型)
  1. 用户名和密码是否大小写敏感;

  2. 页面上的密码框是否加密显示;

  3. 后台系统创建的用户第一次登录成功时,是否提示修改密码;

  4. 忘记用户名和忘记密码的功能是否可用;

  5. 前端页面是否根据设计要求限制用户名和密码长度;

  6. 如果登录功能需要验证码,点击验证码图片是否可以更换验证码,更换后的验证码是否可用;

  7. 刷新页面是否会刷新验证码;如果验证码具有时效性,需要分别验证时效内和时效外验证码的有效性;

  8. 用户登录成功但是会话超时后,继续操作是否会重定向到用户登录界面;

  9. 不同级别的用户,比如管理员用户和普通用户,登录系统后的权限是否正确;

  10. 页面默认焦点是否定位在用户名的输入框中;

  11. 快捷键 Tab 和 Enter 等,是否可以正常使用。

安全性用例
  1. 用户密码后台存储是否加密;
  2. 用户密码在网络传输过程中是否加密;
  3. 密码是否具有有效期,密码有效期到期后,是否提示需要修改密码;
  4. 不登录的情况下,在浏览器中直接输入登录后的 URL 地址,验证是否会重新定向到用户登录界面;
  5. 密码输入框是否不支持复制和粘贴;
  6. 密码输入框内输入的密码是否都可以在页面源码模式下被查看;
  7. 用户名和密码的输入框中分别输入典型的“SQL 注入攻击”字符串,验证系统的返回页面;
  8. 用户名和密码的输入框中分别输入典型的“XSS 跨站脚本攻击”字符串,验证系统行为是否被篡改;
  9. 连续多次登录失败情况下,系统是否会阻止后续的尝试以应对暴力破解;
  10. 同一用户在同一终端的多种浏览器上登录,验证登录功能的互斥性是否符合设计预期;
  11. 同一用户先后在多台终端的浏览器上登录,验证登录是否具有互斥性。
性能用例
  1. 单用户登录的响应时间是否小于 3 秒;
  2. 单用户登录时,后台请求数量是否过多;
  3. 高并发场景下用户登录的响应时间是否小于 5 秒;
  4. 高并发场景下服务端的监控指标是否符合预期;
  5. 高集合点并发场景下,是否存在资源死锁和不合理的资源等待;
  6. 长时间大量用户连续登录和登出,服务器端是否存在内存泄漏。
兼容性用例
  1. 不同浏览器下,验证登录页面的显示以及功能正确性;
  2. 相同浏览器的不同版本下,验证登录页面的显示以及功能正确性;
  3. 不同移动设备终端的不同浏览器下,验证登录页面的显示以及功能正确性;
  4. 不同分辨率的界面下,验证登录页面的显示以及功能正确性。
补充
  1. 密码是否有明文和暗文显示两种模式
  2. 是否可记住密码,记住的密码保存是否加密
  3. 用户名和密码是否对空格敏感
  4. 为空和输入空字符串时的校验是否一致
  5. 后端用户名及密码的规则校验
  6. 登录后输入登录URL,是否还能再次登录?如果能,原登录用户是否变得无效
  7. 是否可以使用登录的API发送登录请求,并绕开验证码校验
  8. 是否支持第三方登录
  9. 弱网环境或者无网络环境下登录

02 | 如何设计一个“好的”测试用例?

总结

  1. “好的”测试用例一定是一个完备的集合,它能够覆盖所有等价类以及各种边界值,而能否发现软件缺陷并不是衡量测试用例好坏的标准。
  2. 设计测试用例的方法有很多种,但综合运用等价类划分、边界值分析和错误推测方法,可以满足绝大多数软件测试用例设计的需求。
  3. “好的”测试用例在设计时,需要从软件功能需求出发,全面地、无遗漏地识别出测试需求至关重要。
  4. 如果想设计一个“好的”测试用例,必须要深入理解被测软件的架构设计,深入软件内部的处理逻辑。需求覆盖率和代码覆盖率这两个指标可以帮助衡量测试执行的完备性。

介绍

“好的”测试用例:一个完备的集合,它能够覆盖所有等价类以及各种边界值,而跟能否发现缺陷无关。

特征

  1. 整体完备性: “好的”测试用例一定是一个完备的整体,是有效测试用例组成的集合,能够完全覆盖测试需求。
  2. 等价类划分的准确性: 指的是对于每个等价类都能保证只要其中一个输入测试通过,其他输入也一定测试通过。
  3. 等价类集合的完备性: 需要保证所有可能的边界值和边界条件都已经正确识别。

三类设计方法

等价类划分

从每个等价类中任意选取一个值进行测试,就可以用少量具有代表性的测试输入取得较好的测试覆盖结果。另一个关键点是找出所有“无效等价类”

边界值分析

边界值分析是对等价类划分的补充,你从工程实践经验中可以发现,大量的错误发生在输入输出的边界值上,所以需要对边界值进行重点测试,通常选取正好等于、刚刚大于或刚刚小于边界的值作为测试数据。

错误推测法

错误推测方法是指基于对被测试软件系统设计的理解、过往经验以及个人直觉,推测出软件可能存在的缺陷,从而有针对性地设计测试用例的方法。这个方法强调的是对被测试软件的需求理解以及设计实现的细节把握,当然还有个人的能力。(组件缺陷库并实时维护)

如何设计

在具体的用例设计时,首先需要搞清楚每一个业务需求所对应的多个软件功能需求点,然后分析出每个软件功能需求点对应的多个测试需求点,最后再针对每个测试需求点设计测试用例。

注意
  1. 从软件功能需求出发,全面地、无遗漏地识别出测试需求是至关重要的,这将直接关系到用例的测试覆盖率。
  2. 对于识别出的每个测试需求点,需要综合运用等价类划分、边界值分析和错误推测方法来全面地设计测试用例。

03 | 什么是单元测试?如何做好单元测试?

定义

单元测试是指,对软件中的最小可测试单元在与程序其他部分相隔离的情况下进行检查和验证的工作,这里的最小可测试单元通常是指函数或者类。

如何做好

代码特征及错误原因

单元测试的对象是代码

要做到代码功能逻辑正确,必须做到分类正确并且完备无遗漏,同时每个分类的处理逻辑必须正确。

单元测试用例

单元测试的用例是一个“输入数据”和“预计输出”的集合。

输入数据
  1. 被测试函数的输入参数;
  2. 被测试函数内部需要读取的全局静态变量;
  3. 被测试函数内部需要读取的成员变量;
  4. 函数内部调用子函数获得的数据;
  5. 函数内部调用子函数改写的数据;
  6. 嵌入式系统中,在中断调用时改写的数据;
输出数据
  1. 被测试函数的返回值;
  2. 被测试函数的输出参数;
  3. 被测试函数所改写的成员变量;
  4. 被测试函数所改写的全局变量;
  5. 被测试函数中进行的文件更新;
  6. 被测试函数中进行的数据库更新;
  7. 被测试函数中进行的消息队列更新;

驱动代码、桩代码和 Mock 代码

驱动代码

(Driver)指调用被测函数的代码

桩代码

(Stub)是用来代替真实代码的临时代码。

桩代码的应用首先起到了隔离和补齐的作用,使被测代码能够独立编译、链接,并独立运行。同时,桩代码还具有控制被测函数执行路径的作用

Mock 代码和桩代码的本质区别是:测试期待结果的验证(Assert and Expectiation)。

04 | 为什么要做自动化测试?什么样的项目适合做自动化测试?

定义

自动化测试是,把人对软件的测试行为转化为由机器执行测试行为的一种实践

优势

  1. 替代大量的手工机械重复性操作;
  2. 大幅提升回归测试的效率,适合敏捷开发过程;
  3. 可利用无人值守时间,去更频繁地执行测试;
  4. 手工测试无法完成或者代价巨大的测试;
  5. 保证每次测试执行的操作以及验证的一致性和可重复性,避免人为的遗漏或疏忽。

劣势

  1. 不能取代手工测试;
  2. 自动化测试用例的维护成本高;
  3. 自动化测试用例的开发工作量远大于单次的手工测试;
  4. 手工测试发现的缺陷数量通常比自动化测试要更多,自动化仅能发现回归bug;
  5. 测试的效率很大程度上依赖自动化测试用例的设计以及实现质量;
  6. 自动化测试的初期,用例开发效率通常都很低;
  7. 业务测试和自动化测试二者紧密合作,才能高效开展自动化测试;
  8. 自动化测试开发人员必须具备一定的编程能力,这对传统的手工测试工程师会是一个挑战。

适合场景

  1. 需求稳定,不会频繁变更;
  2. 研发和维护周期长,需要频繁执行回归测试;
  3. 需要在多种平台上重复运行相同测试的场景;
  4. 某些测试项目通过手工测试无法实现,或者手工成本太高;
  5. 被测软件的开发较为规范,能够保证系统的可测试性。(⚠️ 某些用例的自动化必须要求开发人员在产品中预留可测试性接口,否则后续的自动化会很难开展。)
  6. 测试人员已经具备一定的编程能力。

05 | 你知道软件开发各阶段都有哪些自动化测试技术吗?

在软件研发生命周期的各个阶段都有自动化测试技术的存在,并且对提升测试效率有着至关重要的作用。

单元测试的自动化技术

  1. 用例框架代码生成的自动化;
  2. 部分测试输入数据的自动化生成;
  3. 自动桩代码的生成;
  4. 被测代码的自动化静态分析;
  5. 测试覆盖率的自动统计与分析。

代码级集成测试的自动化技术

比较

代码级集成测试与单元测试最大的区别只是,代码级集成测试中被测函数内部调用的其他函数必须是真实的,不允许使用桩代码代替,而单元测试中允许使用桩代码来模拟内部调用的其他函数。

Web Service 测试的自动化技术

  1. 测试脚手架代码的自动化生成;
  2. 部分测试输入数据的自动生成;
  3. Response 验证的自动化;
  4. 基于 SoapUI 或者 Postman 的自动化脚本生成。

06 | 你真的懂测试覆盖率吗?

作用

测试覆盖率通常被用来衡量测试的充分性和完整性,从广义的角度来讲,测试覆盖率主要分为两大类,一类是面向项目的需求覆盖率,另一类是更偏向技术的代码覆盖率。

需求覆盖率的统计方式不再适用于现在的敏捷开发模式,所以现在谈到测试覆盖率,大多是指代码覆盖率。

分类

需求覆盖率

指测试对需求的覆盖程度,通常的做法是将每一条分解后的软件需求和对应的测试建立一对多的映射关系,最终目标是保证测试可以覆盖每个需求,以保证软件产品的质量。

代码覆盖率

简单来说,代码覆盖率是指,至少被执行了一次的条目数占整个条目数的百分比。

价值

统计代码覆盖率的根本目的是找出潜在的遗漏测试用例,并有针对性的进行补充,同时还可以识别出代码中那些由于需求变更等原因造成的不可达的废弃代码。代码覆盖率的价值现在很多项目都在单元测试以及集成测试阶段统计代码覆盖率,但是统计代码覆盖率仅仅是手段,必须透过现象看到事物的本质,才能从根本上保证软件整体的质量。

局限性

高的代码覆盖率不一定能保证软件的质量,因为代码覆盖率是基于现有代码,无法发现那些“未考虑某些输入”以及“未处理某些情况”形成的缺陷

工具

JaCoCo

工具实现原理

实现代码覆盖率的统计,最基本的方法就是注入(Instrumentation)。简单地说,注入就是在被测代码中自动插入用于覆盖率统计的探针(Probe)代码,并保证插入的探针代码不会给原代码带来任何影响。

根据注入目标的不同,可以分为源代码(Source Code)注入和字节码(Byte Code)注入,主要使用字节码注入(On-The-Fly 注入模式和 Offline 注入模式)

07 | 如何高效填写软件缺陷报告?

总结

一份高效的软件缺陷报告,应该包括缺陷标题、缺陷概述、缺陷影响、环境配置、前置条件、缺陷重现步骤、期望结果和实际结果、优先级和严重程度、变通方案、根原因分析,以及附件这几大部分。

缺陷报告是测试工程师与开发工程师交流沟通的重要桥梁,也是测试工程师日常工作的重要输出。

缺陷报告本身的质量将直接关系到缺陷被修复的速度以及开发工程师的效率,同时还会影响测试工程师的信用、测试与开发人员协作的有效性

好的缺陷报告绝对不是大量信息的堆叠,而是以高效的方式提供准确有用的信息。

包括的内容

缺陷标题

缺陷标题通常是别人最先看到的部分,是对缺陷的概括性描述,通常采用“在什么情况下发生了什么问题”的模式。

清晰简洁,最关键是要足够具体,切忌不能采用过于笼统的描述

标题应该尽可能描述问题本质,而避免只停留在问题的表面

缺陷标题不易过长,对缺陷更详细的描述应该放在“缺陷概述”里

缺陷概述

缺陷概述通常会提供更多概括性的缺陷本质与现象的描述

清晰简洁地描述缺陷,使开发工程师能够聚焦缺陷的本质

缺陷影响

决定了缺陷的优先级(Priority)和严重程度(Severity)

环境配置

详细描述测试环境的配置细节,环境配置的内容通常是按需描述,通常只描述那些重现缺陷的环境敏感信息

前置条件

测试步骤开始前系统应该处在的状态,其目的是减少缺陷重现步骤的描述

缺陷重现步骤

用简洁的语言向开发工程师展示缺陷重现的具体操作步骤,通常是从用户角度出发来描述的,每个步骤都应该是可操作并且是连贯的,所以往往会采用步骤列表的表现形式

期望结果和实际结果

当你描述期望结果时,需要说明应该发生什么,而不是什么不应该发生;而描述实际结果时,你应该说明发生了什么,而不是什么没有发生。

严重程度是缺陷本身的属性,通常确定后就不再变化,而优先级是缺陷的工程属性,会随着项目进度、解决缺陷的成本等因素而变动。

根原因分析

如果你能在发现缺陷的同时,定位出问题的根本原因,清楚地描述缺陷产生的原因并反馈给开发工程师,那么开发工程师修复缺陷的效率就会大幅提升

附件

有界面截图、测试用例日志、服务器端日志

自己额外补充:经办人比较重要

08 | 以终为始,如何才能做好测试计划?

总结

成功的测试计划,必须清楚地描述:测试范围、测试策略、测试资源、测试进度和测试风险预估这五个最重要的方面。

测试范围

测试范围中需要明确“测什么”和“不测什么”

测试策略

明确“先测什么后测什么”和“如何来测”这两个问题。

测试策略会要求我们明确测试的重点,以及各项测试的先后顺序。

测试策略还需要说明,采用什么样的测试类型和测试方法。

功能测试

先实现主干业务流程的测试自动化。

兼容性测试

兼容性测试的实施,往往是在功能测试的后期,也就是说需要等功能基本都稳定了,才会开始兼容性测试。

性能测试

明确了性能需求(并发用户数、响应时间、事务吞吐量等)的前提下,结合被测系统的特点,设计性能测试场景并确定性能测试框架

测试资源

测试人员和测试环境,测试资源就是需要明确“谁来测”和“在哪里测”这两个问题。

测试工程师:数量及个人经验和能力

测试进度

测试进度主要描述各类测试的开始时间,所需工作量,预计完成时间,并以此为依据来建议最终产品的上线发布时间。

测试风险预估

在制定测试计划时,你就要预估整个测试过程中可能存在的潜在风险,以及当这些风险发生时的应对策略

09 | 软件测试工程师的核心竞争力是什么?

作为测试人员,必须要深入理解业务,但是业务知识不能等同于测试能力。

测试开发岗位的核心其实是“测试”,“开发”的目的是更好地服务于测试,

测试工程师应该具备的核心竞争力

测试策略设计能力、测试用例设计能力、快速学习能力、探索性测试思维、缺陷分析能力、自动化测试技术和良好的沟通能力。

测试开发工程师的核心竞争力

测试系统需求分析能力,更宽广的知识体系

10 | 软件测试工程师需要掌握的非测试知识有哪些?

总结

软件测试工程师需要掌握非常多的非测试专业知识,包括:网站架构、容器技术、云计算技术、DevOps 思维,以及前端开发技术的核心知识以及实践。

开发工程师通常是“深度遍历”,关注的是“点”;而测试工程师通常是“广度遍历”,关注的是“面”。

小到 Linux/Unix/Windows 操作系统的基础知识,Oracle/MySQL 等传统关系型数据库技术,NoSQL 非关系型数据库技术,中间件技术,Shell/Python 脚本开发,版本管理工具与策略,CI/CD 流水线设计,F5 负载均衡技术,Fiddler/Wireshark/Tcpdump 等抓包工具,浏览器 Developer Tool 等;大到网站架构设计,容器技术,微服务架构,服务网格(Service Mesh),DevOps,云计算,大数据,人工智能和区块链技术等。

网站架构的核心知识

掌握网站架构的核心知识,不需要像系统架构师那样能够熟练驾驭各种架构,并根据业务选型,但至少需要理解架构相关的基本知识以及核心原理

容器技术

Docker

个人补充:还需要了解容器编排,需掌握Kubernetes相关知识

云计算技术

作为测试工程师,你必须理解服务在云端部署的技术细节才能更好的完成测试任务。

DevOps 思维

DevOps 的具体表现形式可以是工具、方法和流水线,但其更深层次的内涵还是在思想方法,以敏捷和精益为核心,通过发现问题,以系统性的方法或者工具来解决问题,从而实现持续改进。

前端开发技术

测试工程师的角度来讲,如果能够掌握前端开发技术,也就意味着可以更高效地做前端的测试,更容易发现潜在缺陷。同时,还可以自己构建测试页面,来完成各类前端组件的精细化测试,大大提高测试覆盖率和效率

11 | 互联网产品的测试策略应该如何设计?

总结

传统软件通常采用金字塔模型的测试策略,而现今的互联网产品往往采用菱形模型。菱形模型有以下四个关键点:

  1. 以中间层的 API 测试为重点做全面的测试。
  2. 轻量级的 GUI 测试,只覆盖最核心直接影响主营业务流程的 E2E 场景。
  3. 最上层的 GUI 测试通常利用探索式测试思维,以人工测试的方式发现尽可能多的潜在问题。
  4. 单元测试采用“分而治之”的思想,只对那些相对稳定并且核心的服务和模块开展全面的单元测试,而应用层或者上层业务只会做少量的单元测试。

研发流程的不同决定了测试策略的不同

发布周期的巨大差异决定了,传统软件产品的测试策略必然不适用于互联网产品的测试,二者的测试策略必然在测试执行时间和测试执行环境上有巨大差异。

传统软件产品的测试策略设计

在这里插入图片描述

单元测试

最底部是单元测试,属于白盒测试的范畴,通常由开发工程师自己完成

API测试

中间部分是 API 测试,主要针对的是各模块暴露的接口,通常采用灰盒测试方法。灰盒测试方法是介于白盒测试和黑盒测试之间的一种测试技术,其核心思想是利用测试执行的代码覆盖率来指导测试用例的设计。

API 测试用例的数量会少于单元测试,但多于上层的 GUI 测试。

GUI测试

模拟用户在软件界面上的各种操作,并验证这些操作对应的结果是否正确。

互联网产品的测试策略设计

在这里插入图片描述

GUI测试

GUI 测试通常采用“手工为主,自动化为辅”的测试策略,手工测试往往利用探索性测试思想,针对新开发或者新修改的界面功能进行测试,而自动化测试的关注点主要放在相对稳定且核心业务的基本功能验证上。所以,GUI 的自动化测试往往只覆盖最核心且直接影响主营业务流程的 E2E 场景。

API测试
  1. API 测试用例的开发与调试效率比 GUI 测试要高得多;
  2. API 测试用例的执行稳定性远远高于 GUI 测试;
  3. 单个 API 测试用例的执行时间往往要比 GUI 测试短很多;
  4. 对微服务的测试,本质上就是对不同的 Web Service 的测试,也就是 API 测试。
  5. API 接口的改动一般比较少,即使有改动,绝大多数情况下也需要保证后向兼容性
单元测试

互联网产品的全面单元测试只会应用在那些相对稳定和最核心的模块和服务上,而应用层或者上层业务服务很少会大规模开展单元测试。

以上就是软件测试52讲中测试基础知识内容啦~

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值