文档开发者中心
我的

值得细读的测试设计好文:搜狗灰盒用例设计思想和方法

本文转载自51testing第39期电子杂志。不得不说这是一篇描述测试设计过程的好文,搜狗虽然没有使用MBT/RBT/HTSM/探索式测试等前沿花哨的测试方法(唉,我又反动了),但是他们用大道至简的方式描述了如何设计出好的测试用例。对于刚开始做测试设计的同事来说有很大的启发性和借鉴性,而且很多测试设计思路/理念其实与我司是一致的。
我最喜欢其中的一句话:作为一名光荣而自豪的测试工程师。

《搜狗灰盒用例设计思想和方法》  --作者:搜狗测试deadwalk

前言
本章内容旨在向大家介绍桌面组的测试设计思路和方法,不论你是新加入测试的初学者,还是从事一段测试的实践者,通过阅读这篇文章相信可以帮助你更加深入地了解桌面组的测试。
我们在测试过程中经常会遇到以下问题:
. 如何进行测试设计?
. 测试设计的过程是怎样的?
. 什么是测试对象?为什么要进行测试对象的拆分?
. 常见的测试用例设计方法有哪些?
. 如何进行开发实现了解在灰盒层面进行测试?
. 为什么要进行灰盒层面的测试?
. 如何提升自己的测试发散度?
以上诸多问题可能是新加入测试的同学或者从事一段时间测试之后,同学们常见的问题,下面我们将逐一解答大家的问题。

一、测试流程介绍
当大家拿到一个新产品或新功能时,有没有考虑如何进行测试?
答案是多种多样的。有些人可能会说要严格的按照软件工程的控制过程,进行单元测试、集成测试、系统测试等;有些人可能会说直接进行黑盒的测试设计,然后执行黑盒测试用例就行,保证黑盒测试做好就行;有些人甚至可能会说不用做复杂的测试设计,直接把产品拿来就用,当做一个实际用户来进行产品的使用即可。
这些答案,我觉得是仁者见仁智者见智,不同项目的质量要求、不同项目的迭代周期,不同项目所处阶段决定了它的测试方法、测试流程。之前曾听说有些项目组(如手机输入法)每天就进行大量的随机测试,但是同样能够保证软件的质量。从这个问题,我们可以看到测试流程在整个测试中的重要性,首先我们先讨论这个测试流程。
是不是测试流程一定要具备类似于传统软件行业的双V模型(后续会做介绍)等规范化的流程才能称之为测试流程?我个人的意见是不一定。互联网软件行业最大的一个特征就是快速迭代,通过不断地、持续地进行增量式的迭代开发,在较短的周期内进行软件需求、设计、开发、测试并上线。虽然这个过程中各方没有规范化的文档,没有按照规范化的流程来做事,但是通过快速迭代吸引到大量的用户,这个收益和战略意义远比完备的文档要大得多。所以,我们首先要想大家介绍的是,桌面测试组目前的开发模型和测试流程。
1. 常见的软件开发模型:瀑布模型和双V模型
我们先了解一下常见的软件开发模型有哪些。一般常见的软件开发模型有:瀑布模 型、V 模型、双V 模型,这类开发模型被应用于中小型企业的软件开发过程中。不太常见的有RUP 模型、螺旋模型等,这类一般用于大型的复杂软件开发过程,例如航天相关软件、银行系统等。 (参考资料:)
a.瀑布模型:
该模型给出了固定的顺序,将生存期活动从上一个阶段向下一个阶段逐级过渡,如同流水下泻,最终得到所开发的软件产品,投入使用。



b.双V模型:

2. 搜狗桌面组的开发模型:

a.相同点:
i.测试尽早介入。可以看到在需求撰写和制定的阶段,测试人员就已经介入,进行需求的了解和外围黑盒测试设计。这一点与双V模型是类似的,测试越早介入,越容易提早发现问题。
ii.都需要经过一个需求->开发->测试的过程。
b.不同点:
i.与其他模型相比,这个过程中没有里程碑的概念(里程碑是指上一个阶段所有的产出达到标准后才能进入下一个阶段)。
在产品需求已经给出之后,开发可能已经着手进行产品的开发或者技术准备,测试也已经着手进行测试用例准备,此时出现需求考虑不全等问题,可以随时进行问题的沟通和改正。它所带来的问题是已经设计的用例可能要被改写甚至删除。
ii.没有单元测试、集成测试阶段。
传统的软件开发流程中,单元测试和集成测试有着重要的地位和作用,它可以在开发过程的前期,投入一定的成本进行相关函数和模块的测试,将缺陷在早期即被发现。
Note:
可能会有同学会问,既然单元测试和集成测试这么好,为什么我们不去做?
1)单元测试和集成测试需要相应的详细设计文档、概要设计文档来进行支持,同时编写相应的测试代码才可以进行,这需要投入不少的时间和成本。
2)单元测试仅能发现功能的逻辑是否正确,但是不能发现功能的逻辑是否合理。在互联网软件快速迭代的特性下,这个过程是无法满足要求的。
综上所述,桌面组的测试过程是一个全程参与产品需求、设计和测试的过程,同时由于互联网快速迭代的特性,决定了测试过程并不是严格遵照软件工程的开发模型而进行的。快速迭代、周期较短、受众用户广从而对产品质量有着更高的要求,决定了我们要走一条有自己特色的测试发展路线。

二、测试用例设计过程
桌面组的测试用例设计过程一般会经过这样几个过程:
.产品需求了解与确认、
.黑盒层面测试对象拆分、
.黑盒层面测试点发散、
.开发实现的了解、
.实现层面的测试对象拆分、
.实现层面测试点发散,
.撰写测试用例。

1. 产品需求的了解和确认:
a.测试的本质:
测试的本质是使用人工或者自动手段来运行或测试某个系统的过程,其目的在于检验它是否满足规定的需求或弄清预期结果与实际结果之间的差别。需求是测试的出发点,测试用例的设计是基于需求的,所以在测试开始之前,了解需求、搞清需求、评审需求是测试首要做的事情。
(源文档 < )
b.需求确认:
作为一名光荣而自豪的测试工程师,公司赋予我们的第一项职责即是对产品需求文档进行把关。产品需求文档可能存在着各种先天不足,例如需求描述不够详细、需求考虑不够全面,需求设计不合理,甚至需求写得比较简单或者没有需求,所以我们要对需求进行确认。
i.对需求中不明确的地方进行确认:
需求文档中常见的一类问题是需求未做明确的说明,导致我们设计测试用例时不知道预期结果应该是什么样。这类不明确预期的、容易产生歧义的需求点我们都应该提出问题尽早确认,例如以下问题:
实例:我的最爱页面需求
1)需求中"不支持自定义换肤",这个自定义换肤是指什么功能?
2)需求中"用户可根据背景搭配适合的字体颜色",如何根据背景搭配适合的字体颜色,是程序自动搭配还是用户主动选择搭配?
3)起始页8宫格和12宫格的智能判断逻辑中,分辨率的阈值是多少?
4)……
ii.对需求中未考虑的隐性需求进行确认。
需求文档中另一类最常见的问题是需求考虑不全,隐性需求未被考虑。这类隐性需求往不是功能表现层面能够预见到的,它属于一些不常见情况或特殊情况。
举例说明:起始页九宫格会对页面进行截图,我们往会预见到的是截图应该长什么样,高多少,宽多少、鼠标hover显示什么样的效果,但是不容易预见到截图失败应该显示什么样,首次打开起始页未进行截图时显示什么样。所以我们会产生如下的问题列表:
1)起始页九宫格中的网站未截取到截图时,默认显示什么样?
2)鼠标Hover到起始页标题上是否有Toltip提示?
3)起始页标题文字长度是否有限制?
4)切换皮肤是否需要统计Pingback?
5)覆盖安装旧版本后,皮肤如何显示?
6)……
Note:
确认需求的过程中可以参考测试知识库的需求Review列表,帮助我们进行隐性需求的补充和确认。
ii.对需求中的合理性问题进行评审。
需求文档中同时存在的一种问题是:产品的需求设计并不一定是合理的。请记住,产品人员设计的需求不一定就是合理的需求,开发人员设计的程序框架也不一定是合理的,作为测试我们有责任指出问题,凡事都要带一个怀疑的态度。
举例说明:浏览器
2.1版本时,产品人员当时设计的一个需求:当浏览器占用的内存较多时,弹出气泡提示用户内存占用较多,并给出按钮让用户选择清理内存。产品人员的本意是想通过弹泡告诉用户内存需要清理,让用户接受清理内存时所有页面会被重新加载(因为技术原因需要杀死所有进程并重新创建进程以达到清理内存的目的)。但是,我们仔细思考会发现需求并不合理,当用户正在浏览网页的时候,突然以弹泡的形式打扰用户,这是一种极不友好的用户体验;很多用户又都是初级用户,并不理解内存大了能怎样,不明不白地点击按钮致使页面全部被重新加载,留下的只是不解和抱怨。后来经过测试人员的推进,这个需求最终被取消了。
c.需求确认方法:
一般需求确认的方法采用邮件的形式,也可以进行口头直接沟通,最终目的是将需求确认并且公示全组。邮件形式的话,可以将需求确认邮件发送给对应的产品人员,同时抄送给对应的开发和测试组,邮件标题为"【需求确认】XX功能",邮件内容为具体问题的描述,形式不限。
作为一名光荣而自豪的测试工程师,公司赋予我们的第二项职责,监督产品的需求文档的更新,务必确认沟通并确认后的需求更新至对应的需求文档中,口头沟通的需求务进行公示。

2. 黑盒层面进行测试对象拆分:
a.测试对象拆分介绍:
i.测试对象拆分是什么?(what)
1)测试对象拆分即是将一个测试对象,根据产品表现形式或者功能实现方式,划分为更细粒度的测试对象的过程。
2)根据产品表现形式拆分。
举例说明:搜狗浏览器最常使用的一个功能:我的最爱起始页(不熟悉的同学可以安装搜狗浏览器后打开这个页面使用)。根据产品表现形式可以分为我的最爱、页面导航、TAB页切换等大的功能;针对我的最爱又可以进一步划分为搜索引擎、天气预报、九宫格、最近关闭页面、换肤等功能。
3)根据功能实现方式拆分
举例说明:我的最爱起始页中搜索引擎已经被我们拆分为一个测试对象,它还可以拆分为设置搜索引擎、切换搜索引擎类型、搜索栏Sugestion和执行搜索等。在搜索栏输入文字后,搜索栏会自动显示一个下拉列表,这个下拉列表可以显示输入内容相关的提示文字。例如输入"搜狗",下拉列表会显示搜狗输入法、搜狗浏览器、搜狗地图、搜狗搜索等提示。这个功能的实现根据后期
了解,我们可以划分为发送HTTP请求、接受HTTP返回结果并解析和搜索sugestion列表的显示。(第4章我们会详细介绍为什么要进行开发实现的了解,以及为什么要进行实现层面的拆分)
ii.为什么要做测试对象拆分?(why)
1)有助于对测试对象进行测试点归类,不会造成检查点遗漏。
举例说明:我们测试一个窗口,我们会测试窗口显示是否正确。但是可能会忽略了窗口的标题文字、窗口的icon显示、窗口在任务栏的状态,窗口的位置….甚至窗口获取焦点后在任务栏的闪烁等。
2)有助于对测试对象进行测试点发散。
举例说明:如上例所说,如果我们拆分到窗口标题,那么可能会考虑切换标签页后,窗口标题的内容显示;如果我们拆分到窗口的icon,那么可能会考虑
16*16的icon、256*256的icon,win7系统下icon的显示等。
这种思考方法是从一个点联想有关系的多个点的过程。可能有同学会反问上述举例中的窗口标题、窗口icon都是系统处理的,我们有必要进行测试吗?如果你在BUG库筛选一下浏览器、输入法等产品早期的BUG,相信你会得到答案。
ii.如何进行测试对象拆分?(how)
1)抽象和概括功能点。在需求层面对产品的功能进行概括,形成比较独立的测试对象(一级模块划分)
2)针对已经拆分的较为独立的测试对象进一步进行拆分。
测试对象拆分举例:
i.实例:天气预报扩展


ii.拆分过程:
刚拿到天气预报这个扩展,我们可能会觉得这个扩展没什么可测的,就是一个预报天气的扩展而已。那么有这么几个问题是否会进行考虑?
1)天气预报的背景是否进行了考虑?如何对天气预报背景进行考虑?
2)天气预报的天气描述文字是否进行了考虑?类似于"多云转阴"的天气描述信息最长能显示几个字符?
3)天气预报中的温度是否进行了考虑?温度最低温度能显示零下多少度?
以上看似非常简单的问题,实际测试过程都发现过问题,例如:天气描述文字最长可以为"雷阵雨转中到大雨"8个字符,由于开发未做处理导致文字显示断行不够美观;温度显示中,由于未对零下摄氏温度的显示做考虑,导致-20℃~-10
℃文字折行等。这些问题可以通过对测试对象拆分,由大到小逐层的发散和考虑,逐步达到全面覆盖。
天气预报扩展是一个比较简单的扩展,但是测试的思考方法和思路与其他复杂模块是类似的,接下来我们一步剖析和实战拆分过程。
1) 抽象和概括功能点。
抽象和概括功能点是一个归纳和概括需求的过程。我们可能在一篇需求文档中看到许多的需求点,这些需求点往是比较零散和细碎的,我们需要对这些需求点进行归纳,以便我们更好的理解和组织测试用例。这就好比我们整理书籍的时候要把与上课相关的书放在一个抽屉里,把课外的小说放在另外一个抽屉里一样。如果没有归纳和概括的过程,只是从头到尾一股脑地按照产品需求文档给出的需求点设计,那么会缺少一个统看全局的过程,缺少对整个功能轮廓的理解,测试用例的组织也会零散缺少条理,这样不利于我们去查遗补漏。
Note:有一种归纳方法是这样的,我们将自己视为一名产品人员,将产品需求有着相关性的概括为一个功能;然后重新审视一遍需求,确保各个需求点都在所概括的功能之内覆盖。
举例说明:
天气预报扩展分析其需求,大致有以下几点:
a)打开天气预报窗口,显示当天气温显示;
b)打开天气预报窗口,显示未来4天天气;
c)天气预报可以设置不同的城市,设置城市后显示对应天气的信息;
d)点击工具栏天气预报之后,浏览器弹出气泡显示天气预报内容。
e)当显示天气预报内容之后,点击其他区域,天气预报窗口消失。
f)天气预报窗口不再显示时,工具栏仍然可以实时显示天气信息。
g)右键点击工具栏天气预报之后,选择菜单中的访问"中国天气网",浏览器可以新开页面访问中国天气网。
上述需求中,a)、b)、c)我们很容易思考到并概括出当天气温显示、未来4
天天气显示、城市设置三个功能;但是d)、e)、f)、g)没有被涵盖到,而如果将以上需求点分别概括为不同功能后,那么显然没有达到我们合理组织的目的。
对此,我们分析a)、b)、d)都是在显示天气预报窗口时才能显示的,我们可以归纳为一个天气预报窗口的显示;与窗口显示相反的联想到窗口的消失,对此我们可以归纳为一个天气预报窗口的关闭用于覆盖e);城市的设置与窗口显示和关闭都是不相干的,它后台所做的是城市设置的保存和读取,所以我们单独归纳为天气预报设置(c);因为工具栏和天气预报窗口在表现层面是两个不同的对象,他们并不是相互依赖才能展示的,所以我们将工具栏的显示(f)归纳为一个单独功能;剩下g)还没有被覆盖,所以我们单独归纳外部链接为一个单独的功能。
通过以上分析和概括,我们得到工具栏显示、天气预报窗口的显示、天气预报窗口的关闭、天气预报设置和外部链接五部分。
Note:对功能点的概括思路可以建立在功能之上,而不仅限于通过UI进行概括,所见即所得,例如:有些同学可能会用比较直观的方法来概括功
能,"查看当前天气情况",或者为"点击工具栏天气预报扩展"等。这类功能的概括太过具体,可能会不容易发散到其他测试点,比方说,点击工具栏天气预报提示,可能很难考虑到从工具栏的更多菜单中打开天气预报提示等,所以我们需要对功能进行抽象和概括。
抽象和概括测试对象之后,每一个对象还可以继续细分。
举例说明:我们将天气预报的显示按照如图所示的红线部分进行归类和划分,可以划分为:城市名称的显示、日期的显示、实时天气的显示、未来4天天气的显示。进一步观察和Review会发现我们容易忽略的几个部分,如背景图的显示、Loading加载条显示。所以,根据以上的分析,我们得到下图的拆分结果:
Note:测试发散推荐使用MindManager,可以很清晰地看到思路展开过程。
举例说明:我们对工具栏天气的显示进行拆分,得到天气图标、地区、温度、Toltip提示文字等。
通过以上的分析,我们得到以下天气预报的框架图(其中天气预报的设置和外包链接未做详细拆分介绍)。
2) Review需求
通过概括和抽象功能点之后,我们基本完成了测试大纲的建立。但是概括和抽象的过程不可避免会遗漏一些不容易考虑到的需求,所以我们还需要Review
测试大纲。
Review的方法:
a)可以对照需求文档再过一遍,看有没有遗漏的功能;
b)访问测试知识库的公共用例(搜狗内部系统)看看有没有常见的容易遗漏的需求。
思考题:如果测试设计时,经常能够在测试知识库中发现自己容易遗漏的问题,如何改进自我避免遗漏呢?
举例说明:通过Review需求,我们了解到天气预报扩展文件每次安装时都会弹出如下安装对话框,该对话框中的作者、描述、版本号和数字签名都需要验证。
所以,天气扩展的安装需要验证。通过安装功能进而联想到扩展的升级,所以在原有测试大纲中增加天气扩展的安装、升级和卸载,重新组织测试大纲结构得到如下内容:
拆分的越细,能够考虑和发散的测试点越多,所以可以继续拆分的考虑继续拆分下去,例如:实时天气的显示通过界面UI 布局,拆分为实时温度、湿度、风力、天气描述、温度范围等,那么实时天气的显示进一步被拆分为对应的测试对象。
拆分的原则可以灵活掌握,如果继续细分下去对于测试发散度没有太大帮助的话,可以不继续拆分。
Note:拆分粒度的建议--属于UI层面的测试对象,建议拆分的粒度到最小的元
素,例如一个按钮、一段文字、一个图标、一个单选框控件等。属于功能实现层面的测试对象,建议拆分的粒度到一个不可继续拆分的功能逻辑,例如写文件、写注册表,再往下细分是具体的接口函数了,这些函数大多是已封装好的系统函数或第三方函数,可以不用拆分。
3) 多维度影响的考虑
由于我们尽可能的对一个测试对象进行细化和拆分,针对每一个小的测试对象进行测试和发散,但是这也带来一个问题:将各个功能组合起来的集成测试(
黑盒测试理论叫系统测试)不够,例如:
. 覆盖安装为旧的浏览器版本,天气预报扩展能否使用?
. 登录通行证账户后,同步通行证数据,自动下载并加载天气预报扩展后,天气预报的地理位置是否与当前一致?
. 在教育网环境下,开启全网加速功能后,天气预报的实时天气能否正常显示?
通过以上问题,我们看到功能与功能之间相互作用的影响,用户实际使用的复杂场景也是我们设计中需要考虑的。在此我们通过一个事例来说明相关项考虑不够导致上线事故的问题:
浏览器2.0版本对收藏功能进行了重构,我们整个测试过程中对于收藏的添加、删除、拖拽、编辑、显示、重命名等各方面进行了测试,但是忽略了这样一条路径:用户安装1.4版本浏览器后,覆盖安装到2.0版本浏览器。在发现
2.0版本是试用版之后,又重新覆盖安装到1.4较为稳定的版本使用,结果导
致收藏丢失。丢失的原因是由于数据库格式被升级后,旧版本浏览器无法识别。
为了解决类似以上的问题,我们在测试大纲中增加一项"黑盒测试",在这个黑盒测试中,可以着重考虑功能之间相互影响的测试、用户使用场景下的测试:
至此,一个功能黑盒层面的测试大纲拆分过程结束了。

3. 黑盒层面进行用例发散:
a.黑盒层面的用例发散:
在上面文章中,我们介绍了测试大纲的建立和拆分过程,这个过程帮助我们梳理和整理了待测试功能在大方向上的思路和测试范围,我们可以把测试大纲比作"骨架";接下来,我们要在"骨架"的基础上丰富内容,形成饱满的内容。
为了保证功能和功能之间的测试被覆盖到,我们可以首先在黑盒测试这里进行用例发散。用例的发散主要考虑别的功能模块对当前模块有什么影响,以及当前模块对别的模块有什么影响,顺着这个思路进行用例相关的发散。例如:
i.常见的我们会考虑覆盖安装对当前模块的影响;
ii.全屏模式对当前模块的影响;
ii.切换标签页对当前模式的影响;
以上思路主要是针对当前模块,考虑哪些模块与当前模块有关联,再加上平时测试积累的测试经验进行猜测和发散。
另外一种发散方法可以考虑用户使用的场景进行发散,例如:
i.当前用户经常在网吧上网,那么通过通行证进行数据同步是其经常使用的场景。我们可以考虑当用户在网吧电脑上首次安装搜狗浏览器,登录通行证之后,使用天气扩展插件,测试天气扩展可以自动同步并使用等。
ii.当前用户为老年人一族,上网目的主要是查看新闻或者查看天气预报。该类型用户的特点是字体比较大,系统中DPI设置为最大的120,页面缩放比例也是120%以上,那么这种情况下我们会考虑系统分辨率在1024*768分辨率下天气扩展的显示正常,没有错乱。
以上的思路是根据用户使用场景进行思考和发散。
b.根据拆分的测试对象进行用例发散:
在黑盒层面的发散补充之后,我们将在上例中拆分的每一个模块进行逐级的用例发散。
举例说明:天气预报窗口的显示,它下面包含了loading加载条的显示、城市名称的显示、日期的显示等,我们针对每一个模块进行展开考虑。
i.Loading加载条的显示。针对这个模块,我们思考什么情况下会显示
Loading的加载条,什么测试点会影响到加载条。
我们可能会考虑到的是:
1)第一次打开天气扩展时,需要考虑天气扩展读取文件过程显示Loading加载条。
2)第二次或者多次反复打开天气扩展,Loading加载条的显示。(较好的用户体验是不再显示Loading加载条)
3)更换城市时,读取城市天气的过程需要Loading加载条进行场景切换。
4)天气信息已经加载完毕后,验证Loading加载条消失。
……
ii.城市名称的显示。针对城市名称,我们同样思考什么情况会影响到城市名称的显示,或者我们可以使用黑盒用例常见的"边界值"进行发散:
1)长度为2个字、3个字、最长为7个字的。
2)当前系统默认字体为微软雅黑等其他字体后,可能会影响到城市的显示,需要进行考虑。
依次类推,日期的显示、天气的显示、温度的显示、天气说明的显示均
可以参考"等价类"、"边界值"的方法进行考虑。
ii.天气预报的窗口。除了上述对于天气预报窗口内的文字、图标、背景的测试外,我们还需要考虑天气预报窗口的测试:
1)什么情况会影响到窗口的显示。
2)什么情况会影响到窗口的位置。
3)什么情况会影响到窗口的消失。
根据测试经验和之前总结的公共用例库,我们可以发散到如下的测试点:
影响窗口显示的影响因素可能有:
a)入口:包括从工具栏、从扩展插件盒子,从菜单栏更多菜单、通过右键菜单打开天气预报扩展。
b)当前系统的分辨率,可能影响
c)当前浏览器窗口的大小(最大化、全屏、非最大化)
d)当前浏览器窗口宽度小于天气预报窗口宽度
……
影响窗口位置的影响因素可能有:
a)当前浏览器窗口在屏幕的位置(左侧、右侧、上方、下方)
b)当前系统为双屏浏览器
c)存在置顶窗口时,天气扩展窗口能显示在置顶窗口下方。
……
Note:进行测试发散时,不要忽略了数据来源的正确性。例如:在天气扩展中测试日期显示的时候,我们会测试日期的文字显示正确,没有错行;日期的显示位置居中等等,但是不要忘记验证当天到底是星期几!
经过测试发散,我们在"骨架"上补充了"血肉",这些"血肉"就是一个的测试点:

4. 开发实现了解:
a.我们为什么要了解开发实现?
这是一个新来同学经常问到的问题,我们得从黑盒测试和白盒测试的作用进行解释。黑盒测试是一个从需求层面、用户使用层面进行功能测试的过程,测试的目的是验证产品实现与需求是一致,而程序的执行过程和实现方法对于测试人员是不可见的,所以我们称之为黑盒测试。白盒测试是一个从代码层面,针对代码逻辑实现进行测试的过程,测试的目的是验证函数的输出结果与开发设计文档是一致的。
是不是仅做好黑盒测试就可以保证产品质量没有任何问题了呢?答案是否定的。
互联网产品的特点是什么?快速迭代,开发和测试周期比较短。
如何能够做到在尽可能快速迭代、周期比较短的情况下,保证产品的质量得到最大限度的覆盖和保证呢?经过桌面组多年的实际项目经验,我们归纳总结出一套方法:除了进行黑盒层面的测试之外,对于复杂的功能模块进行实现层面了解,补充实现层面的可以测试的测试点,尽可能在测试广度上和测试深度上进行覆盖,我们称之为灰盒测试。
与传统意义上的测试不同的是:与黑盒测试相比,要测得多,测得深;与白盒测试相比,不需要花费较大的精力写专门的测试代码,而是由了解实现发散实现层面的测试点,然后通过外围黑盒测试来构造,比白盒测试要快。
举例说明:浏览器的升级功能
升级功能是一个常见的软件功能,输入法要进行程序的升级,浏览器也要进行程序的升级。那么升级功能我们不了解实现时考虑到的测试点有哪些?
1) 未了解实现的测试点可能有:
已安装旧的版本情况下,执行升级,验证可以升级到新版本
升级时的UI显示
升级时的各类操作(取消、关闭)
升级后程序原有功能正常
2) 开发实现的了解:
3) 新增加的测试点:
经过开发实现的了解,我们知道功能需要读取注册表键值判断升级是否启动、需要发送网络请求查询版本信息、需要进行MD5计算校验文件完整性。所以我们会联想到如下的测试点:
启动升级程序:
当天首次启动浏览器,验证升级程序运行
非当天首次启动浏览器,验证升级程序不会运行
升级程序所在路径是中文路径或者带有空格路径,验证升级程序能够启动运行
验证升级程序带有数字签名,不会被杀毒软件和防火墙拦截
……
发送HTP查询请求:
验证发送的请求带有当前浏览器的版本号、渠道号和机器名,以便可以控制待升级的版本和渠道
……
版本比较:
服务器没有返回信息时,验证升级程序不会崩溃
服务器返回502/404/403等异常信息时,验证升级程序不会崩溃
DNS无法解析情况下,验证升级程序不会崩溃
服务器返回的版本号大于当前版本
服务器返回的版本号等于当前版本
服务器返回的版本号小于当前版本
……
下载升级文件:
下载过程中断网,验证升级程序不会卡死、崩溃,同时可以重试
下载文件的下载路径为中文路径或带有空格路径
运行安装包:
当前账户为受限账户,验证安装包以管理员身份运行安装
当前浏览器正在运行时运行安装包,验证已有浏览器会被关闭
……
b.了解开发实现测试设计的弊端是什么?
上面我们讨论了为什么要了解开发实现,这有利于我们挖掘更多的测试点。但是了解开发实现的弊端是什么?了解开发实现仅能够帮助我们了解一个函数或者一个功能是如何一步一步运行的,但是不能帮助我们辨别这种过程是否合理。所以,请谨记我们了解实现的目的是挖掘更多的测试点,但是不要忘了或者忽略外围黑盒的测试,要同时做到测试的广度(黑盒)和测试的深度(灰盒)。
c.是不是所有的功能都要了解开发实现?
了解实现的目的是帮助我们挖掘更多的测试点,但是有些模块在了解实现后并不能对测试发散度有所帮助,所以并不是所有的功能都有必要挖掘到开发实现,比如弹泡提示、Toltip显示、菜单功能等这些简单的功能;对于有些复杂的功能,例如通行证同步、皮肤系统等复杂模块,可以考虑开发实现了解。
d.了解实现的几种方式:
i.开发给出相应的设计文档。
由于项目进度压力,开发人员能力高低、模块的复杂程度等因素的影响下,有些开发人员可以给出详细的设计文档,有些开发可能连指导文档都是没有的。对于能够给出设计文档的开发人员,我们鼓掌欢迎;对于不能够给出设计文档的,也请同学们互相体谅。
ii.直接与开发进行沟通。
作为一名光荣而自豪的测试工程师,公司赋予我们的另一项职责即是与开发人员进行实现层面的沟通。请记住我们了解实现的目的是更好地测试一个产品。
思考题:如何与开发进行开发实现层面的沟通?
ii.由有经验的测试人员进行代码调研,给出调研结果。
iv.自己阅读代码了解实现。

5. 实现层面测试对象拆分
a.根据实现画出流程图:
举例说明:经过实现层面的了解沟通,我们在实现层面了解到实时天气信息的获取过程是这样实现的:
Note:绘制流程图是一个了解实现很好的习惯。它不但有助于我们系统全面地了解实现过程,同时还便于我们根据流程图拆分实现层面测试对象。
b.归纳实现过程:
为了便于梳理和组织测试用例,同时也为了便于我们查缺补漏,我们仍然需要对实现过程进行归纳和概括。在画出流程图之后,流程图中每一步都可以看做是一个子功能,都可以作为一个测试对象。
举例说明:服务器根据IP地址返回归属地这个逻辑是在服务器上运行的,而我们的测试对象是客户端的天气扩展,我们测试的重点是天气扩展在接收到服务器不同数据情况下能够正常处理并显示,而服务器的功能逻辑不在我们的测试范围内。因此,我们把服务器上的功能逻辑忽略,而客户端在解析服务器不同数据最终会作用在天气信息的显示上,所以将天气信息的解析和显示看做是一个过程,解析结果影响着显示,解析最终的结果反映在显示上。
1).归属地查询请求过程:
扩展向服务器发送归属地查询请求,如下图61.4.185.48地址请求信息,发送的请求会携带当前机器的IP地址。
2).归属地结果解析过程:
服务器收到查询请求之后,根据IP地址查询到归属地返回城市编号。
3).天气信息请求过程:
扩展根据返回的归属地编号向 ww.weather.com.cn 发送请求,获取天气信息,如下图所示第5条。
4).天气信息解析和显示过程:
服务器将天气信息以JSON格式返回给扩展,扩展收到信息后解析JSON数据,分别获取到城市名称、当前温度、当天温度、风力、湿度、日期、未来7日信息、天气描述信息等。
c.更新测试大纲:
根据以上的总结,我们将测试大纲中实时天气的显示进一步拆分为发送归属地查询请求、归属地结果解析、发送天气信息请求、天气信息解析和显示几个部分,将原有已拆分的实时气温、湿度、温差显示等划分在天气信息解析和显示下,如图:
发送归属地查询请求又可以细分为:请求的URL、请求中的参数 (例如是否有H机器码参数、V版本号参数等)。根据这样的思路,我们细分为:
Note:对比一下,经过这样的拆分有什么好处?
i.我们会考虑一些容易疏漏的测试点。
比如,我们要测试每次打开扩展至少都会发送重新获取归属地的请求,我们要测试请求的服务器地址是正确的,我们要测试请求中的参数是正确的(
对于pingback测试,尤其要关注hrv和自定义字段的发送是正确的)。
ii.我们会自然而然考虑上一个过程对下一个过程的影响。
例如:天气信息返回的内容为空对显示的影响;天气信息返回超时对显示和扩展的影响;
ii.我们会考虑一些比较深的测试点。
例如:返回的天气信息不是JSON格式对显示的影响;返回的数据中包含
JSON的敏感字符,对显示的影响等。

6. 实现层面测试点发散
a.发散方法:
发散方法可以从上一个过程对下一个过程的影响、深层次的实现对外围功能的影响进行发散考虑。在这个事例中,实现层面我们看到了两个新的测试对象,HTTP请求的发送与接收,JSON数据的解析与显示。我们可以借鉴之前的测试公共用例库进行发散补充,比如HTTP常见的返回码(502\404\403\401等)、HTTP常见的网络异常(返回超时、返回内容为空、返回内容不正确等)。再比如JSON数据常见的测试点(返回的内容不是JSON格式、返回的字段中包含JSON特殊字符、返回的JSON数据为空等)
Note:实现层面的发散方法与黑盒层面是类似的,需要使用常见的用例设计方法等价类、边界值等,或者通过已总结的测试公共用例库、或者通过积累大量的测试经验。

7. 撰写具体测试点的测试用例
a.撰写测试用例的过程:
经过以上的步骤,对测试大纲抽象、概括、整理和发散,一个待测试功能的思路已经基本成型,测试设计工作基本已经完成了2/3,后续所要做的事只是针对每一个测试点去详细写一条用例的内容,如前提条件、操作步骤、预期结果等。
Note:推荐仍然在mind manager中写测试用例,在每一个条目下按下ctrl+t,在右侧的文字输入栏粘贴用例模板,然后写每一个字段内容即可。用例全部写完之后,用mind manager的导出功能,将测试用例导出为一份word文档即可。

点赞
收藏
回复
1
分享
举报
浏览2673 发布于2015-11-03 08:16未知归属地
全部评论
最多点赞
最新发布
最早发布
原来是这样的啊
1楼回复于2015-11-03 08:57 未知归属地
写回答
新增插入模板功能
一键使用模板,快速填写内容,轻松发帖~
知道了
  • 为了保障您的信息安全,请勿上传您的敏感个人信息(如您的密码等信息)和您的敏感资产信息(如关键源代码、签名私钥、调试安装包、业务日志等信息),且您需自行承担由此产生的信息泄露等安全风险。
  • 如您发布的内容为转载内容,请注明内容来源。

我要发帖子

了解社区公约,与您携手共创和谐专业的开发者社区。