对于高质量的软件测试,用例设计不仅需要考虑明确的显式功能性需求,还要涉及兼容性、安全性和性能等一系列的非功能性需求,这些非功能性需求对软件系统的质量有着举足轻重的作用;
测试工程师目标是保证系统在各种应用场景下的功能是符合设计要求的,因此,需要考虑的测试用例就需要更多、更全面。优秀的测试工程师必须具有宽广的知识面,才能设计出有针对性、更易于发现问题的测试用例。
软件测试的用例设计是不可穷尽的,工程实践中难免受制于时间成本和经济成本,所以优秀的测试工程师需要兼顾缺陷风险和研发成本,采用基于风险驱动的模式,有所侧重地选择测试范围和设计测试用例,以寻求缺陷风险和研发成本之间的平衡
用户登录
输入已注册的用户名和正确的密码,验证是否登录成功;
输入已注册的用户名和不正确的密码,验证是否登录失败,并且提示信息正确;
输入未注册的用户名和任意密码,验证是否登录失败,并且提示信息正确;
用户名和密码两者都为空,验证是否登录失败,并且提示信息正确;
用户名和密码两者之一为空,验证是否登录失败,并且提示信息正确;
如果登录功能启用了验证码功能,在用户名和密码正确的前提下,输入正确的验证码,验证是否登录成功;
如果登录功能启用了验证码功能,在用户名和密码正确的前提下,输入错误的验证码,验证是否登录失败,并且提示信息正确。
用户名和密码是否大小写敏感;
页面上的密码框是否加密显示;
后台系统创建的用户第一次登录成功时,是否提示修改密码;
忘记用户名和忘记密码的功能是否可用;
前端页面是否根据设计要求限制用户名和密码长度;
如果登录功能需要验证码,点击验证码图片是否可以更换验证码,更换后的验证码是否可用;
刷新页面是否会刷新验证码;如果验证码具有时效性,需要分别验证时效内和时效外验证码的有效性;
用户登录成功但是会话超时后,继续操作是否会重定向到用户登录界面;
不同级别的用户,比如管理员用户和普通用户,登录系统后的权限是否正确;
页面默认焦点是否定位在用户名的输入框中;
快捷键 Tab 和 Enter 等,是否可以正常使用。
“好的”测试用例:一个完备的集合,它能够覆盖所有等价类以及各种边界值,而跟能否发现缺陷无关。
等价类划分
从每个等价类中任意选取一个值进行测试,就可以用少量具有代表性的测试输入取得较好的测试覆盖结果。另一个关键点是找出所有“无效等价类”
边界值分析
边界值分析是对等价类划分的补充,你从工程实践经验中可以发现,大量的错误发生在输入输出的边界值上,所以需要对边界值进行重点测试,通常选取正好等于、刚刚大于或刚刚小于边界的值作为测试数据。
错误推测法
错误推测方法是指基于对被测试软件系统设计的理解、过往经验以及个人直觉,推测出软件可能存在的缺陷,从而有针对性地设计测试用例的方法。这个方法强调的是对被测试软件的需求理解以及设计实现的细节把握,当然还有个人的能力。(组件缺陷库并实时维护)
在具体的用例设计时,首先需要搞清楚每一个业务需求所对应的多个软件功能需求点,然后分析出每个软件功能需求点对应的多个测试需求点,最后再针对每个测试需求点设计测试用例。
单元测试是指,对软件中的最小可测试单元在与程序其他部分相隔离的情况下进行检查和验证的工作,这里的最小可测试单元通常是指函数或者类。
单元测试的对象是代码
要做到代码功能逻辑正确,必须做到分类正确并且完备无遗漏,同时每个分类的处理逻辑必须正确。
单元测试的用例是一个“输入数据”和“预计输出”的集合。
(Driver)指调用被测函数的代码
(Stub)是用来代替真实代码的临时代码。
桩代码的应用首先起到了隔离和补齐的作用,使被测代码能够独立编译、链接,并独立运行。同时,桩代码还具有控制被测函数执行路径的作用
Mock 代码和桩代码的本质区别是:测试期待结果的验证(Assert and Expectiation)。
自动化测试是,把人对软件的测试行为转化为由机器执行测试行为的一种实践
在软件研发生命周期的各个阶段都有自动化测试技术的存在,并且对提升测试效率有着至关重要的作用。
代码级集成测试与单元测试最大的区别只是,代码级集成测试中被测函数内部调用的其他函数必须是真实的,不允许使用桩代码代替,而单元测试中允许使用桩代码来模拟内部调用的其他函数。
测试覆盖率通常被用来衡量测试的充分性和完整性,从广义的角度来讲,测试覆盖率主要分为两大类,一类是面向项目的需求覆盖率,另一类是更偏向技术的代码覆盖率。
需求覆盖率的统计方式不再适用于现在的敏捷开发模式,所以现在谈到测试覆盖率,大多是指代码覆盖率。
指测试对需求的覆盖程度,通常的做法是将每一条分解后的软件需求和对应的测试建立一对多的映射关系,最终目标是保证测试可以覆盖每个需求,以保证软件产品的质量。
简单来说,代码覆盖率是指,至少被执行了一次的条目数占整个条目数的百分比。
统计代码覆盖率的根本目的是找出潜在的遗漏测试用例,并有针对性的进行补充,同时还可以识别出代码中那些由于需求变更等原因造成的不可达的废弃代码。代码覆盖率的价值现在很多项目都在单元测试以及集成测试阶段统计代码覆盖率,但是统计代码覆盖率仅仅是手段,必须透过现象看到事物的本质,才能从根本上保证软件整体的质量。
高的代码覆盖率不一定能保证软件的质量,因为代码覆盖率是基于现有代码,无法发现那些“未考虑某些输入”以及“未处理某些情况”形成的缺陷
JaCoCo
实现代码覆盖率的统计,最基本的方法就是注入(Instrumentation)。简单地说,注入就是在被测代码中自动插入用于覆盖率统计的探针(Probe)代码,并保证插入的探针代码不会给原代码带来任何影响。
根据注入目标的不同,可以分为源代码(Source Code)注入和字节码(Byte Code)注入,主要使用字节码注入(On-The-Fly 注入模式和 Offline 注入模式)
一份高效的软件缺陷报告,应该包括缺陷标题、缺陷概述、缺陷影响、环境配置、前置条件、缺陷重现步骤、期望结果和实际结果、优先级和严重程度、变通方案、根原因分析,以及附件这几大部分。
缺陷报告是测试工程师与开发工程师交流沟通的重要桥梁,也是测试工程师日常工作的重要输出。
缺陷报告本身的质量将直接关系到缺陷被修复的速度以及开发工程师的效率,同时还会影响测试工程师的信用、测试与开发人员协作的有效性
好的缺陷报告绝对不是大量信息的堆叠,而是以高效的方式提供准确有用的信息。
包括的内容
缺陷标题通常是别人最先看到的部分,是对缺陷的概括性描述,通常采用“在什么情况下发生了什么问题”的模式。
清晰简洁,最关键是要足够具体,切忌不能采用过于笼统的描述
标题应该尽可能描述问题本质,而避免只停留在问题的表面
缺陷标题不易过长,对缺陷更详细的描述应该放在“缺陷概述”里
缺陷概述通常会提供更多概括性的缺陷本质与现象的描述
清晰简洁地描述缺陷,使开发工程师能够聚焦缺陷的本质
决定了缺陷的优先级(Priority)和严重程度(Severity)
详细描述测试环境的配置细节,环境配置的内容通常是按需描述,通常只描述那些重现缺陷的环境敏感信息
测试步骤开始前系统应该处在的状态,其目的是减少缺陷重现步骤的描述
用简洁的语言向开发工程师展示缺陷重现的具体操作步骤,通常是从用户角度出发来描述的,每个步骤都应该是可操作并且是连贯的,所以往往会采用步骤列表的表现形式
当你描述期望结果时,需要说明应该发生什么,而不是什么不应该发生;而描述实际结果时,你应该说明发生了什么,而不是什么没有发生。
严重程度是缺陷本身的属性,通常确定后就不再变化,而优先级是缺陷的工程属性,会随着项目进度、解决缺陷的成本等因素而变动。
如果你能在发现缺陷的同时,定位出问题的根本原因,清楚地描述缺陷产生的原因并反馈给开发工程师,那么开发工程师修复缺陷的效率就会大幅提升
有界面截图、测试用例日志、服务器端日志
自己额外补充:经办人比较重要
成功的测试计划,必须清楚地描述:测试范围、测试策略、测试资源、测试进度和测试风险预估这五个最重要的方面。
测试范围中需要明确“测什么”和“不测什么”
明确“先测什么后测什么”和“如何来测”这两个问题。
测试策略会要求我们明确测试的重点,以及各项测试的先后顺序。
测试策略还需要说明,采用什么样的测试类型和测试方法。
先实现主干业务流程的测试自动化。
兼容性测试的实施,往往是在功能测试的后期,也就是说需要等功能基本都稳定了,才会开始兼容性测试。
明确了性能需求(并发用户数、响应时间、事务吞吐量等)的前提下,结合被测系统的特点,设计性能测试场景并确定性能测试框架
测试人员和测试环境,测试资源就是需要明确“谁来测”和“在哪里测”这两个问题。
测试工程师:数量及个人经验和能力
测试进度主要描述各类测试的开始时间,所需工作量,预计完成时间,并以此为依据来建议最终产品的上线发布时间。
在制定测试计划时,你就要预估整个测试过程中可能存在的潜在风险,以及当这些风险发生时的应对策略
作为测试人员,必须要深入理解业务,但是业务知识不能等同于测试能力。
测试开发岗位的核心其实是“测试”,“开发”的目的是更好地服务于测试,
测试策略设计能力、测试用例设计能力、快速学习能力、探索性测试思维、缺陷分析能力、自动化测试技术和良好的沟通能力。
测试系统需求分析能力,更宽广的知识体系
软件测试工程师需要掌握非常多的非测试专业知识,包括:网站架构、容器技术、云计算技术、DevOps 思维,以及前端开发技术的核心知识以及实践。
开发工程师通常是“深度遍历”,关注的是“点”;而测试工程师通常是“广度遍历”,关注的是“面”。
小到 Linux/Unix/Windows 操作系统的基础知识,Oracle/MySQL 等传统关系型数据库技术,NoSQL 非关系型数据库技术,中间件技术,Shell/Python 脚本开发,版本管理工具与策略,CI/CD 流水线设计,F5 负载均衡技术,Fiddler/Wireshark/Tcpdump 等抓包工具,浏览器 Developer Tool 等;大到网站架构设计,容器技术,微服务架构,服务网格(Service Mesh),DevOps,云计算,大数据,人工智能和区块链技术等。
掌握网站架构的核心知识,不需要像系统架构师那样能够熟练驾驭各种架构,并根据业务选型,但至少需要理解架构相关的基本知识以及核心原理
Docker
个人补充:还需要了解容器编排,需掌握Kubernetes相关知识
作为测试工程师,你必须理解服务在云端部署的技术细节才能更好的完成测试任务。
DevOps 的具体表现形式可以是工具、方法和流水线,但其更深层次的内涵还是在思想方法,以敏捷和精益为核心,通过发现问题,以系统性的方法或者工具来解决问题,从而实现持续改进。
测试工程师的角度来讲,如果能够掌握前端开发技术,也就意味着可以更高效地做前端的测试,更容易发现潜在缺陷。同时,还可以自己构建测试页面,来完成各类前端组件的精细化测试,大大提高测试覆盖率和效率
传统软件通常采用金字塔模型的测试策略,而现今的互联网产品往往采用菱形模型。菱形模型有以下四个关键点:
发布周期的巨大差异决定了,传统软件产品的测试策略必然不适用于互联网产品的测试,二者的测试策略必然在测试执行时间和测试执行环境上有巨大差异。
最底部是单元测试,属于白盒测试的范畴,通常由开发工程师自己完成
中间部分是 API 测试,主要针对的是各模块暴露的接口,通常采用灰盒测试方法。灰盒测试方法是介于白盒测试和黑盒测试之间的一种测试技术,其核心思想是利用测试执行的代码覆盖率来指导测试用例的设计。
API 测试用例的数量会少于单元测试,但多于上层的 GUI 测试。
模拟用户在软件界面上的各种操作,并验证这些操作对应的结果是否正确。
GUI 测试通常采用“手工为主,自动化为辅”的测试策略,手工测试往往利用探索性测试思想,针对新开发或者新修改的界面功能进行测试,而自动化测试的关注点主要放在相对稳定且核心业务的基本功能验证上。所以,GUI 的自动化测试往往只覆盖最核心且直接影响主营业务流程的 E2E 场景。
互联网产品的全面单元测试只会应用在那些相对稳定和最核心的模块和服务上,而应用层或者上层业务服务很少会大规模开展单元测试。
以上就是软件测试52讲中测试基础知识内容啦~