我们都知道全局探索性测试的漫游测试法,也知道局部探索性测试可以从用户输入、状态、代码路径、用户数据和执行环境测试着手点。
那么,如果我们能够获取开发代码,我们怎么从代码入手,进行具体的局部探索性测试呢?
简单回顾
在进行具体的案例讲解前,我们先简单回顾下局部探索性测试的用户输入、状态、代码路径、用户数据和执行环境测试方法。
一张图说明一切。
图1局部探索性测试测试要点总结
具体案例讲解
本文从代码层入手,分享如何进行局部探索性测试。值得注意的是,接下来的叙述没有优先级和重要性排序,单纯是某些测试要点的启发。
比对代码改动,寻找测试要点!
随着功能的改进或者故障的修复,总会伴随代码的改动。因此,我们可以从代码改动点出发寻找测试要点。
在此,需要大家问自己几个问题:开发人员为什么要这样改?这样改有什么意义?
图2 elasticsearch开源代码提交记录:修改远程集群设置的authorization为credentials
由上图2所示,为elasticsearch开源代码某次提交记录(修改远程集群设置的authorization为credentials)。如果我们获取到这样一份代码,我们要怎么寻找测试要点呢?!
对于代码修改的原因和意义,开发人员在代码提交记录中已经声明:credentials名字更精确。而且从提交记录中,我们还可以看到有许多地方涉及的authorization被修改。因此,我们很容易就能想到一个测试要点:authorization名字修改是否覆盖完全?!
我们再来看一个样例。如下图所示,为elasticsearch的PreviewTransformAction.java某次代码变动。
从提交记录说明可以看到变动原因:目前我们按顺序序列化转换预览文档。
然而,当我们在另一端读取它们时,我们将其反序列化为散列映射,失去顺序。因此,排序时序列化毫无意义。但是在集成测试时,writeMapWithConsistentOrder的使用总使得集成测试失败,因此将其改为无功能影响的writeGenericMap。
由此我们一眼可以得出最重要的一个信息:功能不影响。
所以,对此次变更,我们应首要进行功能回归测试,确保已有功能正常。那还有没有其它测试要点呢?试试writeGenericMap是否真的是无顺序转换?
图3 elasticsearch开源代码提交记录:修改writeMapWithConsistentOrder方法调用为为writeGenericMap调用
注意覆盖代码中的分支!
开发代码中经常会有if…else、switch…case等分支,可是当我们从外部进行场景测试或功能测试时很少能覆盖完全代码中的分支,从而可能忽视某些故障。因此,可以从代码层面出发,寻找或构造能够触发代码某个分支的场景。
图4 elasticsearch的ElasticsearchException.java某部分代码1
如上图4所示,为ElasticsearchException.java某部分代码。该代码使用了if…else分支结构,面对这样的代码,我们是不是首先就会想:如何进入不同分支?进入不同分支后会有什么样的效果?
如上图所示,试试elasticsearchException不为null呢?再试试id!=127呢?更或者,试试传入的id为null呢?
图5 elasticsearch的ElasticsearchException.java某部分代码2
如图5所示,switch…case分支,想想:测试场景中覆盖完了所有case分支吗?如果没有,如何构造场景走到这些分支,尤其是default分支?
3)异常都捕获到没?
我们在测试过程中,经常由于环境或其他原因的影响造成一些异常的产生。而针对异常的捕获往往是代码中预先定义好的,但如果异常不在期望中呢?是否能够正常打印异常和捕获异常?
图6 elasticsearch的ExceptionsHelper。。java某部分代码
如图6所示,是try…catch…finally结构,但没有catch分支。假如formatStackTrace功能异常呢?能够捕获异常吗?试试。又或者ExceptionsHelper。maybeError(throwable)不存在呢?会是什么样的效果,试试。
4)不同的return返回值尝试过没?
如题所述,试试不同的返回值对调用者的影响。看看是否调用方都能够正确处理或响应。如下图7所示,试试不同case分支下的返回值,尤其是不常见用的返回值,如PARTIAL、INCOMPATIBLE等。
图7elasticsearch的SnapshotState。java某部分代码
5)如果变量不在定义的集合范围内呢?
代码中我们难免会定义一些列表或集合,会声明列表或集合元素的类型。那么,如果某个变量不在定义的类型范围内呢,要使用列表或集合的功能处理这个变量,会怎么样?
图8 elasticsearch的SnapshotsInProgress。java某部分代码
如上图8所示,定义返回类型为List<String>,如果返回值的类型不是list或者列表中的值不是String呢?想想。
6)正则表达式呢?
正则表达式是很多测试人员头疼的一点,因为人工解析不太顺畅。在此可以给大家推荐一个很好的解析器网址https://regexper.com/#%5Ba-zA-Z_0-9%5D%7B3%2C%7D。如下图所示,将正则表达式输入,就可以解析。
图9 regexper。com正则表达式解析网站
假如针对[a-zA-Z_0-9]{3,}这样的正则表达式,试试输入变量为345呢?会有什么样的效果?
7)代码中有没有写死的变量?
比如常见的引用ip、port等,是否被固定了?比如有没有用到sleep?被写死的变量会导致代码更改时容易忽略,而产生异常。而sleep 10s这样的写法会导致性能下降。试试有没有这样的问题?
8)每一条路径走完没有?
在这里可以给大家推荐一个好用的工具visustin(www.aivosto.com),可以解析代码路径,可视化输出。支持java,jsp,python等多种语言。
图10 visustin软件解析代码路径样例图
如上图所示,在visustin的帮助下,我们可以方便地看出每条路径。试试遍历所有路径?
3.总结
探索性测试的核心在于启发性思维。本文结合具体样例,简单讲述了如何从代码层面入手,开始局部探索性测试。并简单介绍了两个有用的工具regexper.com网站和visustin软件,它们可以帮助我们解析正则表达式和可视化代码路径。工欲善其事必先利其器,希望这两个软件也能帮助到你。
探索性测试是一门值得研究和探讨的课题,尤其是对于测试人员来说,对于专业能力的提升和个人职业的发展都有帮助。希望能有更多的同行加入探讨和研究。
最后:
可以到我的个人号:atstudy-js,可以免费领取一份10G软件测试工程师面试宝典文档资料。以及相对应的视频学习教程免费分享!其中包括了有基础知识、Linux必备、Mysql数据库、抓包工具、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试持续集成、测试架构开发测试框架、性能测试等。
这些测试资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!