购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

第6章

软件功能性测试用户故事

软件功能性测试存在一个比较全面的用户故事表。对用户故事,我们看重六个方面:谁是执行者、行为、情况/状态、方式、目标/价值、验证/检查点。

6.1 软件功能性测试故事表

小白 适合性和准确性,从软件功能测试的角度来说,应该是一个目的。对吧?

大鸟 从功能性角度来说,这是最基础的目的。

小白 目的只是用户故事的一部分,对吧?有没有比较全面的用户故事表呢?

大鸟 为了让读者能对功能测试有一个比较清晰的认识,我们做了一个比较全面的软件功能测试的用户故事表。这里基于如下的用户故事:

As an Actor(作为一个 执行者 ),I would like to do this Action(我实施了这样的 行为 / 诱因 )on this Object that is in this State(在这样的 情况 / 状态 下),using this Method(使用如下 方式 )so that achieve some business value or statement of intent(以便能够完成特定的 目标 / 价值 )And made the following verification(做了如下的 验证 / 检查 ).

对这个故事呢,我们看重六个方面:谁是执行者、行为、情况/状态、方式、目标/价值、验证/检查点。

小白 上次我们讲用户故事的时候,只有三个方面。 做了什么样的 行为 ,实现了什么样的 目标/价值 。为什么在这里要另加三个方面?

大鸟 上次讲用户故事主要是从需求的角度来讲,然而从测试的角度来看,必须要加上如下三点:情况、方式、检查点。详见下面这个列表。

(续表)

6.2 执行者/行为/状态/预期结果/检查点

小白 对于执行者,系统管理员和客户、负责人和部门成员都代表了不同权限,这个我能理解。但是我对生产者和消费者不是看得很懂。这个是指什么呢?

大鸟 我给你举个例子吧,超市和自助餐改变了原来的商店销售和餐厅服务模式,消费者部分的自助服务,换来了更多元、更自如舒适的选择。

种植者原本需要辛苦摘下苹果,运到城市,卖个(每斤)四五块钱的价格,但是采摘活动却让消费者“辛苦”参与劳动,而且使种植者以两倍或者更高的价格销售苹果。像采摘(体验自然和劳动)、陶艺(体验手工并享受艺术创造)、钓鱼(感受安宁并享受休闲)这类活动,都是给消费者提供了独特的体验,收益在生产过程中发生,收获的是愉悦和满足。

在互联网企业,也有类似的情况。比如整个网站都建立在用户贡献内容这个基础上,所以部分消费者转变为生产者,或者绝大多数消费者都参与了生产,对Blog来说是这样,对微博和Facebook也是这样。在互联网时代,生产、消费是交织发生的。

对于生产者和消费者来说,他们各自的权限和执行方式也不一样(但也可能互相转化)。所以,我们在这里做此分类。

小白 对于接下来的行为/状态/检查点。我知道检查点是对结果的检查,行为和结果也比较容易理解,因果关系嘛。但是State(状态)是指什么呢?按我的理解,用户实施了这样的行为,然后就得到了这样的目标/价值。这就足够了啊,为什么还要有一个额外的“状态”或者说条件呢?

大鸟 你说得没错,行为和结果的确是一个因果关系,但是有因不见得有果,中间还有个“缘”字。比如说人接触了甲H1N1型病毒,就一定会高烧,会呕吐腹泻,会肌肉酸痛,然后会死人吗?答案是,不一定。为什么不一定?如果你的身体不给它提供那种发病条件的话,就算是你感染了,也会相安无事。

病毒发病含有两个条件:第一,有一个诱因;第二,有一个生长条件。这个病毒或者细菌呀,它是个因。那么,有了它就会造成我们出现的这些病理症状吗?这个因进到我们身体里了,但是呢,我们没有病毒赖以生存的那种生长条件,病毒就呆不住,就不会发病,对吧。

小白 唔……作为一个皇马的球迷,通过点击皇马官网的最新新闻栏,以便能够实时了解最新的皇马动态。点击这个动作是因,了解皇马动态是结果。这就是直接的因果关系啊。

大鸟 嘿嘿,还是不一定。虽然你是皇马球迷,但是①你权限不够,点击不了;②出于某种原因,皇马官网的最新新闻栏被锁定了,相关的Button变灰,点了没反应。所以说,从功能测试的角度来看,你不一定能获得你期望的结果,甚至得到了别的结果。

小白 所以你说的State实际上就是个“缘”?

大鸟 State的说法可以有很多了,比如缘、内因、条件等等,是吧。Action是因。

小白 Action和State到底有啥区别?

大鸟 原因和结果在时间上是一个先后关系,而状态/条件/情况是已经存在的客观事实。

小白 预期结果和检查点是指什么呢?

大鸟 软件缺陷是经过对比而得出来的。软件测试必须有预期结果,没有预期结果的测试是不可理喻的。这正如没有标准无法进行度量一样,如果我们事先不知道或是无法肯定预期的结果,我们必然无法了解测试的正确性。,不少测试人员常常凭借自身的感觉去评判软件缺陷的发生,其结果往往是把似是而非的东西作为正确的结果来判断,因此常常出现误测的现象。

6.2.1 添加数据

小白 好的,我们现在把用户的行为一条条来过一下。首先是添加数据。

大鸟 让我们假设往一个文本输入框里来添加数据,包括如下一些情况。

(1)空数据。

(2)合法数据。

(3)添加中断机制。

(4)添加文件/图片。

(5)特殊字符字段。

(6)带空格字段。

(7)带回车键字段。

(8)字段长度。

(9)数字型边界。

(10)数字的约束。

(11)字段类型。

(12)重复添加。

(13)单选按钮。

(14)复选框。

(15)列表框。

(16)上下控件文本框。

(17)日期约束。

$1.2.1.1 空数据

小白 空数据的情况是指用户没有输入任何内容是吧?

大鸟 是的。用户有可能没有任何输入,即输入数据是一个空数据。

小白 那这种情况到底是合理呢还是不合理呢?

大鸟 这个要看具体情况。比如手机中的电话号码簿:只输入用户姓名,没有输入号码。这种情况是合理的。为什么呢?我们允许用户不用一次输入完全部信息,下次可继续输入。

再比如另一种情况:某个网站,注册新用户,用户名是必须输入的,否则没法做验证。

对于这种必需输入的数据条目,在数据框前应该清楚地指出这是必须输入的数据条目字段。

对于强制输入的字段,在屏幕上最好有些标识以说明其为必须输入的字段。一般在字段前或后用红色的“*”号表示。测试时必须要检查有标识的字段是否和功能说明书或其他参考文档所要求的一致,错误信息提示是否正确,强制输入的字段是否真的必须输入。

6.2.1.2 合法数据

小白 合法数据是指什么?

大鸟 就是指所有输入字段为合法数据。另外,点击“保存”按钮时,要注意如下一些检查点:

(1)系统应该有保存成功提示信息。

(2)在数据库中有新保存的数据。

(3)通过查询页面,也可以查询到添加的数据。

(4)有时程序会把合法数据当作非法数据处理。比如添加 IP 时,认为223.255.255.255不合理,其实这种IP是合理的,只是系统没有考虑到子网掩码是255.0.0.0的可能性。

6.2.1.3 添加中断机制

小白 添加中断机制是指什么啊?

大鸟 有两种情况要考虑。一种情况是还没添加呢,就想退出了。这种情况应该允许用户直接退出。还有一种情况是,添加了一半,突然不想继续了,反悔了,已经添加的不想要了。

小白 还能这么搞?

大鸟 当然可以,事是死的,人是活的;不是人照着事做,是事跟着人变。假如做一件事情,就必须至死不变地照做,那么世界上就没有解约、反悔、道歉、离婚等许多事了。

小白 这种情况要怎么处理?

大鸟 还是给出合理的提示吧。比如一封邮件写好了,然后取消掉。至少要问一下用户是否保留邮件内容,或者取消中断的操作。

6.2.1.4 添加文件/图片

小白 添加文件/图片的检查点是什么?

大鸟 上传、下载文件的功能是否能实现;上传的文件能否打开;对上传的文件格式是否有规定;变化选择格式后,显示的内容是否也一并变化;系统验证是否正常;系统是否能正常读取上传和下载的文件。

此外,对于图片预览的功能,对于没有上传的图片,在查看编辑页面时,是否显示默认图片;如果上传了图片,是否显示上传的图片(因为实际工作中很多客户很介意图片显示为红叉)。

6.2.1.5 特殊字符字段

小白 特殊字符字段是指什么呢?

大鸟 举个例子来说:单引号。大多数基于SQL的数据库系统在用户存储包含单引号的信息(例如John's car)时会出现问题。对于每一个可以接受文字、数字型数据条目的屏幕,都要试试输入包含一个或多个单引号的文本。

其实不只是单引号,基本上测试人员应该测试所有的特殊字符:单引号、逗号、/、<、>。因为这些特殊字符对于 Web 应用程序来说,都是很容易引发错误的。下面是一个特殊字符测试列表:

● 输入半角/全角,大写/小写英文字符

● 输入半角/全角数字

● 输入简体中文字符(默认全角)

● 输入繁体中文字符(默认全角)

● 输入全角特殊字符:!@#¥%……&*()

● 输入半角特殊字符:!@#$%^&*()

● 输入html字符:&nbsp(空格的转义字符);<script></script>;<br>;<tr>;<td>;</tr>;</td>;</html>;</body>;</table>

● 输入JavaScript函数:<b>Hello</b>,alert(″hello″)

● 输入日文字符

6.2.1.6 带空格字段

小白 带空格字段是指什么样的情况呢,是指中间有空格吗? 大鸟 不只是中间,应该包括以下几种情况:

(1)中间空格如“aaa aa”,看看保存时是否会过滤掉或过滤成一个空格。

(2)输入正常内容的前、后、中间加入多个空格,如“aaaaa”或“aaaaa”,看看保存时是否会过滤掉或过滤成一个空格,以及是否算入长度来计算空格。

后者这种情况,如果你单独测试一个平台时没有什么问题,但一旦涉及不同系统间的互操作性可能就有问题了。

案例 用户在Linux下安装某个软件并创建文件夹名时多输了一个空格作结尾,结果映射到Windows下生成的文件夹就不可移动/删除,文件不能运行,而且不能在相同目录中建立同名不带空格的文件夹。

这种以空格为结尾的文件名、文件夹名会给普通用户带来很多麻烦,没有任何好处。所以,这里要考虑是否允许用户创建以空格结尾的文件名、文件夹名的情况。

(3)输入半角/全角空格的情况。

(4)只输入空格是否正确,能否正确保存,如不能保存是否有提示。

6.2.1.7 带回车键字段

小白 带回车键字段是指什么样的情况呢?

大鸟 回车键包括如下几种方式。

● 是否允许输入换行回车。

● 保存后显示能否显示输入时的样式。

● 只输入换行是否正确并能否正确保存。

● 若不能查看是否有提示。

6.2.1.8 字段长度

小白 字段长度是指最长能输入多少字符的情况吗?

大鸟 最长最短都要测。应该包括以下几种情况:

(1)测试可以输入的最短字符:假设最短限制为N个字符。测试输入1个字符、N-1个字符、N个字符、N+1个字符等情况。

(2)测试可以输入的最长字符:假设长度限制为N个字符。测试N-1个字符、N个字符、N+1个字符、N+N+...(超长)这几个边界值。

功能说明书上应该清楚地指出可以在字段中输入的字符数(例如,first name必须是50个或更少的字符)。一般对于限制长度的字段,现在开发时大多采用限制输入的方法(设置字段的长度)来处理。所以测试时需要测试限制的长度是否合理(和功能说明书或其他参考文档相一致),对于没有限制长度的字段,要测试无穷输入时是否出错。如下图所示。

可以通过写测试用例来保证用户只可以输入特定的字符数,防止用户输入比允许范围更多的字符。因用户已输入过多的字符而给出的错误信息要清晰准确,如下图所示。

(3)复制大于长度的值粘贴进去看看是否能输入。

6.2.1.9 数字型边界

小白 数字型边界测试主要指什么呢?

大鸟 对于数字型的字段,测试上下边界是非常重要的。例如,如果你正在计算某个账户的利息时,你永远不会输入一个负的利息数给应该赢取利息的账户。因此,你应该尝试用负数测试。同样,如果功能说明书上要求字段在某一个特定的范围(如从10~50),你就应该尝试输入9或51,它应该给出一个得体的信息表示失败。

在边界值测试同时,最好结合等价类以及一些特殊数字进行开展,如这个例子里面的负数,虽然账户利息永远不会出现负数,但是如果系统中一旦输入负数,系统就崩溃,那么这样的系统对于客户来说也是非常危险的。

6.2.1.10 数字的约束

小白 数字的约束测试是指什么呢?

大鸟 大多数数据库系统和编程语言允许数字条目被识别为整数或长整数。通常,整数的范围是从-32,767~32,767,长整数的范围从-2,147,483,648~2,147,483,647。对于那些没有特定边界限制的数字数据条目,用这些限制测试以确保不会出现数字的溢出错误。

小数型的数字字段同样也需要额外的测试。一般对于未指出数字类型的字段,尝试输入负整数、负小数、0、正整数、正小数进行测试。

6.2.1.11 字段类型

小白 字段类型主要是指什么呢?

大鸟 某些字段类型测试是有特定数据输入要求的。如数字字段,有电话号码、邮编等。测试屏幕上每一个被指出有特定类型的字段,是为了保证你输入基于字段类型的、符合正确格式的数据(数字型字段应该不允许字符或特殊字符,日期型字段应该允许输入一个正确的日期等)。

其实这里还有一个字段格式和字段内容的测试。有些字段对输入的格式有要求,这些字段的格式一般在屏幕上也有相应的提示。所以在测试时需要测试提示的格式是否合理(和功能说明书或其他参考文档相一致)以及系统是否正确识别输入的格式。有些字段对字段的内容有限制,如常见的用户名,不能包含特殊字符,首字不能为数字等要求。所以在测试时需要测试提示的格式是否合理(和功能说明书或其他参考文档相一致),还需要测试在输入不符合内容要求的数据时系统是否正确地处理。下面分别举三个例子来详细介绍。

例1 邮箱输入框字段校验测试

● 输入合理的英文及数字字符组成的正确格式

● 格式正确的前提下输入第一部分中的异常字段校验

● 输入无@的格式,如:ab.com

● 输入@前无内容的格式,如@b.com

● 输入@后无内容的格式,如a@

● 输入@前后均没有内容的格式,如@

● 输入没有域名的格式,如a@b.,a@b

● 输入E-mail中有多个@的格式,如a@@b.com,a@b@c.d

● 输入@后面直接跟域名的格式,如a@.com

● 输入@后面有多个分隔符的格式,如a@b.c.d,a@b.c.d.e

● 输入@前面有分隔符的情况,如a.b@c.d,a.b.c@d.e,a.b@c,a.b.c@d

例2 验证码输入框字段校验测试

● 不输入,空内容

● 空格输入

● 输入空格+正确验证码,空格出现在开头、中间、结尾均需要测试

● 输入4位其他非数字内容

● 输入第一部分中的异常字段校验

● 输入前3位或后3位验证码正确数字

● 输入4位正确验证码+其他数字

例3 邮编输入框字段校验测试(假设限制6个字符,只能输入数字)

● 不输入,空内容

● 空格输入

● 输入空格+数字,空格出现在开头、中间、结尾均需要测试

● 输入其他非数字内容

● 输入第一部分中的异常字段校验

● 输入1个数字

● 输入6位数字

● 输入超过7位数字

● 输入超长全数字测试

6.2.1.12 重复添加

小白 添加重复数据会是怎样的情况?

大鸟 如果需求规定输入字段不能输入重复数据,那么验证程序对重复数据应该控制。如果输入内容不允许同名,还要检查是否区分大小写的情况。在输入的内容的前后添加空格,看看系统是否对此做出正确的处理。如果输入重复数据,程序不能崩溃,程序对重复数据的错误提示信息清晰准确。

小白 以上我们说的几种情况都是文本框形式,还有没有别的方式?

大鸟 有,其实添加数据我们还有别的形式,比如说单选按钮、复选框、列表框、上下控件文本框以及日期约束等等形式。

6.2.1.13 单选按钮

小白 单选按钮是指什么?

大鸟 单选按钮(Radio Button)是必须选且只允许选中一个按钮;一组单选按钮在执行同一功能时,初始状态必须有默认值,不能为空。比如选择男、女单选按钮,在页面初始时,必须有一个被默认选中。

6.2.1.14 复选框

小白 复选框控件是指什么?

大鸟 复选框(Check Box)可以同时选中多个选项。验证点如下。

(1)查看是否允许选中所有框体。

(2)部分选中若干个框体。

(3)一个都不选的情况。

(4)选中全选框时应该选中当前页所有选项,而去掉当前页某个选项的勾选时,则全选框也取消选中。翻页后,自动去掉已勾选的选项及全选框。

(5)在以上几种情况下,查看控件状态,执行选中复选框的功能;如至少有一个必须选中,检查程序是否存在友好提示。

6.2.1.15 列表框

小白 列表框控件主要验证什么?

大鸟 列表框控件(List Box)主要验证如下几方面。

(1)列表框条目内容是否正确。

(2)列表条目比较多时要使用滚动条。

(3)挑出部分条目选择,验证功能实现是否正确。

(4)列表框如果允许多选时,利用Ctrl键和Shift键查看鼠标多选条目的情况。

(5)键盘帮助选择的情况,如上图左边所示,如果用户键入 Are,就可以立刻跑到Are开头的条目那里。

6.2.1.16 上下控件文本框的测试

小白 上下控件文本框的测试主要测什么?

大鸟 上下控件文本框(up-down)主要验证如下几方面。

(1)上下箭头的可控性:直接输入数字或用上下箭头控制。如在“数目”中直接输入10,单击向上的箭头,使数目变为11。

(2)边界检测:对于使用上下箭头控制数字的情况,如控件中的数字为最大的限定数字32767时,单击向上箭头,数目应该不变化,反之亦适用;直接输入超边界值,系统应该不允许输入或者提示重新输入。

(3)输入默认值、空白内容。比如“插入”的数目为默认值,点击“确定”按钮进行测试;删除默认值,使内容为空,然后点击“确定”按钮进行测试。

(4)输入字符。此时,系统应提示输入有误。

6.2.1.17 日期约束

小白 日期约束是什么情况?

大鸟 日期约束测试包括5方面。

(1)日期校验

对于日期型的字段,测试上下边界是很重要的。日输入的最小天数-1;根据不同的月份输入最大天数+1。

此外,如果你正在检查一个出生日期的字段,出生日期很大可能不会早于150年前。同样,出生日期应该不是将来的某一天。一般来说,每种数据库系统的日期都有个范围,如SQL Server最小日期是1753年1月1日,所以如果是输入型的日期字段,同样也应该测试早于1753的日期。

(2)月份校验

月输入的最小月份-1天以及最大月份+1天,看看程序是否进行日历验证,是否存在友好提示窗体。

(3)年份校验

查看设计文档,非闰年,月输入 2、日输入 29;闰年,月份输入 2、日输入30。看看程序是否进行日历验证,是否存在友好提示窗体。

(4)日期格式检查

查看设计文档,检查日期格式的合法性,例如 2010-05-28、2010/5/28、20100528、2010.05.28。

(5)时间格式验证:包括时间校验和格式检查。

时间校验:查看设计文档,输入24时;输入60分;输入60秒,看看程序是否进行时间验证,是否存在友好提示窗体。

格式检查:不合法格式如“12:30:”、“1:3:0”等。

6.2.2 显示数据

小白 显示数据主要检查哪些内容?

大鸟 主要包括如下几个方面。

(1)分页显示。

(2)显示数据的一致性。

(3)显示信息归类的合理性。

(4)滚动条。

(5)陈旧数据的及时更新。

(6)对数据进行排序。

(7)避免遮蔽。

6.2.2.1 分页显示

小白 分页显示是指什么呢?

大鸟 当用户查看数据时,如果数据比较多,就需要分页显示数据。

小白 分页显示数据主要验证哪些方面?

大鸟 分页显示数据的检查点如下。

(1)首页、上一页、下一页、尾页四个按钮:在存在数据时,控件的显示情况;在无数据时,控件的显示情况(无数据时,上述四个按钮应该隐藏,如果存在数据,且数据能够在一页内显示完全,上述四个按钮亦应该隐藏)。

(2)在首页时,首页和上一页是否可单击;在尾页时,下一页和尾页是否可以单击(默认应该为灰,不允许单击)。

(3)在非首页和非尾页时,按钮功能是否正确。

(4)翻页后,列表中的记录是否按照指定的顺序进行排序(曾经遇见这样的情况,翻页前按照用户名称排序,翻页后居然按照用户ID排序了,因为翻页过程中进行了初始化处理)。

(5)总页数是否等于总的记录数/每页指定显示的条数。

(6)当前页数显示是否正确。

(7)指定跳转页跳转是否成功。

(8)输入非法页数时,是否给出提示信息。

(9)是否存在默认每页显示条数。

(10)是否允许用户自定义显示条数,设定后,显示的条数和页数是否正确。

6.2.2.2 显示数据的一致性

小白 显示数据的一致性是指什么?难道数据会不一致吗?

大鸟 会的,有两种情况。

由于数据源不一样,显示的数据就不一样。看下面这个图:数据Summary里有一个Free Memory的数据,NodeList也有一个Free Memory的数据。但是它们来自不同的数据源,所以数据不一致。这是个Bug,要统一数据源。

还有一种情况是,前台数据和后台数据同步时间不一致,从而导致显示数据不一致。如上图所示,两个Free Memory的值各不相同,必然会给用户造成困扰。后台的数据实时来自于数据库,所以是比较真实的。前台的数据却不是实时刷新的。比如三分钟刷新一次的话,前台数据就是后台数据三分钟前的数据。

小白 那就应该实时刷新了呗?

大鸟 这个东西还是要看需求。比如你要看火箭的曲线和数据,这样的情况显然需要实施响应。而有些就是看看节点的内存大小,不需要那么实时,但一定要保证数据源的一致性。

6.2.2.3 显示信息归类的合理性

小白 显示信息归类的合理性是指什么呢?

大鸟 你看菜市场卖水果的,苹果和苹果放一起,梨和梨放一堆。他不会胡乱放,他有分类。所以显示信息也应该是这样,CPU的信息放在一起,内存的信息放在一起,Job(作业)的信息放在一起。这叫显示信息归类的合理性。

6.2.2.4 滚动条

小白 如何检查滚动条控件呢?

大鸟 当数据比较多的情况下,就会出现滚动条来控制显示。滚动条控件的测试,要注意以下几点。

(1)滚动条的长度根据显示信息的长度或宽度及时变换,这样有利于用户了解显示信息的位置和百分比,如在Word中浏览100页文档,浏览到50页时,滚动条位置应处于中间的位置。

(2)拖动滚动条,检查屏幕刷新情况,并查看是否有乱码。

(3)单击滚动条,检查是否工作。

(4)用滚轮控制滚动条,检查是否工作。

(5)单击/常按滚动条的上下按钮,应该可以正常工作。

(6)避免使用水平滚动条,因为它会使项目阅读起来比较困难。解决的办法有:尽量使用垂直滚动条、加宽窗口、减小文本的宽度,或者使文本自动换行等。当然,如果确实需要,也可以使用水平滚动条。

(7)在字段间的 Tab 顺序应该是水平移动的。在一些案例中,Tab 的顺序可以被设置为垂直移动。

6.2.2.5 陈旧数据的及时更新

小白 陈旧数据的及时更新主要检查哪些内容?

大鸟 比如年份变化了,今年是2014年而不是2013年了,但是软件版权日期的数据源还显示2013年。再比如说,某些电话、邮箱发生了变化。QA要注意某些数据的变化,避免DEV一股脑儿地拷贝原来数据的情况。

6.2.2.6 分类排序

小白 分类排序是指什么?

大鸟 用过淘宝之类的吧,你想买个商品,比如说买个LV包,一下子搜到很多,你想要按照价钱、产地、口碑、信誉进行一下排序。像这种排序一般有个默认值,有的从高到低,有的从低到高,具体要看需求。此外还要注意一点,如果是英文,那么是否要忽略大小写呢?

6.2.2.7 避免遮蔽

小白 避免遮蔽是指什么?

大鸟 在显示多个数据的情况下,要避免自己的数据被别的东西挡住从而显示不全的情况发生。

6.2.3 删除数据

小白 删除数据主要检查哪些内容?

大鸟 主要包括如下几个方面。

(1)删除合法数据。

(2)不允许删除的数据。

(3)删除不存在的数据。

(4)删除数据的衍生影响。

6.2.3.1 删除合法数据

小白 删除合法数据是怎样的情况呢?

大鸟 删除的合理操作应该验证以下三种情况。

(1)删除一条数据记录。

(2)删除多条数据记录。

(3)删除全部数据记录。

检查点是:

(1)数据删了之后,可能就恢复不了了。所以删除时,要让用户认识到删除严重性,并予以确认。

(2)删除后,在数据库中是否也删除了。

(3)删除后查询数据,数据库应该查不到。

(4)删除后,是否可以添加同样的数据记录。

(5)删除成功后要有提示信息。

6.2.3.2 不允许删除的数据

小白 不允许删除数据的操作应该是怎样的情况?

大鸟 比如说,有些节点正在使用,所以不允许删除。或者有些是默认设计不允许删除的,如管理节点。在这种情况下,要么删除时报错,要么使删除按钮变灰不让用户操作。

小白 有一种情况,就是要删除多个数据,但其中有的允许删除,有的不允许删除。那么在这种情况下,删除按钮是该变灰还是不变灰呢?

大鸟 不变灰,而是提示用户某些数据可以删除,某些不能删除;接着,让用户确认;如果用户确认了,则删除可以删除掉的,不能删除的则保留。

6.2.3.3 删除不存在的数据

小白 删除不存在的数据是怎样的情况呢?既然不存在,我咋删除呢?

大鸟 是有这样的情况,比如同时打开两个Web窗口,某些数据在窗口1已经删除掉了,但是在窗口2还有显示,在这种情况下,再删一次,看看会有什么样的情况发生,看看是否有合理的错误提示。

6.2.3.4 删除数据的衍生影响

小白 删除数据的衍生影响是指什么呢?

大鸟 测试删除数据的时候,不是删除一个数据那么简单。数据与数据之间有其特定的关联性。从数据层方面来说,查看在明细文件(子表)内是否有相关的细项记录,如果有则不允许删除父表的记录。

小白 对,正所谓“皮之不存,毛将焉附”。

大鸟 是的,还有就是逻辑层方面的问题。即便是在数据库层面都是各自独立的数据表,但是如果彼此之间存在逻辑依赖,那么还是要考虑是否删除相关的数据或者删除后的影响。

案例 作者曾经做过一个节点管理软件的测试,其中有些节点是有标签的,比如说节点Compute001标签名为Dell1950,Compute002标签名为ETT3650,这些是硬件标签。

如果你在标签管理中,把 Dell1950 这个标签给删除了,那么节点上所对应的标签名是否也要删除呢?这个就涉及到实现的问题。从逻辑上来说它们是有关系的。此外,还有组合标签的情况。比如说一个标签是“Dell1950 And Windows 2013”,如果删除了标签Dell1950,那么组合标签“Dell1950 And Windows 2013”是否也要删除呢?

6.2.4 查询数据

小白 查询数据主要测什么,怎么测?

大鸟 查询数据的用户场景是这样的:有个查询条件,然后有个查询关键字,点击查询按钮,得到查询结果。

6.2.4.1 查询条件输入

小白 查询条件输入是指什么?

大鸟 查询按条件来看,包括两种情况:单条查询、组合查询。单条查询是指仅一条查询语句,返回一个查询结果集;组合查询是指多条查询语句,返回一个查询结果集。

查询条件输入有哪些检查点呢?

检查点有如下几条:

(1)查询条件输入方式和需求描述不一致,比如,需求为下拉列表,程序为文本框。

(2)对于组合查询,要保证逻辑的正确。输入多个搜索条件,可以同时添加合理和不合理的条件,查看系统是否正确。比如说这种情况就是错误的:查找CPU Usage>20%而且CPU Usage<10%的情况。对于逻辑错误的提示要清晰合理。

(3)开始时间和结束时间:选择起始时间后,联动显示出结束时间选择,选择结束时间小于起始时间的日期。

(4)对于开始时间和结束时间,如果用户不选,则要给一个合理的默认开始时间和结束时间。比如结束时间默认为当前时间,起始时间默认为当前时间前两小时。

6.2.4.2 查询关键字

小白 查询关键字是输入值吧。

大鸟 是啊,因为关键字的值是你自己输入,所以对输入框的限定要进行测试。另外,对于特殊字符、带空格字段、超长字符、数字型边界、数字的约束等情况都要考虑,读者可以参照“添加数据”一节,这里不再赘述。

6.2.4.3 模糊查询与精确查询

小白 精确查询和模糊查询有什么区别?

大鸟 精确查询就是直接查。例如:

这么查就是查出字段名必须等于“长虹”的字段。那么长虹空调、长虹电视就查不出来。

模糊查询就是换成like:

这么查就是查出字段名中带有“长虹”的字段,%表示任意长度的字符串。那么长虹电视、长虹空调、美丽的长虹都可以查出来。

小白 默认的应该是精确查询还是模糊查询呢?

大鸟 默认的一般都是模糊查询,除非用户指定为精确查询。

6.2.4.4 查询结果

小白 查询结果有哪些检查点?

大鸟 有如下几方面:

(1)通过查询功能查询到的数据记录个数,要与通过数据库查询的数据记录个数相符。有可能存在不符合的情况:有些记录丢失,有些多出来了。比如说我用长虹电视作为关键字(模糊查询),如果查出长虹空调、长虹洗衣机,那显然就多了。如果“长虹电视机顶盒”没查出来,显然这就是少了。

(2)如果根据查询条件确实查不到任何数据,应该给出清晰合理的结果。不能让用户费解。

(3)如果用户选择默认条件查询,应该可以查询出全部的数据记录。

(4)如果用户选择全空条件查询,应该可以查询出全部的数据记录。

6.2.5 修改数据

小白 修改数据主要检查哪些方面呢?

大鸟 修改数据主要检查如下几个方面:修改合理数据,不能修改/锁的情况,修改多个数据,以及修改后的衍生影响。

6.2.5.1 修改合理数据

小白 修改合理数据是指什么?

大鸟 对于修改数据,这里要注意如下几个检查点:

(1)点击“修改”按钮,程序跳转到修改页面,验证信息内容和修改时的输入一致。

(2)修改后查找数据库,里面有新保存的数据;同时,老数据查不到。

(3)通过查询页面,也可以查询到修改的数据;同时,老数据查不到。

(4)修改成功后,程序提示保存成功。

对于把数据修改为特殊字符、带空格字段、超长字符、数字型边界、数字约束等情况,读者可以参照“添加数据”一节,这里不再赘述。

6.2.5.2 不能修改的情况

小白 不能修改是怎样的情况呢?

大鸟 不能修改是指某些数据正在被使用,因此不能修改。这里面应该有一个锁机制,数据库就是通过锁机制来解决并发问题的。

小白 如何解决这种并发机制呢?

为了确保并发用户在存取同一数据库对象时的正确性(即无丢失修改、可重复读、不读“脏”数据),数据库中引入了锁机制。基本的锁类型有两种:排他锁(Exclusive lock,记为X锁)和共享锁(Share lock,记为S锁)。

排他锁与共享锁

排他锁:若事务T对数据D加X锁,则其他任何事务都不能再对D加任何类型的锁,直至T释放D上的X锁;一般要求在修改数据前要向该数据加排他锁,所以排他锁又称为写锁。

共享锁:若事务T对数据D加S锁,则其他事务只能对D加S锁,而不能加X锁,直至T释放D上的S锁;一般要求在读取数据前要向该数据加共享锁,所以共享锁又称为读锁。

在执行select语句的时候需要给操作对象(表或者一些记录)加上共享锁,但加锁之前需要检查是否有排他锁,如果没有,则可以加共享锁(一个对象上可以加n个共享锁),否则不行。共享锁通常在执行完 select 语句之后被释放,当然也有可能是在事务结束(包括正常结束和异常结束)的时候被释放,主要取决于数据库所设置的事务隔离级别。

执行insert、update、delete语句的时候需要给操作的对象加排他锁(笔者感觉在执行 insert 的时候应该是在表级加排他锁),在加排他锁之前必须确认该对象上没有其他任何锁,一旦加上排他锁之后,就不能再给这个对象加其他任何锁。排他锁的释放通常是在事务结束的时候[当然也有例外,就是在数据库事务隔离级别被设置成 Read Uncommitted(读未提交数据)的时候,这种情况下排他锁会在执行完更新操作之后就释放,而不是在事务结束的时候]。

数据库是支持在一个事务中进行自动锁升级的,例如,在某个事务中先执行 select语句,后执行update语句,这两条语句操作了同一个对象,并且假定共享锁是在事务结束的时候被释放的。如果数据库不支持自动锁升级,那么当update语句请求排他锁的时候将不能成功。因为之前select语句的共享锁没有被释放,那么事务就进入了无限等待,即死锁。有了自动锁升级,在执行update语句的时候就可以将之前加的共享锁升级为排他锁,但有个前提,就是这个共享锁必须是本事务自己加的,而且在操作对象上没有在加其他任何锁,否则共享锁是不能被升级为排他锁的,必须等待其他锁的释放。

还有一种叫更新锁。因为通常在执行更新操作的时候要先查询,也就是我们通常会在update语句和delete语句中加where子句。那么,有的数据库系统可能会在执行查询的时候先给操作对象加共享锁,然后在更新的时候加排他锁,但这么做会有问题,也就是如果两个事务同时要更新一个对象,都先给这个对象加了共享锁,当要更新的时候,都请求升级锁,但由于这个对象上存在对方事务加的共享锁,所以无法升级。这样两个事务就在等待对方释放共享锁,进入死锁状态。更新锁就是为了解决这个问题,即在执行查询操作的时候加的不是共享锁而是更新锁(一个对象上只能有一个更新锁和 n 个共享锁),当要更新的时候,再将更新锁升级为排他锁,升级前提是这个对象上只有本事务加的更新锁,没有其他任何锁了。

大鸟 如果QA进行测试的话,要怎么进行呢?

小白 首先要和DEV沟通,看看相关的锁机制是否建立好了。然后要按照上面的分类,构造测试环境。看看相关的锁机制是否工作。

6.2.5.3 修改多个数据

小白 修改多个数据是指什么?

大鸟 一般情况下不太可能修改多个数据。当然不排除有种情况,要看需求。比如说用户是给多个数据加标签,加前缀后缀的情况。检查时要保证所有数据都被修改,而不只是第一个/某几个数据被修改。

6.2.5.4 修改后的衍生影响

小白 修改后的衍生影响是指什么呢?

大鸟 牵一发而动全身啊,修改这种动作呢,不光对自己进行了改变,可能还对相关数据都进行了改变。

小白 套用黄健翔的话说“他不是一个人在战斗,他不是一个人”。 大鸟 对,所以修改有个边界界定的问题,包括以下两种情况:

(1)仅改自己,与别的数据无关的,不要改别的东西;如果自己的数据改后添加了,不影响以前的数据。

(2)改自己且与别的数据相关的数据,要把别的数据也改掉。

所以不要做少了也不要做多了。

案例1 笔者曾经做过一个节点管理软件的测试:节点管理有一个模板,这个模板下有10 个节点。当笔者修改这个模板下的某个脚本时,比如脚本改为“在根目录下建一个 test 目录”。这个改动实际上是要求对模板下所有节点都要建一个 test 目录,所以修改后应该提示用户要对节点进行同步操作。

案例2 情况如上。笔者还是修改了这个模板,现在的情况是笔者仅仅对管理模板的描述信息做了修改。这个修改不会对它下属的节点造成任何影响,但事实上软件还是提示用户要进行同步,显然这是一个Bug,它做了一些不该做的事情。

6.2.6 激活/冻结

小白 什么叫冻结啊?我记得郭德纲有一句话形容一个大侠:他的剑是冷的,他的刀是冷的,他的心是冷的,他的血也是冷的……这孙子冻上了,哈哈!

大鸟 嗯,有点儿意思。其实冻结的意思在软件中也差不多哦,我们在冻结一个特性、功能或数据后,也要检查相关的功能(删除、修改、拷贝等等)是否也被冻结了。保证该冻上的要被冻上,不该冻上的别被冻上。此外还要检查如下几点:

(1)冻结后不允许用户再使用的,要把它变灰。

(2)冻结成功后,要有合理的提示信息。

(3)能否同时冻结多个。

(4)重复冻结的情况。

(5)冻结已经被删除数据的情况。

(6)冻结的时候,要不要一些描述冻结的理由。

当然具体的行为,还是要看用户需求。

小白 明白了,那么激活呢?

大鸟 所谓激活数据就正好相反,即解冻或者是发布。读者可以参照冻结的检测点加以验证。

6.2.7 导入/导出数据

小白 导入/导出数据的检查点是什么?

大鸟 检查点包括如下几点。

(1)导入合理数据。

(2)导入数据中存在不合理数据。

(3)导出数据。

6.2.7.1 导入合理数据

小白 导入合理数据是指什么?

大鸟 导入数据也是一种添加数据,请参考“添加数据”一节。此外你还要考虑,导入的格式是否合理,如果不合适是否有提示等情况。

6.2.7.2 导入数据中存在不合理数据

小白 导入数据中存在不合理数据是指什么?

大鸟 这里存在如下几种情况。

(1)有的数据是存在的但不合理(格式、数值边界等不合理)。

(2)有些数据是合理的但不存在数据(空的路径、不存在的文件夹等)。

(3)数据内容不合理,如错误的网卡地址等等。

(4)导入的若干条正确记录中混有一条错误记录。

(5)对于不合理数据要及时给出提示。

6.2.7.3 导出数据

小白 导出数据是指什么?

大鸟 导出数据主要检查如下几点:

(1)导出的格式(如xml,doc,pdf)是否满足需求。

(2)能否被打开且不出现乱码;数字格式精度是否满足需求。笔者就遇见过这样的情况,在Web报表上展示的是小数点后三位,结果导出xls后就变成小数点后两位了。

(3)如果是大规模的导入导出,可能还要测试性能。不过这不属于功能测试,这里就不多说了。

6.2.8 实例化

小白 实例化是指什么?

大鸟 在面向对象的编程中,通常把用类创建对象的过程称为实例化。软件测试中我们通常把根据模板创建出对象的过程叫实例化。这里主要检查创建出来的对象是否能显示正常,实例化过程中是否可定制化,能否实例化多个对象等测试。

6.2.9 拷贝

小白 拷贝和添加数据比较像吧。应该都属于一种添加。

大鸟 对,本质上来说都是添加。下面我们说说区别,区别有以下两条:

(1)拷贝数据信息检查。

(2)默认拷贝数据名。

6.2.9.1 拷贝数据信息检查

小白 什么叫拷贝数据信息检查啊?

大鸟 拷贝数据之后,要进行信息检查。对于拷贝数据和被拷贝数据来说,某些信息是一致的,某些信息是不一致的。一致的比较好理解,下面说一下不一致的地方。举例来说,因为所有拷贝的数据都是用户自定义的,所以如果有 Build-in (内嵌)属性,那么对于拷贝数据的话,它一定是“否”。

所以做测试的时候,要把那些不一致的地方搞清楚,别把那些本来应该不一致的地方,最后也变成一致的了。

6.2.9.2 默认拷贝数据名

小白 拷贝数据,还要给个默认的名字吗?

大鸟 对于拷贝数据名,默认要给一个合理值。比如 rhel6.4 这个名字,可以给rhel6.4_copy1 这个名字。如果再对 rhel6.4 拷贝的话,可以累加,比如得到rhel6.4_copy2。像这样的设计才是合理的。

小白 如果我已经有 rhel6.4_copy1,rhel6.4_copy3,rhel6.4_copy4 了,那我再拷贝一个,默认名字应该是rhel6.4_copy2了吧。

大鸟 是的。

小白 如果拷贝rhel6.4_copy1呢?

大鸟 拷贝出来的名字应该是 rhel6.4_copy1_copy1。至于重复添加,拷贝不存在的数据情况,请读者参考“添加数据”一节进行分析。此外,对于拷贝出来的数据,加个时间戳也是合理的。

6.2.10 检查日志

小白 大鸟,我发现表中有一个检查点是检查日志,这是指什么呢?

大鸟 当程序出现错误的时候能准确地定位问题成了保证软件质量的关键,而如何才能准确定位问题呢?这就需要程序出错时尽可能地吐出更多的消息,最好的情况就是把问题定位到具体的文件和语句以及当时的堆栈信息,这样就可以帮助程序员快速地定位问题,这便是软件可测试性的最终目的。

我们平时会使用到一些测试手段,如在代码中使用 ASSERT,在屏幕或者控件里打印一些程序的执行过程,还有就是利用Debug去直接跟踪程序的语句等,但是以上这些简单的测试手段对于那些程序中隐藏比较深的Bug就显得有点束手无策了,特别是对一些服务器一级的程序,它们都需要长时间的运行,有时候出了错误并允许马上停下来,这就需要程序必须把错误信息保存下来待以后再去分析它。Windows系统内部就有很多的日志,这些日志不仅可以供开发人员定位问题,也可以帮助用户更好地使用系统。其实所有的程序对可测试性都有着一些相同的要求,于是我们可以把这些需求提取出来抽象成一个单独的系统(类),这样就可以为所有的程序都提供统一的测试接口了。

日志可以提供一种跟踪机制,这种机制提供的信息有:组件正在做什么,包括它们正在操作的数据,应用程序的状态或者应用程序遇到的错误。在执行测试过程期间,测试工程师可以利用这些信息来跟踪处理流程,以及利用这些信息来对系统发生的错误进行定位。

小白 怎么定义一个好的日志呢?

大鸟 比较好的日志一般满足如下条件:

(1)能保存成独立的文件,一些程序要执行很久,必须要把程序执行的信息保存下来,同时程序关闭后测试的信息不能随着程序一起消失掉,所以没有比把这些信息保存在磁盘更好的方法了。

(2)打印日志的方法必须是可重入的(若一个程序或子程序可以“安全地被并行执行”,则称其为可重入),现在很多软件是多线程的,为了让线程之间打印的信息不互相干扰,我们的打印方法必须支持多线程。

(3)对打印要求设定级别,级别的粒度因需要而定,一般都要包括错误信息、报警信息和一般信息三类,这样用户就可以根据需要,通过日志的配置文件来选择需要打印的信息,而不是一股脑地把所有的信息都打印出来,重点不突出反而不利于问题的定位。

(4)打印接口要设计得灵活,可以让用户自由地去打印任何信息。有些情况下,打印的同时也要把当时的堆栈信息打印出来,这些信息可能是字符串、整形或浮点型等。

(5)打印的内容要采用统一的格式,一个合理的日志条目应该包含如下信息:

[时间戳][等级][文件/函数/进程ID/主机名][信息内容] H7ryUSs9g8Qg8WObVx/1NdTYD2u3aQdMsSAM8cEBlBpd8EZx6O/lkSETUEsNZQnJ

点击中间区域
呼出菜单
上一章
目录
下一章
×

打开