软件测试中的用户输入Word下载.docx

上传人:b****5 文档编号:16870068 上传时间:2022-11-26 格式:DOCX 页数:8 大小:65.69KB
下载 相关 举报
软件测试中的用户输入Word下载.docx_第1页
第1页 / 共8页
软件测试中的用户输入Word下载.docx_第2页
第2页 / 共8页
软件测试中的用户输入Word下载.docx_第3页
第3页 / 共8页
软件测试中的用户输入Word下载.docx_第4页
第4页 / 共8页
软件测试中的用户输入Word下载.docx_第5页
第5页 / 共8页
点击查看更多>>
下载资源
资源描述

软件测试中的用户输入Word下载.docx

《软件测试中的用户输入Word下载.docx》由会员分享,可在线阅读,更多相关《软件测试中的用户输入Word下载.docx(8页珍藏版)》请在冰豆网上搜索。

软件测试中的用户输入Word下载.docx

比如,我们可以使用“某个长度”这样一个抽象输入来表示1~32768之间的任何一个原子输入长度值。

  因为输入可以接收的可能值实在太多,所以必须把它抽象化。

在测试中,正整数、负整数和任意长度的字符串这些概念都包含着可以无限使用的值,测试所有这些值是不可能的。

但是不穷尽所有的情况,我们就无法保证软件能够正确处理所有这些值。

  任何一个特定应用程序可以接受的原子输入的数量都是无穷的。

因为不可能去尝试所有的值,所以从输入的角度来看,测试就要求只选定某些输入值,然后在程序中使用它们,希望这些输入值可以引发程序所有的缺陷。

这样我们就可以认为软件质量已经足够好了,并且可以认为即使用户使用其他那些并没有被测试过的值时也不会有问题。

要做到这一点,测试人员必须下苦功学习如何在各种不同的输入中选择出最佳的一个。

我们会在本章和下几章中介绍相关策略。

  实际情况比这还要复杂。

如果我们只需要研究如何从一堆原子输入中找出一个最佳子集,软件测试就比现在我们实际面对的简单得多。

还有两个因素让输入选择问题比我们想象得更复杂。

  首先是各种输入之间会相互影响,从而造成软件失效。

事实上,即使软件在分别处理这两个或多个原子输入时没有问题,但如果把这些输入组合起来使用,软件还是有可能出问题。

比如,在机器上查找所有的CD文件,可能没问题,如果只查找所有的视频文件,也没有问题。

但是如果同时查找所有的CD和视频文件时,软件可能就报错。

测试人员必须能够识别哪些输入值和其他输入有关联,然后在同一个测试用例中使用它们,这样就可以保证这些情况都被覆盖了。

  然后,输入这些值时的先后顺序也会导致问题。

输入a和输入b可以产生如下组合:

ab、ba、aa、bb。

我们还可以重复三次或更多次,这就产生了更多的顺序(比如aaa、aab和aba等)。

如果有两个以上的输入值时,就会出现更多的顺序。

如果我们决定不测某些顺序,那些没有被测试的顺序就可能会导致软件失效。

比如,我们可以购买一本书,然后去结账,或者购买两本书再结账,还可以结账之后又买一本书再去结账。

有太多种可能要考虑,但是只能测其中的一小部分。

测试人员必须可以枚举出那些比较恰当的顺序,然后测试它们,这样才有把握相信软件可以满足实际用户的需求。

前面已经说过了,本章和接下来的几章都会讲述该主题。

如何测试用户输入

  想象一下这个场景,光标位于某个文本输入框中,它正一闪一闪地等待我们键入值。

每个测试人员每天都会多次面对此情形。

这时,测试人员会做些什么?

该使用什么样的策略来决定使用这个值而不用那个值?

需要考虑哪些因素?

我一直很吃惊那些测试新手不知道可以从哪里学习这些测试策略。

更让我吃惊的是,如果我向10个测试人员询问上述这些问题,我会得到12个不同的答案。

是时候把所有这些问题整理编辑起来了,这正是本书想做到的。

  首先,我们必须意识到我们正在测试的软件和其他软件并没有什么不同。

测试人员倾向于认为自己测试的软件比较特殊,和其他人的程序完全不一样。

事实上并非如此。

所有的软件,从操作系统、API函数、设备驱动程序、常驻内存的程序、嵌入式应用、系统代码库,到Web应用程序、桌面应用程序、基于Form的用户界面,甚至游戏软件,它们可能运行于完全不同的环境中,但是它们都会执行四个基本任务,即接收输入、产生输出、存储数据和进行运算。

各种输入的产生方式各不相同,把输入传入应用程序的方法也会五花八门。

相对某些应用程序而言,其中有些程序可能更注重时效性,但是所有的软件从基本面上来说都是相同的,我在本书中针对的就是这些相同的本质。

读者从本书中可以获得一些通用的知识,再把它们应用到各自测试的软件上去,也就是按照被测试应用程序的特定输入方式来输入数据,以及按照这些应用程序规定的方式和运行环境进行交互。

就我个人而言,我测试过美国政府的武器系统、实时安全监控软件、反病毒引擎、蜂窝交换机、高层操作系统、底层操作系统、Web应用、桌面应用程序、大型服务器软件、控制台程序、桌面游戏软件,还有很多因为时间久远我已经说不出其名称的软件。

但是我这里讲述的概念,对前述软件都适用。

我把这个技术的实际应用留给读者自己来尽情发挥。

  合法输入和非法输入

  首先让我们理解正向测试(postivetesting)和逆向测试(negativetesting)的概念。

你是想确认程序可以进行正常工作呢,还是在想办法让它失效?

要知道,这两者都需要进行深入测试,对某些应用领域内的程序,逆向测试尤其重要,所以我们必须找到一个可用于分析合法输入和分析不合法输入的策略。

  测试人员解决这个问题时首先想到的是依据开发人员的思路来构造一个非法输入值。

开发人员必须要精确地知道什么是合法输入,什么是非法输入。

对于他们认为的非法输入值,他们通常会实现一段错误处理(error-handling)代码,用于处理这些情况。

他们在哪些地方编写了错误处理代码,具体错误代码是如何实现的,这些都需要测试。

  测试人员应该牢记,大多数开发人员都不喜欢编写错误处理代码。

一般没有人认为大家热衷于计算机科学是出于喜欢编写那些出错信息。

因为用户使用软件的目的就是要求代码必须实现某些功能,所以开发人员更愿意编写功能代码。

通常,开发人员会忽视错误处理代码,或者编写时草草了事,因为开发人员就是希望可以尽快地编写“真正”的功能代码。

正因为开发人员的这种态度,它通常会导致应用程序的这些部分有很多问题,所以测试人员必须重视对这些地方的测试。

  假设开发人员编写了一段功能代码,用于接收一个输入值。

他们可能会立刻想到需要检查该输入值是否合法,可能会做如下几件事情。

他们可能会暂时停止编写功能代码,转而先实现错误处理代码。

他们也有可能先在程序里加一段注释(比如说,“本处需要添加错误处理代码”),然后决定以后再来处理它。

在前者的情况下,由于开发人员的思路被多次打断,首先需要从编写功能代码切换到编写错误处理代码,然后还要转换回去。

这会干扰开发人员的想法,增加代码出错的可能性。

在后者的情况下,则有可能会发生开发人员再也没有回头添加那些错误处理代码的情况,毕竟,开发人员都很忙,不是吗?

我曾经不止一次地在已发布的软件代码中发现那些“本处还需要实现……”的注释!

用户输入

(2)

  开发人员有三种基本方式来定义错误处理程序(errorhandler),它们分别是输入筛选器(inputfilter)、输入检查(inputcheck)和使用异常(exception)。

下面我们讲述如何从测试人员角度来看待这三种方式。

  输入筛选器

  输入筛选器用于防止非法的输入值被传递给应用软件的功能代码。

换句话说,编写输入筛选器的目的是把那些坏的输入值挡在应用程序之外,这样开发人员就不用担心那些非法输入值了。

如果一个输入值被传递给应用程序,这个输入值就被认为是一个好的输入值,可以被安全使用,所以也就没有必要进行进一步的检验。

当程序的性能比较关键时,开发人员通常会使用这个技术。

  输入筛选器不会产生错误信息(这是它和输入检查的区别所在,下一节会讨论输入检查),相反,输入屏蔽器默默地把非法的输入排除在外,只把合法的输入值传给应用程序。

比如,一个图形界面的应用程序有一个面板可以接收整数值,该面板可以忽略所有的字符或字母输入值,只显示键入的数值输入值(参见图3.1)。

图3.1 

该对话框来自PowerPoint,它只允许用户输入数值输入,这样就屏蔽了所有的非法字符

  还有,所谓的列表框和下拉列表框是一种输入筛选器,因为它们只提供那些合法的输入选项(参见图3.2)。

这里的好处显而易见,现在开发人员可以专心编写功能代码,不再需要对那些输入进行进一步的检查了,这省了很多麻烦。

图3.2 

让用户从一些预先定义好的合法输入值中进行选择也是屏蔽输入的一种方式

从测试的角度,对于输入筛选器,我们需要检查如下几个方面。

  第一,开发人员是否正确地实现了该功能?

如果开发人员从一开始对于非法输入和合法输入的区分就是错误的,可以预见导致的结果就是该部分会有很严重的缺陷。

比如,如果不小心把一个非法输入值归类于合法输入的范围,就会导致该非法值突破软件的唯一保护层(假设软件没有做进一步的检查)。

如果测试人员怀疑发生了这种情况,就应该上报该问题,以便及时修复此缺陷。

与此相对的,如果把一个合法输入值归于非法的范围,也是非常严重的问题。

这可能会导致软件拒绝服务(denialofservice)和严重的用户不满,因为他们试图输入的值是完全合法的但软件不接受他们的输入。

  第二,是否可以绕过屏蔽器?

如果有某种方法可以让输入值进入系统,或者当输入值进入系统后还可以被修改,那么该屏蔽器就没有什么用处,开发人员还必须实现更多的错误检查代码。

在发布之前找出此类的缺陷非常重要,因为它们往往会在软件安全性上导致严重的副作用。

图3.3显示了一个被修改过的数量值(它是通过编辑Web页面的HTML源代码来实现的),如果后面的代码不进一步检查该数值,就会导致用户的订单显示一个负数值,使用该软件进行交易的卖方就会遭受损失。

图3.3 

图中Quantity字段显示为负数,所以绕过输入约束会导致危险的结果

输入检查

  输入检查属于应用程序代码主线的一部分,通常通过类似IF(如果)、THEN(那么)、ELSE(否则)结构的语句来实现(或者是CASE、SELECT结构,或者是查找表(lookuptable)的方式,这和具体使用的编程语言相关)。

它们会接受一个输入值,如果输入值合法,那么接着运行处理它,否则就产生一条错误消息并中止处理。

实现了输入检查后会报警,通常就是显示一条错误信息,该信息会描述当前状况,并准确地表示当前的输入值出现了不合法的情况。

  这里,使用探索式测试法的测试人员必须牢牢抓住显示的错误信息,我的建议是必须仔细阅读每一条错误信息,检查该信息是否写错了,错误信息还可以透露出开发人员编程时的一些想法。

错误信息一般会指出当前输入值被认定为非法值的根本原因以及如何修改让它变成合法输入值。

这就可以给我们很多启发,比如还有哪些输入值可以触发其他一些错误信息,或者是哪些输入值实际上应该导致错误出现而软件却没有报错。

  输入检查和异常处理(下文会详述)的根本差别在于代码的位置,当程序从外部接收到输入值后,一般紧接着就是输入检查的代码。

读入输入值的代码之后会紧跟着一个IF语句,用于检查输入值是否合法。

所以显示出的错误信息会非常精确,例如,“不允许输入负数”就是一条精确的错误信息,它告诉用户当前输入值哪里出了问题。

如果错误信息比较笼统,往往表示这里使用的是异常处理的方式。

接下来让我们看看什么是异常处理。

  异常处理代码

  异常处理代码就像错误检测,但是它不是对每一个输入值进行检测,异常处理代码把整个例程(routine)当成一个整体看待,检测其上发生的任何一个错误。

错误处理代码会位于程序的结尾部分,或者位于一个单独的文件中,如果在软件运行的过程中出现任何被指定的错误,该段代码会进行处理。

这意味着如果违背了输入规则,异常处理代码会接手处理,但是如果软件发生了其他某些错误,比如发生了违规内存存取(memoryviolation)等情况,异常处理代码也会进行处理。

从本质上而言,异常处理代码可以处理各种各样的软件失效状况,不单单局限于非法输入。

  这也表明,由异常处理代码产生的错误信息相对于由特定的输入检查产生的错误信息来说,一般都更笼统、含糊。

因为该程序中任何一行代码都有可能引发一个异常,发生异常的原因也五花八门,所以异常处理代码无法知道到底哪里出了问题,问题的实质是什么。

除了报告说“发生了一个错误”,异常处理代码也没有更好的处理办法。

  如果测试人员看见这样一个空泛的通用出错信息,我的建议是接着反复测试同一段函数,继续使用刚才引发异常的输入数据,或者是稍微修改一下,看看会不会导致出错。

尝试运行其他一些要调用该函数的测试用例,看看会发生什么情况。

接连不断地引发异常很可能会让程序彻底失效。

  非法输入应该被忽略,或者应该触发出错信息(出错信息可以显示在一个弹出式对话框中,也可以被输出到错误日志文件,或者是显示在界面的某个特定保留区域)。

应该按照规格说明书所定义的来正常处理合法的输入,产生合理的结果。

如果你观察到的和前述情形有任何不同,表明你已找到了一个有效的软件缺陷。

常规输入还是非常规输入?

  输入分为常规输入和非常规输入。

一个常规输入表示没有特定的格式或含义,可以直接使用于被测试软件。

常规输入就是那些开发人员计划中的输入,也是真实用户经常使用的输入值。

非常规输入只在那些比较特殊的情况下才会发生,或者完全是由于某个机缘巧合才会发生。

比如,一个用户想在文本框内输入大写的字母C,他可能想使用Shift+c来键入该字符,但是他不小心按下了Ctrl+c键。

Shift+c是一个常规输入,代表大写字符C。

但是Ctrl+c就有完全不同的含义,比如在Windows系统中,它可以表示复制(Copy)或取消(Cancel)。

在一个输入框内键入Ctrl+c或其他某些特殊字符可能会导致某些意想不到的情况,甚至引发一些不希望发生的状况。

  所有和Ctrl、Alt、Esc按键组合的字符都算得上是特殊字符,比较明智的做法是在应用程序里测试某些这样的特殊字符,如果发生不合要求的情况就要把它当成软件缺陷上报。

测试人员可以安装最终用户可能会使用的那些特殊字体,使用这种方法来测试不同国家的语言。

某些字体,在处理Unicode或某些多字节字符集时,如果它没有被正确地本地化,不能支持当地的语言时,就会发生软件失效的情况。

测试人员可以从产品的文档出发,看看该软件支持那些语言,然后安装那些所支持语言的语言包和字体库,这样就可以开始测试那些特殊字符了。

  还有一些特殊字符与软件运行的平台相关。

每一个操作系统、编程语言、浏览器和运行时环境都有一些特定的保留词,它们具有特殊的含义。

Windows就有一些保留的设备名称,例如LPT1、COM1、AUX等。

如果一个输入框期待测试人员输入一个文件名,但是如果键入的是这些保留词,程序往往会挂起或彻底崩溃。

根据软件运行平台的不同,在输入框中键入的特殊字符有可能由运行平台来决定它的含义,也有可能由当前软件来决定。

明确回答该问题的唯一方法是找出那些相关的特殊字符,然后使用它们作为测试输入值。

  默认输入或用户提供的输入?

  如果在一个空白的文本字中不输入任何东西,可以算是一个最简单的测试。

但是对测试人员来说是简单,对被测软件则并不简单。

事实上,测试人员不输入任何东西并不意味着软件就不需要花功夫去处理这些情况。

  不管是在空白字段中不输入字符或是给某个API传递一个NULL参数,它们都需要软件在默认(default)的情况下运行下去。

通常这些默认的情况要么被忽视,要么没经过深思熟虑。

在单元测试(unittesting)中,它们也常常被忽视,所以手工测试就成为最后一道防线。

  开发人员必须处理这些空白的输入,因为他们知道并不是所有的用户都会提供输入。

用户在输入时会跳过这些字段,他们可能根本没有看见该字段,或者没有意识到这些字段是需要输入的。

如果程序有很多数据输入字段(比如一个Web表单要求用户输入姓名、送货地址和其他一些私人信息),显示出的错误信息还会根据哪些字段没有填而变化。

这一点在测试中也很重要,不能忽视。

  除了测试不输入任何值,还有很多其他东西可以测试。

如果一个表单含有一些预先设置好的值,我在这里把这些值称为开发人员设置的默认值。

比如,在一个打印表单中的打印页数字段,默认值就可能是“全部”。

默认值反映的是开发人员认为的一个正常用户最有可能使用的数值。

测试人员需要检验开发人员所做的这些假定,必须保证开发人员在选择这些默认值时没有犯任何错误。

在看见开发人员设置的默认值后,首要任务是把该默认值删除,留下一个空白的字段。

(开发人员往往没有考虑到这种情况,因为他们把时间都花在如何设置默认值,却没有去想如果该数值没有怎么办。

)接着就是试试在默认值附近的一些其他值。

如果是一个数值字段,试试比默认值大1或小1的数。

如果是一个字符串字段,试试修改默认字符串头部的几个字符,尾部的几个字符,加上几个字符或删除几个字符。

还可以尝试一下使用和默认字符串具有相同长度但不同字符的字串等来看看结果。

  一个字段如果被预先设置好默认值,便和不含默认值的字段在程序处理时往往有很大的不同。

测试人员如果愿意在这上面花费一些额外的时间,肯定会获得回报。

  使用输出来指导输入选择

  本章讲述的都是如何选择输入,至今为止我们已经讨论了如何根据输入值自身固有的属性(无论这些属性我们喜欢或是不喜欢)来进行输入选择。

换句话说,一些属性(如类型、长度、大小、值等)很适宜作为测试输入对象。

选择输入的另一种方法是考察它可能会(或者应该会)导致哪些输出结果。

  从很多方面来说,这和孩子试图说服父母让他去参加某个聚会的过程类似。

孩子可能知道回答必定是两者之一,不是“同意”就是“不同意”,所以他肯定会使用一种让父母更有可能同意的方式来发问。

比如,一种问法是“我可以参加那个激情四射的疯狂舞会吗?

”另一种是“我有几个好朋友去乔伊家聚会,我可以和他们一起去吗?

”前者听上去很糟糕。

提问的方式在很大程度上决定了最后得到什么样的答案。

  这个概念也可以用于软件测试。

具体来说就是先明确自己希望软件会产生什么样的反应,然后确定哪些输入会引发相应输出,然后在测试中使用这些输入值。

  很多测试人员的第一反应就是对任何一个功能,首先把其所有的主要输出结果罗列出来,然后确定哪些输入会引发这些输出。

把输入和输出配对是最常用的一种手段,它可以保证所有有趣的场景都被测试过了。

  如果从抽象的角度而言,最高层的抽象就是把输出分为非法输出(illegaloutupt)和合法输出(legaloutput)。

前者的大部分都和我们前面描述的那些用于产生错误消息的技术相重复。

出现重复是不可避免的,但是测试人员必须把精力主要放在生成各种各样的合法输出上,多多益善,这样可以保证新增的功能和场景都被测试到了。

  下面的这种测试方式要求测试人员积极主动地从输出结果来思考整个问题。

测试人员首先确定他们希望程序产生什么样的输出结果,然后考察所有的用户场景,看看如何去生成期望的结果。

还有一种测试方式相对而言比较被动一些,但有时它也非常有效,那就是先观察输出结果,然后再选择新的输入,并保证新的输出是重新计算后的结果,或者是确保新的输出结果和原先不同。

  当软件第一次针对输入产生某种响应时,通常是处于一种默认的情形,很多内部的变量和数据结构刚刚被初始化,输出结果第一次被生成。

当输出结果被第二次生成时,很多变量的值还是上一次运行时被设定的值。

这意味着第二次测试的情况和第一次的完全不同。

第一次我们测试的是软件处于一个未被初始化的状态时如何产生输出,而第二次测试的则是当软件处于一个已被初始化的状态时如何产生输出的。

这两个是不同的测试,如果其中一个测试通过了,而另一个失败了,这种情形也并不少见。

  还有一种从被动观察输出结果衍生出来的测试方法是寻找那些被保存起来的输出结果。

这种输出值通常在被计算出来后会被显示在屏幕上,或者被存储在一个文件中以供程序未来再次读取。

如果这些值是可以改变的,一定要试试去改动这些值或者改动它们的功能(大小和类型等),这样可以测试该值是否在原有的值上被重新生成了。

测试人员对每一个功能都需要运行这样的测试。

  输入选择的复杂性只是测试人员在软件测试中最先遭遇的技术难题。

不断地对软件进行输入后,软件内部的数据结构被持续更新,不同的内部变量值导致软件处于不同的状态,这就出现了软件状态的问题。

下面就让我们来看看它是怎样让软件测试变得更复杂的。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 环境科学食品科学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1