这几天看了一些关于软件工程里面软件测试方面的书籍,感觉蛮有收获,试与诸君共分享之。

  软件测试,对我这个才进入软件领域两年不到的菜鸟来说是一个既熟悉又陌生的词汇。每个软件行业的人不可能没听说过软件测试,但是,我相信大多数和我一样的菜鸟都没有真正对自己写的软件程序做过系统的测试工作。


  说到这里,有很多同学都不乐意了。我怎么没测试了?!!我都是写一段代码run一下,保证一段代码成功了才写后面的好不好。而且,我写的程序都能正确运行好不好。OK,OK,先不谈这个,当年我也是这么认为的,关于这点我们首先来界定下何为软件测试再说。

  官话:软件测试的目的是为了发现软件设计和实现过程中的疏忽说造成的错误。

  我的理解:发现并修改软件中不好的部分。这些不好的地方指错误、低效代码、不合理或不方便的设计等等一切影响功能和终客户反馈的地方。

  同学们,还坚持么?

  一个很吓人的事实是软件界存在8020法则,即大多数好的软件其测试所花费的工作量比其他所有的软件工程加起来都多,比例为80:20。从这个角度来讲,若大型系统的测试还像小游戏一样无规则、无计划的进行测试,结果可想而知...可想而知,好的测试思路与方法在正式的测试工作当中是必要的了...

  一、软件测试的战略方法与思想

  1.1 验证与确认(Verification and Validation,V&V)

  在大的方向,软件测试通常做两件事:验证--即保证软件的功能正确实现,和确认--确保软件合乎客户真正的需求。

  上面的话可能让人头痛----不是一样的意思么?

 

  好吧,换一种说法:验证--我们在正确的构造产品么? 确认--我们在构造正确的产品么?

  验证不用说,正确性是软件(其实远不止软件)基本的要求,做计算器时你至少得保证1+1不等于3吧!!关于确认,很多编程人员都有一个误区,是我做客户让我做的东西。但一个很重要的问题是,客户提出的需求真的与软件的实际需求一致么?撇去客户表达与需求分析之间的不一致性不谈,在人机设计与界面交互这一块我们能做的更好吧。这里借用MXR同学的成果(见图1):当我们在做webAPP时,对同样的功能需求,不同的表现方式会达到不同的效果。这也是说,软件测试,不仅仅是测试错误,更要对软件的可用性与适用性做出修正,即保证软件的质量。同样,测试还应该包括性能监控、可行性研究、数据库评测、算法分析等等一切影响软件质量的属性。


  图1


  1.2 软件测试的组织

  V&V实现解决了测试是干什么这个基本问题,现在要解决另一个基本问题:谁来做测试工作?

 

  很多人会有这样的思想,对同样的东西(这里是指待测试的软件模型),不同的人在认识上肯定会有差异。那么,软件开发人员对软件进行测试是一个很好的选择,谁能比开发者本人更了解程序呢!!!这也是为什么别人列出一长串代码让你找出某个错误时,你不耐烦的原因。

 

  然而,一个显而易见的事实是,开发人员本身总是急于展现他们所开发的程序的正确性,是成功的,是符合期望的,这是人之常情。令人遗憾的是,错误时客观存在的。笔者也经常在向别人展示自己花了很大心思做成的程序时,试图掩饰莫名出现的错误。有人说过,从心理学方面来看,软件的分析和设计都是一类建设性的工作。从本文后面可以看到,软件人员总是努力构造测试实例来“破坏”软件。软件工程师也会自豪与自己的“孩子”,这种仇视任何一个企图伤害自己“孩子”的人这种心理是可以理解的。

  那么是否可以得出结论:开发工作与测试工作应该分离开来?答案是否定的。虽然独立测试组(Independent Test Group,ITG)在所有大公司都是存在的,但开发人员与测试人员在软件开发初期应该进行交流。一个原因前面已经说了,你能忍受从头看别人给你的100000+行代码,然后找出某个似乎存在的错误么?笔者在前一段时间试图分析hadoop的源代码,不到两天脑袋歇菜了。另一个可能的原因是,测试并不仅仅是“大家一起来找茬”,而是一个自我修正的过程,完全需要开发人员一起来参与。

 

  从这个意义上来讲,ITG是软件开发项目组的一部分。


  1.3 软件测试的流程

  如图2所示,在软件工程的螺旋开发模型当中,软件开发呈螺旋方式(PS:可能没画出螺旋效果,见谅)。工作开始初期需

  要在系统级别定义软件的角色,接着进行需求分析活动,紧接着的是整体与单元设计,后


  则是编码阶段。一步一步降低抽象层次。


  图2

  软件的测试过程同样可以以一种螺旋模型看待。与开发过程不同,测试过程是一种由内而外的过程,即首先进行单元测试,接着是集成测试,然后是确认测试,后的活动室系统测试。一般而言,单元测试和集成测试的主要工作在开发期。

  单元测试:


  单元测试软件设计的小单元(软件构件或模块)的验证过程。这个过程侧重于构件中的内部处理逻辑与对外接口、局部数据结构、独立路径和错误处理路径。测试内部逻辑与对外接口是为了测试对单元数据的正常流入与流出。这部分不关心数据在构件间的交互。检查数据结构是为了保证数据信息在算法的执行过程中保证其完整性。笔者曾经写了一个二叉决策树,用于一个坦克大战的小游戏程序中AI坦克方向判断,但每次在坦克变换方向后都回到初始地方,后来发现是在算法结束后有一项数据被清零了,?。独立路径和错误处理路径会在后面介绍测试战术中的白盒测试的文章中提到。

  下面列出别人总结的一些计算中常见的错误:1)不正确的算术优先级 2)混合模式操作,貌似我也不理解这个 3)不正确的初始化,以前老犯,现在好了些 4)不精确的精度,暂时没碰到过,估计一旦出问题,很难发现 5)表达式有不正确的符号表示 5)边缘测试,这个特别重要,软件在边界出错,通常出现在n维数组或者n次循环的第1个或者第n个元素,哎,这个错误笔者犯的数不胜数了,而且一直改不了。