前言
本篇文章为极客时间茹炳晟老师《软件测试52讲》专栏课程的学习笔记与操作实践的相关内容。原文课程链接:
https://time.geekbang.org/column/article/10030
一、常用的黑盒测试方法
作为测试工程师,你的目标是要保证系统在各种应用场景下的功能是符合设计要求的,所以你需要考虑的测试用例就需要更多、更全面
1.等价类划分方法
是将所有可能的输入数据划分成若干个子集,在每个子集中,如果任意一个输入数据对于揭露程序中潜在错误都具有同等效果,那么这样的子集就构成了一个等价类。后续只要从每个等价类中任意选取一个值进行测试,就可以用少量具有代表性的测试输入取得较好的测试覆盖结果。
2.边界值分析方法
是选取输入、输出的边界值进行测试。因为通常大量的软件错误是发生在输入或输出范围的边界上,所以需要对边界值进行重点测试,通常选取正好等于、刚刚大于或刚刚小于边界的值作为测试数据。边界值分析是对等价类划分的补充,所以这两种测试方法经常结合起来使用。
二、为“用户登录”设计测试用例
1.普通测试工程师设计的用例
基于等价类划分和边界值分析方法设计登录功能的测试用例:
- 输入已注册的用户名和正确的密码,验证是否登录成功;
- 输入已注册的用户名和不正确的密码,验证是否登录失败,并且提示信息正确;
- 输入未注册的用户名和任意密码,验证是否登录失败,并且提示信息正确;
- 用户名和密码两者都为空,验证是否登录失败,并且提示信息正确;
- 用户名和密码两者之一为空,验证是否登录失败,并且提示信息正确;
- 如果登录功能启用了验证码功能,在用户名和密码正确的前提下,输入正确的验证码,验证是否登录成功;
- 如果登录功能启用了验证码功能,在用户名和密码正确的前提下,输入错误的验证码,验证是否登录失败,并且提示信息正确。
2.优秀测试工程师设计的测试用例
上面的测试用例集已经涵盖了主要的功能测试场景。但是在一个优秀的测试工程师眼中,这些用例只能达到勉强及格的标准。有经验的测试工程师通常还会再增加以下测试用例:
- 用户名和密码是否大小写敏感;
- 页面上的密码框是否加密显示;
- 后台系统创建的用户第一次登录成功时,是否提示修改密码;
- 忘记用户名和忘记密码的功能是否可用;
- 前端页面是否根据设计要求限制用户名和密码长度;
- 如果登录功能需要验证码,点击验证码图片是否可以更换验证码,更换后的验证码是否可用;
- 刷新页面是否会刷新验证码;
- 如果验证码具有时效性,需要分别验证时效内和时效外验证码的有效性;
- 用户登录成功但是会话超时后,继续操作是否会重定向到用户登录界面;
- 不同级别的用户,比如管理员用户和普通用户,登录系统后的权限是否正确;
- 页面默认焦点是否定位在用户名的输入框中;
- 快捷键 Tab 和 Enter 等,是否可以正常使用。
3.资深测试工程师设计的测试用例
虽然改进后的测试用例集相比之前的测试覆盖率的确已经提高了很多,但是站在资深测试人员的角度来看,还有很多用例需要设计。资深测试工程师通常还会考虑非功能性需求即隐式功能性需求。
三、显式功能需求与隐式功能需求
一个质量过硬的软件系统,除了显式功能性需求以外,其他的非功能性需求即隐式功能性需求也是极其关键的。
显式功能性需求(Functional requirement)的含义从字面上就可以很好地理解,指的是软件本身需要实现的具体功能。
那什么是非功能性需求(Non-functional requirement)(隐式功能性需求)呢?从软件测试的维度来看,非功能性需求主要涉及安全性、性能以及兼容性三大方面。
下面,基于非功能需求继续补充测试用例。
1.安全性测试用例
- 用户密码后台存储是否加密;
- 用户密码在网络传输过程中是否加密;
- 密码是否具有有效期,密码有效期到期后,是否提示需要修改密码;
- 不登录的情况下,在浏览器中直接输入登录后的 URL 地址,验证是否会重新定向到用户登录界面;
- 密码输入框是否不支持复制和粘贴;
- 密码输入框内输入的密码是否都可以在页面源码模式下被查看;
- 用户名和密码的输入框中分别输入典型的“SQL 注入攻击”字符串,验证系统的返回页面;
- 用户名和密码的输入框中分别输入典型的“XSS 跨站脚本攻击”字符串,验证系统行为是否被篡改;
- 连续多次登录失败情况下,系统是否会阻止后续的尝试以应对暴力破解;
- 同一用户在同一终端的多种浏览器上登录,验证登录功能的互斥性是否符合设计预期;
- 同一用户先后在多台终端的浏览器上登录,验证登录是否具有互斥性。
- 是否可记住密码,记住的密码保存是否加密,记住密码是否有有效期,有有效期,过期之后是否会清空密码
- 是否可以使用登录的API发送登录请求,并绕开验证码校验;
- 是否可以用抓包工具抓到的请求包直接登录,截取到的token等信息,是否可以在其他终端上直接使用,绕开登录
- token过期时间校验;
- 用户登录后存储在数据库中的用户个人信息是否加密;用户登录过程中log中是否有个人信息明文打印;
2.性能压力测试用例
- 单用户登录的响应时间是否小于 3 秒;
- 单用户登录时,后台请求数量是否过多;
- 高并发场景下用户登录的响应时间是否小于 5 秒;
- 高并发场景下服务端的监控指标是否符合预期;
- 高集合点并发场景下,是否存在资源死锁和不合理的资源等待;
- 长时间大量用户连续登录和登出,服务器端是否存在内存泄漏。
3.兼容性测试用例包括
- 不同浏览器下,验证登录页面的显示以及功能正确性;
- 相同浏览器的不同版本下,验证登录页面的显示以及功能正确性;
- 不同移动设备终端的不同浏览器下,验证登录页面的显示以及功能正确性;
- 不同分辨率的界面下,验证登录页面的显示以及功能正确性。
通过上述对“用户登录”功能设计测试用例我们会发现:一个优秀的测试工程师必须具有很宽广的知识面,如果不能对被测系统的设计有深入的理解、不明白安全攻击的基本原理、没有掌握性能测试的基本设计方法,很难设计出“有的放矢”的测试用例。
四、测试的“不可穷尽性”
虽然上面已经从各个维度罗列了非常丰富的测试用例,但是谁也不敢保证就一定覆盖了所有场景。这也是测试的“不可穷尽性”,即绝大多数情况下,是不可能进行穷尽测试的。
所谓的“穷尽测试”是指包含了软件输入值和前提条件所有可能组合的测试方法,完成穷尽测试的系统里应该不残留任何未知的软件缺陷。
在绝大多数的软件工程实践中,测试由于受限于时间成本和经济成本,是不可能去穷尽所有可能的组合的,而是采用基于风险驱动的模式,有所侧重地选择测试范围和设计测试用例,以寻求缺陷风险和研发成本之间的平衡。
五、总结
首先,对于高质量的软件测试,用例设计不仅需要考虑明确的显式功能性需求,还要涉及兼容性、安全性和性能等一系列的非功能性需求,这些非功能性需求对软件系统的质量有着举足轻重的作用。
其次,优秀的测试工程师必须具有宽广的知识面,才能设计出有针对性、更易于发现问题的测试用例。
最后,软件测试的用例设计是不可穷尽的,工程实践中难免受制于时间成本和经济成本,所以优秀的测试工程师需要兼顾缺陷风险和研发成本之间的平衡。
六、精彩点评
对登录的测试还有很多很好的补充,以下摘自评论区:
1.弱网环境测试
2.从安全性方面出发的考虑
3.用户状态校验
4.多登录方式校验
5.需求合理性测试
个人感觉,这是个最与众不同的观点。很多人都只想到了场景,而忽略了需求~
七、补充与发散
1.登录测试场景补充
在评论区还看到了我本人当年的评论,好像点赞数是最多的,哈哈。就以此作为补充吧:
(主要针对APP登录测试):
1、登录失败后二次登录
(1)输入正确的用户名,不输入密码,点击登录;登录失败后,再次输入正确的密码登录并观察登录情况
(2)输入正确的用户名和错误的密码登录失败后,再次输入正确的密码登录并观察登录情况
(3)输入未注册的用户和任意密码登录失败后,再次输入正确的用户名和密码,观察登录情况
2、修改密码后
(1)修改完密码后是否重定向到登录界面
(2)修改完密码后,分别使用原密码和新密码登录
(3)在其他终端修改密码后,本终端是否自动下线?下线后,使用原密码能否继续登录?
3、退出登录
(1)退出登录是否有记住账号或记住密码功能
(2)退出登录后,再次输入密码登录
4、数据同步
(1)第一次登录时,数据的同步情况,如个人头像,好友列表等
(2)本终端切换其他账号登录后,数据的同步情况,日志记录情况,如:用户文件夹是否自动创建
5、账号互踢
(1)不同页面下被踢,如:后台运行时被踢,进入前台查看反应;前台运行时一级、二级页面下被踢能否提示正确并重 定向到登录界面
(2)本终端被踢下线后点击登录能否再次登录
6、密码错误限制次数
(1)密码输入错误是否有最大次数限制?分别测试最大值-1、最大值、最大值+1时的输错密码情况
(2)超过最大次数限制后,是否采取强制手段限制登录或对账号暂时冻结处理
(3)超过最大次数限制后,分别输入正确的密码和错误的密码再次登录
7、安全性
(1)本终端用户已登录,在其他终端尝试登录本用户账号登录失败时、本终端是否有账号异常操作的安全提示
(2)输入密码时是否有安全键盘模式?点击密码输入框是否能调起安全键盘?(参考各大手机银行APP)
8、网络相关
(1)无网络模式下登录,是否给出“网络未连接”或“网络异常”的提示及提示是否正确
(2)第一次登录请求超时后(服务器出问题,随后恢复正常),再次请求登录能否登录成功
(3)第一次无网络情况下登录失败后,再次连接网络并登录
(4)正在登录过程中,遇到网络切换,如(4G切换到WiFi环境时)能否正常登录
9、其他
(1)已登录的用户,杀死APP进程后,再次打开APP是否依然为已登录状态
2.软件测试的原则
由前面提到的测试的“不可穷尽性”,我联想到了软件测试的几大原则。其中就包括“测试是不可穷尽的”。不同的书籍中给出了不同版本,我们可以分别看一下。
在《软件测试的艺术》一书中,给出了“软件测试的十大原则”:
1.测试用例中一个必须部分是对预期输出或结果的定义
2.程序员应当避免测试自己编写的程序
3.编写软件的组织不应当测试自己编写的软件
4.应当彻底检查每个测试的执行结果
5.测试用例的编写不仅应当根据有效和预期的输入情况,而且也应当根据无效和未预料到的输入情况
6.检查程序是否“未做其应该做的”仅是测试的一半,测试的另一半是检查程序是否“做了其不应该做的”
7.应避免测试用例用后即弃,除非软件本身就是一个一次性的软件
8.计划测试工作时不应默许假定不会发现错误
9.程序某部分存在更多错误的可能性,与该部分已发现错误的数量成正比
10.软件测试是一项极富创造性、极具智力挑战性的工作
而在《软件评测师教程(第2版)》中,则给出了7条软件测试的相关原则:
1.所有的软件测试都应当追溯到用户需求
2.应当把“尽早地和不断地进行软件测试”作为测试者的座右铭
3.完全测试是不可能的,测试需要终止
4.测试无法显示软件潜在的缺陷
5.充分注意测试中的集群现象
6.程序员应避免检查自己的程序
7.尽量避免测试的随意性
3.由“登录测试”联想到的面试问答
“登录测试”是测试面试过程中最常见的一类问题,上述案例给我们提供了很多有价值的参考。然而,在很多面试过程中,通常还会有其他稀奇古怪的问题,比如:如何测试一个椅子,如何测试一个杯子。很多人喜欢一上来就回来问题,这是一个非常不好的习惯,这也是面试官给我们布下的一个陷阱!
作为测试人员,我们首先考虑的应该是理解和澄清业务需求,再去谈如何设计测试用例。比如在测试一个杯子之前,我们需要从多方面搞清楚需求:
1.从功能方面看:
- 是不是盛水的?
- 能不能加热?
- 带不带保温功能?
- 自带吸管吗?
- 带不带刻度?是不是量杯?
- .......
2.从非功能方面看:
- 耐热性怎么样:例如零下的液体、100度以上的液体
- 耐摔性怎么样
- 跟各种液体的兼容性:例如果汁、浓酸性的液体
- 安全性(是否有毒/是否可以砸伤人)
- ......
软件测试,真是一点也不简单啊!