软件测试浅悟妄语

上一篇 / 下一篇  2013-05-27 15:49:42 / 个人分类:测试人生

本文转自:http://www.51testing.com/html/69/n-81769.html

妄语:
 
  软件是不可测试的,因为我们的眼界不是无限的、手段不是无限的;
  软件是可以测试的,因为软件的用户是有限的,用户的操是有限的。
 
小序:
 
  近日有朋友抱怨说自己因为写不出测试Case、报不出Bug而压力很大,以致经常梦到猪笼草及杀虫剂,或者在厨房中遭遇不长眼的小强并将其拍死后竟条件反射地打开电脑想报个Bug给Lead。朋友问我怎么办,其实我也是一脸苦笑——抓Bug有时是要看运气的——如果Version是在寅时Build出来,兴许Bug会多一些,如果是在申时Build出来,兴许Bug会少很多(如果开发团队在国外,别忘记倒时差)。
  这些当然是说笑。我想说的是,目前市面上大多数软件测试类书籍都是国外作者写成,虽然也有不少著作是我们中国测试专家写成,但里面引经据典了很多国外作品,使测试思想沿习了欧美的思路。
  一个民族最伟大的东西是什么?是文化和思想。那么我们能不能用中国的文化和思想去重新审视软件测试的方法,创新出自己的思路来呢?本文就是一次斗胆尝试。
 
正文:
 
  测试中的文化

  西方人善于推理,因此他们的测试流程是——
  1. Test Plan
  2. Test Case
  3. Find Bug
  4. Review fixed bug
  以上这4个环节是用推理的办法逐步细化,并随着软件版本的更新而迭代前行的。
 
  中国人善于归纳,按照上面的这个流程做测试时,最大的困难是第一步到第二步的跨越——依Test Plan去正推Test Case是件很痛苦的事情,很容易陷入两个误区:一个误区是写了一大堆不疼不痒的Case,把测试变成了跑龙套;另一个误区是过分追求要抓到Bug,结果产生很多疏漏。
  为什么会出现这种情况呢?原因在于文化。Test Plan本身是按“逻辑”将软件的功能分组,然后进行测试,老外的逻辑思维能力是比较强的,基本上能够比较轻松地把符合Test Plan中某个分枝的操作都挑出来、Fill进Test Plan里,而这在我们中国人看来,这是对软件操作的一种“割裂”,因此心里会感觉很乱、无从下手——于是测试就成了一个怎么也走不出去的迷宫。
  我的办法是:先写Test Plan,但不以Test Plan为指导方针;按照软件的Functions写Test Case,然后把Test Case分门别类填充到Test Plan的框架中去——这一步就是归纳——有时候对于特殊的软件,甚至可以归纳出不同寻常的测试分支来。
  你可能会问:不按Test Plan怎么写Case啊??那不成了胡写八写了?
  下面我就来说说我是怎么分析功能、写Case的。
 
从“测试”二字说起
 
  一个民族的文化能够得以保存,是因为有了语言和文字。其中尤以文字最为厉害,因为语言难以记录(录音机、MP3和DV那是近几年的事儿),在千万年的口耳相传中难免产生讹变和失传,而文字是相当稳定的东西,即使发生讹变和误用,机率也比语言要小得多。
  特别是中国的方块字,那就是一座宝藏。古人在造字之初的含义就蕴含在这方寸之间,虽历经甲骨钟鼎、篆圆楷正,却几乎一点不变地穿越时空,把祖先想表达的意思直接带到我们面前。拉丁文等拼音文字就差一些了,它没有“形状”,只能依靠字母的排列组合来作为遗传的DNA了。
  中国人把Test翻译成测试,妙哉!
  先看“测”字。从“水”、从“则”。“则”为何物?我们常说的“规则”,规是用来画圆的、矩是用来画直角的,则最早是用“刀”把章法刻在“鼎”上让人们遵守的——后引申为“尺度”。这下,圆规、直尺、三角板都齐了,呵呵。拿尺子伸到水里,不就是测量水的深度吗?这就是“测”的本意——亘古未变。再进一步,其实测量不光能测水深吧,凡是与被测对象的属性打交道、进行量化的行为,都应该算作“测”。秦始皇下大力气统一“度”(长度)“量”(体积)“衡”(货币),不都是为了方便测试行业在全国的统一发展吗。请大家注意,“测”字为我们传递了一个非常重要的信息,那就是“静态”。基本上可以说,如果被测对象不是相对静态的,那么就无法测量了。量子物理中的“测不准原理”中的测,也正是说明这一点。
  再看“試”字。从“言”从“式”。 试,用也——《说文》。毋庸多言,“试”字为我们传递的重要理念是“动态”——使用,当然是动态的。而且,软件测试在国际范围内的公共定义就是“为了找到软件缺陷而进行的使用”。引申一步,“试”字从“言”,又有“考试”一个含义。看来,这个考试是口试了,呵呵。既然是考试,那么问答就是必要的了,所以会有一个言字,其实这一“问”和一“答”就是软件的“输入”与“输出”。
  软件的Build从拿到我们手里开始,就是处在“动”与“静”的交替状态。既然是动静交替,我们非要先把静的挑出来写成Case、再把固定某一种“动”挑出来写成Case(而不管它在什么时候出现),当然是件很麻烦的事情。那么我们应该怎么办呢?
 
对软件的“测”
 
  上文提到,静者为测。让我们想想软件都在什么时候是“静”的。
  我们看一个自然的流程:Build下载à下载完成à安装à安装完成à开启à使用à关闭à卸载。哪些是静?哪些是动?让我们一一剖析。
1.         下载 :     全部属性处在动态而不可测中。
2.         完成:      静态。此时可测量软件的大小、Hash验证码等。
3.         安装:      全部属性处在动态而不可测中。
4.         完成:      静态。此时可测量软件各文件大小,目录,COM注册情况,注册表情况等属性。
5.         开启:      动态。全部属性处在动态而不可测中。
6.         使用:      半动态。哈!怎么是半动态呢?因为这时候软件已经从硬盘Load进内存了,在内存中是相对静态的。你可以观察内存占用是否稳定、有否泄漏。这就叫“静中有动,动中有静”,这才是咱们中国人的哲学。
7.         关闭:      静态。检查运行后的生成物(如聊天记录、Log文件、temp文档)是应该存在还是被删除。
8.         卸载:      静态。检查有没有遗留物,硬盘、注册表,都找找看。
 
  看,这样理顺下来,是不是写Case就轻松多了?如果要是按照Test Plan的架构来写Case,这些Case应该分布在至少是“内存检验”“注册表检验”“安装测试”“文件完整性测试”……等等分支里。总之,在软件处在相对静态的时候,你能深入想出软件的多少属性,那么就能写多少Case。进而,你能想出多少直接和间接影响软件这些属性的环境因素,就又有多少Case出现……然而,我们的思考能力是有限的,我们几乎不可能把软件的所有属性都想到,我们也不可能把所有可能影响软件静态属性的环境因素都找出来——即使是使用各种静态测试工具,比如内存跟踪工具等——也不可以完全做到。因此,有了我开篇的妄语。
 
对软件的“试”
 
  上文说过,“试”是动态的。对软件的动态测试比较复杂,一是要时刻提醒自己要识别一些相对静止的属性,把对它们的观测提出来,二是动态测试要分析的东西也比较多——但并不是没有章法。
  软件动态测试之“道”,只有两个字,那就是——宇宙。
  古往今来谓之“宇”,它强调一个时序关系。我们在动态测试的时候,特别要注意软件操作的时序,因为每一步的操作都在直接和间接地影响着后面的操作。
  上下四方谓之“宙”,它强调一个空间关系。如果我们把软件看作一个系统,那么“宙”就是这个系统的环境。
  举个简单例子,我们观察上面的测试流程中的第3步“安装”:
  它的“宇”就是前两步和后几步,如果“宇”中的第2步出了问题——下载的时候文件出了问题,那么安装肯定要失败的。
  它的“宙”中有一项是硬盘空间,如果硬盘空间不足,那么安装也是要失败的。
  所以,我们在做软件的动态测试时,要把测试中的“宇”和“宙”想周全。
  那么,怎样才能把“宇”和“宙”想周全呢?
软件测试的生命之图
 
  如果把软件从启动到关闭看作是一次生命的话,那么软件的生命会是一张非常美丽的生命之图——这张图的起点是软件的Start,然后每一步你都有一个或者若干选择,从而让用户可以有多个达到下一步的通路,这些通路有的是可逆的,有的是单行的,有些是可跳过的……总之,我们最后会达到软件生命的另一端——关闭。
  虽然这是一个“图”数据结构,但是对每个通路的遍历却是一条线(我是说线性的步骤),其中包含一些可以回溯的步骤。而每条线又是由有限个线段构成的。
每条线段由两个端点和一条连线构成。两个端点,一个是起点(我称它为“起点场景”),一个是终点(我称它为“终点场景”),中间的连线是从起点到终点的“动作”。(目前CSDN没法上传图片,过几天我补上图)
  那么有个问题:这条小线段有几种走法?OK,让我们来分析一下——
1.         起点à正确操作à终点。(基线测试)
2.         起点à错误操作à终点。
3.         起点à正确操作à终点à正确操作à起点。
4.         起点à错误操作à终点à正确操作à起点。
5.         起点à正确操作à终点à错误操作à起点。
6.         起点à错误操作à终点à错误操作à起点。
7.         起点à部分正确操作à放弃à起点。
8.         起点à部分错误操作à放弃à起点。
  别忘记还有“宇”的问题,操作的上一步、下一步组合起来会如何?如果这一线段之前的“宇”都是正确的,那么这样的测试是常规的。如果此前的“宇”已经在某步出了问题(我称之为“错误传递”)那这对软件的质量就是考验了:我认为,凡是能在“宇”中传递下来的数据,都是正确的;如果有错误被在“宇”中传递,那么这就是软件的缺陷。有了这一点,情况似乎简单多了——我们只需要检查这几项就足够了:
1.         起点状态的正确性。
2.         操作输入的正确性(小到简单的鼠标点击,大到多项数据的组合输入,边界检验,默认值等)。
3.         终点的正确性(如果有错误,软件是否通过报错而阻止错误在“宇”向下中传递)。
4.         可返回性。
5.         返回操作的输入。
6.         返回起点后状态正确性的检查。

如果软件的每一步都能严格地通过这些“宇”测试,那么无疑会健壮很多。
  当然我们也不要将“宙”视若等闲,有这样几个问题需要问自己:
  1.         起点中的对象的属性都受哪些环境因素的影响?
  2.         一个操作会影响到哪些环境因素?
  3.         哪些环境因素会影响到当前要进行的操作?
  4.         终点能不能在环境中生存?
  5.         终点会对环境产生哪些影响?
  如果软件能通过这些测试,那么它会更加健壮。然而,找到这些“宙”因素是要依靠你大脑里的知识、强大的分析问题的能力、冥想、灵感……忘记什么Test Plan吧!打破框框的禁锢,用思考去测试软件!这时候,你基础知识的威力就显现出来了——汇编、操作系统、编译原理、软件工程等课程知识就成了你分析问题、设计Test Case的利器!然而……我们的知识总是有限的,我们分析问题的能力也是有限的,于是,有了我开篇的妄语。
 
思想之剑
 
  我强烈建议软件测试公司在招聘新员工的时候要查看一下员工的语文成绩。为什么?请往下看。
  当有了“静测动试”和测试的“宇宙观”后,我们应该如何下手写Test Plan和Test Case呢?答案是:从分析用例的句子成分开始。
  大多数测试员接触到的都是Test Case,也就是“测试用例”。实际上,在软件工程的最一开始,“用例”就已经出现了——它就是Use Cases。市面上关于如何写用例的书也有不少,其中《编写有效用例》堪称经典,建议大家都去读一读。理想状态下,软件都是有用例的——它是需求分析的产物。如果你发现一个软件没有用例支持,那么说明它根本没有良好的需求分析,几乎可以肯定它存在很多缺陷。相信我,一个没有良好设计的软件,再怎么测试也不会成为一个优秀的软件。
  偏偏我们的测试员都很走运——几乎都没有用例在手。原因很简单,那是一个软件生产的源策动力,那才是这个软件的精华——不是代码,一般做外包测试,雇主是不会把用例给测试员看的。还有的时候,项目和开发人员由于种种原因(包括时间紧、公司风格或懒惰等),根本没有用例,测试人员也要硬着头皮上。
  没有用例怎么办?有一种文档可以部分替代用例,那就是Functional Specification。不同公司及公司中不同的项目组对FS的定义不一样,有的就相当于用例,有的很粗糙。如果遇到粗糙的,没办法,我们只能多花时间在软件的使用上,然后把它细化。
  总之到最后,你应该拿到一批用例——这样才能展开对软件的分析和测试。顺便说一句:有用例的一大好处是——它跟我们的基线测试基本上是一致的J
  有了Use Case,我们就可以通过分析句子写出Test Case了。
我们来分析这句话:“漫漫黑夜终于过去了。一轮火红的太阳从东方冉冉升起!”它是一个精美绝伦的3D游戏场景,需要你测试一下——这个游戏是使用完全面向对象的方法开发的,一切物体都是对现实世界的模拟。
句子的分析如下:
1.         这个用例在宇向上分为两步。句子的主干为“夜过去”和“太阳升”。
2.         对“夜”的基线测试
           i.              夜能正确结束。
3.         对“夜”的静态属性分析(Check List)——定语分析
           i.              夜的颜色是黑的吗?        定语:黑
          ii.              夜的长度够吗?                定语:漫漫
4.         对“夜”行为的动态分析——状语、补语分析
           i.              夜能过去吗?                     补语:了,表示结束
          ii.              夜过去能回来吗?            不允许
5.         对“太阳”的基线测试
           i.              太阳正常升起
6.         对“太阳”的宇分析
           i.              太阳是在黑夜正常结束后开始升起的吗?
7.         对“太阳”的静态分析
           i.              是只有一个太阳吗?        定语:一轮
          ii.              太阳的颜色正确吗?        定语:火红
8.         对“太阳”的动态分析
           i.              是从东方吗?                     状语:东方
          ii.              升起的速度正常吗?        状语:冉冉(不是蜗速升起,呵呵)
        iii.              升的方向正确吗?            补语:起
        iv.              还会降下去吗?                不允许,太阳“降落”的方法只能在黄昏时调用
 
  做完这些测试,程序基本上过关。但我们还有深入挖掘的余地:昼夜更迭的本质原因是什么?是地球的自转。也就是说,这个Test Case的一个“宙”是没有在Use Case中出现的“地球”对象。
 
1.         对“地球”的静态测试
           i.              地球的自转方向正确吗?地球自西向东转,保证了太阳从东方升起,黑夜会结束。
          ii.              地球的自转速度正确吗?只有速度正确的情况下,黑夜才会“漫漫”、太阳升起才会“冉冉”。
2.         对“地球”的动态测试
           i.              地球会一直稳定转下去吗?(性能测试
          ii.              会有彗星撞地球吗(环境冲击测试)?这是“宙”测试(只要你肯想,会有很多环境因素)
同一个游戏中,还有这样一个Use Case:海上生明月,天涯共此时。我们继续分析——
        相信你会立刻意识到,这也与地球自转有关,而日升月沉共用一个地球,所以这个Case的地球就不用测试了。这时候,你应该意识到:地球自转是“黑夜过去”、“太阳升”、“明月生”等的源动因,所以这组隐藏Case的优先级反而高。而且,由于地球在Case中始终没有UI,所以它更有可能被归为功能测试和性能测试里去。
1.         基线测试
           i.              月亮升起,测验天涯范围内的时间是否一致
2.         “月”静态分析
           i.              亮度够吗?                定语:明
          ii.              位置正确吗?           定语:海上
3.         “月”的动态分析
           i.              升(生)的方向对吗?
          ii.              升(生)的速度正确吗?(此Case可以省略,与太阳升属等价类Case)。
4.         “天涯”静态分析
           i.              天涯的范围是一个时区吗?
          ii.              在天涯的范围内时间一致吗?(边界测试)
 
        其实,如果你肯仔细想,还能想出很多两个Use Case的“宇”和“宙”来。只要我们的测试团队能够超出用户可探知的“宇宙范围”,那么我们就胜利了。可喜的是,在我目前的测试项目中,我正在验证这种思路,特别是在“宙”测试上——试图挖掘对象与菜单操作的(菜单操作是最全面的)所有正交反应,果然找到很多意想不到的Bug。
宇宙终归是无限的,所以,我们除了要将上面的Test Case向Test Plan中归类外,就是更深入地研究“宇”和“宙”——究竟有多少Case和Bug隐藏其中?我不知道……也许跟点点繁星一样多吧……
 
结语:
 
         面对苍茫的宇宙,我敞开胸怀……
         软件是不可测试的,因为我们的眼界不是无限的、手段不是无限的;
         软件是可以测试的,因为软件的用户是有限的,用户的操是有限的。


TAG: 文章 测试 浅悟

fhhh_eyou的个人空间 引用 删除 fhhh_eyou   /   2018-07-30 07:10:19
-5
 

评分:0

我来说两句

日历

« 2022-01-18  
      1
2345678
9101112131415
16171819202122
23242526272829
3031     

数据统计

  • 访问量: 9199
  • 日志数: 11
  • 建立时间: 2013-04-24
  • 更新时间: 2014-01-21

RSS订阅

Open Toolbar