测试分析与设计模式

发表于:2012-06-05来源:博客网作者:陈耿点击数: 标签:软件测试
前言 在上海成立的“测试俱乐部”打算编写一个测试杂志。我这为了这份杂志,并且为了将多年的经验进行总结,打算编写一系列的短文来阐述“测试分析与设计模式”这个题目。 这个题目主要关于在设计内进行的“白盒测试”。 如何通过测试的手段尽

  前言

  在上海成立的“测试俱乐部”打算编写一个测试杂志。我这为了这份杂志,并且为了将多年的经验进行总结,打算编写一系列的短文来阐述“测试分析与设计模式”这个题目。

  这个题目主要关于在设计内进行的“白盒测试”。 如何通过测试的手段尽量多的,尽量早的在设计中发现潜在的问题,修改,弥补设计上的漏洞,从而从根本上提高软件开发产物的质量。

  基于接触到的中国国内软件测试黑盒为主的现状,个人感觉把自己的白盒测试方面的经验贡献出来还是有些价值的。

  但是如果泛泛而谈白盒测试很难与实际的实践结合起来,并且一般很难认识到白盒测试在设计验证中的作用。这里要寻找一个与广大软件设计联系的切入点。即能够用来阐述方法,又能够被利用到设计实践中去。 设计模式是一个比较好的靶子。 不管是否有意识的运用,在软件设计中,设计模式是非常普遍的。 而每种模式适用于特定的情景和问题。其像一把双刃剑,在带来解决问题的好处以外还带来了潜在的风险。 设计中的测试分析就是对此杨长避短。

  设计模式在运用时,粒度和抽象度取决于设计者要解决的问题和所处的设计环节。本系列文章不具体讨论特定的设计模式适合何种环境和问题。事实上,很好的,很合适的设计模式也会因为团队能力的不足而引起问题;反之,有时看上去愚蠢的,不合适的设计模式运用也并非无法解决设计问题,或许仅仅是麻烦一些而已。本系列是从测试分析的观点角度来着重分析在对设计模型和代码进行静态分析或者发现测试需求时,每种设计模式所可能对应的薄弱点。

  设计模式是软件设计人员长期经验的积累。某个设计模式可能对于解决某类设计问题特别合适。 但是“没有银弹”。所以任何设计模式不能完美的完全解决现实设计中的所有问题。特别是当依据设计模式把功能设计进行映射时,或者说当把具体功能通过设计模式进行具体的设计落实时,会有一些特别需要谨慎的地方,容易出错的地方。 而测试分析,特别是针对设计的白盒测试分析,就应该根据这些容易出错的地方去考虑各种设计中可能未考虑到的情况。

  在现实软件设计中,设计模式并非决定软件的设计和实现的唯一因素。 一般来说软件需求,设计模式和软件所在的软/硬件平台所支持的软件技术三者结合起来才决定了软件的设计和实现究竟会是什么样子。

  分析视角

  对所谓“容易出错的地方”,“谨慎”的地方的描述可以有多种角度:

  角度一:从ISO 9126的质量属性角度:功能,可靠性,可用性,性能,可维护性 (Functionality, Reliability, Usability , Performance/Efficiency, Supportable/Maintainability, Portability)

  角度二:涉及到某种特定的实现方式或者说语言,操作系统等等情况时,其可能的弱点

  角度三:设计/代码中的错误模型:(某种类型的错误由于设计模式对实现思路的划分而特别集中在某些层次上,比如MVC中,对客户输入的合法性验证可能是集中于V和M中。 即M是否提供了合法性验证的方法,而V是否调用了验证)

  正向设计:

  上层语义要求(即对功能需求的理解)

  逻辑算法

  下层语义作用/副作用

  功能API (子模块,其他模块/子系统)

  软件问题API(并发问题--进程/线程,信号量,哈希表,窗口系统,内存管理)

  异常处理:

  数据范围,长度,内容

  错误返回/异常/信号/中断

  错误现场保护和恢复

  Timeout

  Overflow

  在真正开始讨论各个设计模式的问题之前,再次明确这里所谓“测试活动“的基本思路:

  1. 任何期望,需求,要求达到的东西,要求遵守的规则等等都可以被表述为“测试需求“

  2. 根据测试需求逐条在设计等等模型中推理其是否满足就是“测试执行“的过程。

  整个设计内测试或者说静态测试过程就是不断根据需求,架构等等上游模型,“发现测试需求”,然后通过逻辑推理等过程进行“执行”的过程。 这个过程里软件是在测试人员脑海里“运行”的。 而此“运行”的基础就是逻辑推理。

  设计模式一: 抽象工厂( Abstract Factory)

  抽象工厂是一种创建对象的方式。 其特性有二:

  一.提供创建特定类的方法--通过抽象工厂类来创建特定的类。

  二.实际的创建特定实现的类又通过特定的类工厂来进行。

  从另外角度来说,抽象工厂允许进行2个不同纬度的抽象。 比如对于一类功能进行一个抽象纬度。而各类功能的不同的实现依赖又是另外一个纬度。 举例来说同样的“文本编辑”框,可以是一个类;但是其在Linux中和windows中的实现是不同的,所以第一个纬度是功能,第二个纬度是操作系统。 通过抽象工厂类,使用者可以创建一类功能的不同实现。

  质量特性视角

  从功能角度看,抽象工厂这种设计模式主要用来作对象的创建。 所以一般对功能的属性没有特别大影响。

  抽象工厂模式在易用性上是提供了比较好的优势的。

  如果单纯的运用该模式,只要不涉及到过于频繁的创建/释放动作,一般来说对系统性能也不会有特别大的影响。避免在应用抽象工厂模式中附加自己实现的动态绑定,基本可以比较好的确保代码的性能。

  从稳定性角度来讲,抽象工厂模式带来的风险与创建动作带来的风险基本上是一致的, 即需要确认对象创建是否成功。当程序中对动态创建的对象进行足够的合法性检查时,该模式不会带来更多额外的稳定性风险。

  抽象工厂模式对于可维护性方面提供了2个纬度中一个纬度的可扩展性。但是直接在抽象工厂中定义的纬度的扩展性将会受到很大限制。 所以在确定抽象工厂类定义的纬度时,应该仔细考虑是否有比较大的扩展可能性--> 设计内的测试的分析对于这点,应该从过往的项目经验出发;从客户需求的历史出发;从该纬度本身的“自然特性”出发提出可能的扩展点。(这里列出的扩展点就是测试需求)对这些扩展点发生的可能性进行评估和讨论(而这样的评估和讨论就是测试执行)。 注意这里明确的提出可能的扩展点,以及对这样的扩展点进行讨论,正是测试活动之一。 所以必须对扩展点,以及其相关讨论,结论进行记录。简单讲,当认为不发生这种扩展的可能性很大时,对应测试项就是Pass;否则就是fail.

原文转自:http://www.ltesting.net