UML软件工程组织

测试、测试、测试
--软件测试的理论和实践
Blueski 选自:松耦合空间

题记:测试是交付成功的优质的产品的保证

 

我们每个人,不会都是软件测试人员,但都是某些软件的用户。缺省或默认情况下,用户都会觉得买到的软件是没有问题的,一般不会去想这样的软件可能会有问题,用户只要使用这些软件来解决他们需要解决的问题就可以了。当他们发现问题的时候,甚至会感到震惊。存在的问题很多都和测试的成效有关系,一般的软件产品存在的问题确实比较少,但我觉得即使是以前买的正版的金山快译2000都有着一些显而易见的bug。如果测试不充分,那么这些问题会潜伏在软件中,等到用户发现以后,再有开发人员进行维护,改正错误的费用一般是开发阶段的40倍到60倍。

人们对测试存在着一些误区,例如:
1 测试是想象到可能出现的问题,然后试图验证这些问题。
实际上能想象到的只是一部分的情况,随意性太大,还要取决于开发人员的经验,对业务的熟悉程度和他想象到的程度。
2 让时间有富裕的员工去做一些测试
表面上看这体现了管理的效率和灵活性,但实际上也体现了管理者对测试的轻视。测试和测试的人有很大关系。测试工作人员应该是勤奋并富有耐心,善于学习、思考和发现问题,细心有条理,总结问题,如果具备这样的优点,做其它工作同样也会很出色,因此这里还有一个要求,就是要喜欢测试这项工作。如果他是专职的,那么肯定更有经验和信心。国内的小伙子好象都喜欢做程序员,两者工作性质不同,待遇不同,地位不同,对自我实现的价值的认识也不同,这是行业的一个需要改善的问题。如果只是为了完成任务而完成任务,或者发现了几个问题就觉得满意了,这在任何其它工作中都是不行的。
3 测试是相对简单的工作。
实际上并非如此,要真正做好一件事都不容易。测试也有很多相关技术和工具。而对测试的轻视问题,也许要通过痛苦的经历和结果才可能确切体会到。很多专家都在对测试的理论进行深入的探讨和研究。

测试的基本知识

让我们一起快速过一遍:

什么是软件测试:在软件投入运行前,对软件需求分析、设计规格说明和编码的最终复审,是软件质量保证的关键步骤。
测试的目标:以较少的用例、时间和人力找出软件中潜在的各种错误和缺陷,以确保系统的质量。
从测试的类型来看,测试分为2种:黑盒测试和白盒测试。
黑盒测试又称为功能测试或数据驱动测试,把系统看成一个黑盒子,不考虑程序的内在逻辑,只根据需求规格说明书的要求来检查程序的功能是否符合它的功能说明。
白盒测试又称为结构测试和逻辑驱动测试,允许测试人员对程序内部逻辑结构及有关信息来设计和选择测试用例,对程序的逻辑路径进行测试。
测试用例由测试输入数据以及与之对应的输出结果组成。测试用例设计的好坏直接决定了测试的效果和结果。
从测试实际的前后过程来看,软件测试上是由一系列的不同测试所组成,这些软件测试的步骤分为:单元测试、组装测试(集成测试)、确认测试和系统测试。软件开发的过程是自顶向下的,测试则正好相反,以上这些过程就是自底向上,逐步集成的。

单元测试(模块测试):针对每个模块进行的测试,可从程序的内部结构出发设计测试用例,多个模块可以平行地对立地测试。通常在编码阶段进行,必要的时候要制作驱动模块和桩模块。
集成测试:在单元测试的基础上,将所有模块按照设计要求组装成为系统,必须精心计划,应提交集成测试计划、集成测试规格说明和集成测试分析报告。
确认测试:验证软件的功能和性能及其它特性是否与用户的要求一致。
系统测试:将软件放在整个计算机环境下,包括软硬件平台、某些支持软件、数据和人员等,在实际运行环境下进行一系列的测试。

测试工作的文档主要有:测试计划、测试模型和用例设计或规格说明、测试分析报告等。从软件工程上说,这是属于软件配置的一部分。(我不知道,如果什么报告都没有,只是不断地摆弄执行程序,看到错误和问题就记下来,算不算真正的测试?)

测试需要一定的技术和工具


在用例设计过程中,可以考虑到很多方面,并且也有很多的指导方法和技术。

黑盒测试用例设计包括:

等价类划分:划分等价类--确立测试用例--设计用例
边界值分析:通过分析,考虑如何确立边界情况
错误推测法:靠经验和直觉来推测程序中可能存在的各种错误,从而有针对性地编写用例。可以列举出可能的错误和可能发生错误的地方,然后选择用例。
因果图:通过画因果图,在图上标明约束和限制,转换成判定表,然后设计测试用例。这适合于检查程序输入条件的各种组合情况。

功能图FD:通过形式化地表示程序的功能说明,并机械地生成功能图的测试用例。

白盒测试用例设计包括:

1 逻辑覆盖,以程序内在逻辑结构为基础的测试,包括以下5种类型:

1.1 语句覆盖:每一条可执行语句至少覆盖一次;
1.2 判定覆盖(分支覆盖):设计若干个测试用例,运行所测程序,使程序中每个判断的取真分支和取假分支至少执行一次;
1.3 条件覆盖:设计足够多的测试用例,运行所测程序,使程序中每个判断的每个条件的每个可能取值至少执行一次;
1.4 判定-条件覆盖:设计足够多的测试用例,运行所测程序,使程序中每个判断的每个条件的所有可能取值至少执行一次,并且每个可能的判断结果也至少执行一次;
1.5 条件组合测试:设计足够多的测试用例,运行所测程序,使程序中每个判断的所有可能的条件取值至少执行一次;
1.6 路径测试:设计足够多的测试用例,运行所测程序,要覆盖程序中所有可能的路径。


2 基本路径测试

在程序控制流图的基础上,通过分析控制构造的环路复杂性,导出基本可执行路径集合,从而设计测试用例。包括以下5个方面:
2.1 程序的控制流图:描述程序控制流的一种图示方法。
2.2 程序环境复杂性:McCabe复杂性度量。从程序的环路复杂性可导出程序基本路径集合中的独立路径条数,这是确定程序中每个可执行语句至少执行依次所必须的测试用例数目的上界。
2.3 导出测试用例
2.4 准备测试用例,确保基本路径集中的每一条路径的执行
2.5 图形矩阵:是在基本路径测试中起辅助作用的软件工具,利用它可以实现自动地确定一个基本路径集。

程序的静态分析方法:

1 生成各种引用表、静态错误分析

2 人工测试:桌前检查、代码评审等

3 软件测试工具:包括静态分析工具、动态测试工具、测试数据自动化生成工具、模块测试台、测试合成环境

3.1 静态分析工具:语言程序的预处理器、数据库工具、错误分析器和报告生成器。直接扫描所测试的正文,对程序的数据流和控制流进行分析,然后送出测试报告。

3.2 动态测试工具:通过选择适当的测试用例,实际运行所测程序,比较实际运行结果和预期结果,发现错误。

3.3 测试数据自动化生成工具:包括路径测试数据生成程序、随机测试数据生成程序以及根据数据规格说明生成测试数据

3.4 模块测试台是一种专门的测试用例描述语言,负责将输入数据传送到所测试模块中,然后将实际输出结果与在描述测试用例的语言中所表述的期望结果进行比较,发现错误。另外,也包括其它的功能:语句跟踪、动态断句、覆盖度量、用户自定义符号表、内容表和输出格式。

3.5 测试合成环境:包括环境模拟程序,代码检查程序,测试文档生成程序,测试执行严整程序,输出比较程序,程序正确性证明程序等,以及各种调试工具。而且还有集成系统,集成了多种工具,如SADAT、Microsoft Test for Windows和PureArtria等。

 

***********************************************************

 

测试的管理

作为项目或产品开发的一个必要的组成部分,需要良好的组织和管理。使用软件质量规范,编写和实现测试用例和模型,可以有效地组织测试。

一般的测试工作过程也可以是:计划-->配置(必要的软硬件资源下)-->开发(构造或配置测试工具、创建测试套件和测试方案库、准备适当的报告工具并记录测试系统如何运转)-->测试执行(进行测试、记录测试条件和问题,报告结果)。

测试管理也可以从测试经理和测试小组2个方面去看:

测试经理要管理好团队,很多人认为测试是枯燥乏味的事情,而且似乎低级的事情,所以测试经理应该不断地激励小组成员,为他们争取利益。在时间进度上保证稳步前进。就象赛跑,一开始就加班加点,只会导致极限的过早到来。
作为测试经理,应该有足够的质量意识。评价质量风险的方法是“失败模式和效果分析”(Failure Mode and Effect Analysis, FMEA)。这种方法可以允许您在特定的质量风险和结果上映射需求、规范,以及项目小组假设。然后,按照风险级别进行分类,并按序排列。
实际上如果能得到充分的资源已是很困难的了,能用好临时的测试人员也已经不错了。一般企业的主管和技术经理都并不怎么真正重视测试工作的意义和价值。也许他们认为临时的投入一次性的强力测试足以发现绝大部分问题,而实际上这对产品的长远发展,以及质量改进都没有太大好处。

测试过程中软件功能可能进行调整和变化,测试发现问题也会导致变化,需要重新的测试。对这些变更也需要进行管理。
另外,由于上层管理部门的不重视,必须想办法与之进行清楚而有效的沟通;同开发部门的沟通也非常重要,因为开发和测试在性质上是有些对立的,很容易在相互之间产生一些不必要的矛盾。和开发部门不同的是,一般质量或测试部门和市场或销售部门的立场倒是比较一致的,如果双方都认为高质量的产品是市场战略中重要的品牌战略,彻底的测试对于达到这样的目标来说意义重大。因此,有必要和市场部门保持协作和交流。

测试经理可以经常问自己一些问题:

计划做哪些测试?实际完成了哪些测试?使用了多少用例?其中多少没有通过?管理部门是否有足够的支持?他们是否向你要过测试报告?开发部门的联络是否及时?等等。如果你是测试管理人员,应该可以想到更多的问题。


测试小组:

测试小组有多大的规模,一般取决于项目规模、测试人员与开发人员的比例、项目经理对质量保证的认识和期望等,也取决于你的准确的测试计划。
对一些项目来说,最好是在开始阶段就有测试人员有所介入。

如本文一开始所提到的,在测试小组中测试人员必须具备的素质包括:有效的坦率真诚的交流的能力、清晰简明的表达能力、一定的好奇心(但不至于太强,以至于花太多精力去探究一个微小的问题),不应害怕提出尖锐问题引起麻烦,一定的责任心,
注意力能够高度集中,是职业悲观主义者(但不是抱怨和憎恶)。

以下是一些测试的方法和基本工具:

测试方案、测试模型和测试用例
测试就象是做实验一样,实验对于象我这样的理工科毕业生来说真是太熟悉不过了。做实验之前必然有实验的方案、内容和步骤,测试似乎也是同样的。另外,基于测试用例的测试和常见的随机性的测来测去也是完全不同的,尽管习惯于随机性测试的人,如果注意力集中的话,他的头脑里也是有一些测试用例的。

关于测试实验室,进行测试工作首先要争取到尽可能好的环境。如果可能,应该建立测试实验室,实验室包括必要的装备、工具软件(包括测试工具)和各种操作系统平台,保持实验室的实用、整洁,避免他人干扰甚至破坏测试环境。

关于测试跟踪软件,制作一个简单的测试问题跟踪软件,记录测试的结果,将测试发现的问题分类,并对测试发现的问题和模块、开发人员进行关联,有助于分析问题,并可有效记录测试的结果,形成测试报告,并从中找出一些规律性的东西来。因此测试问题跟踪软件还是有一定的价值的。

关于测试自动化,有一定的风险。对一个稳定的系统,甚至可以自己开发自动化软件,而对于正处于快速变形中的软件开发过程,接口、主要功能和支持环境在发展变化中。为测试配置环境也要付出很多的时间。

以下是关于测试的一些技巧和经验:

在制定测试计划的时候,就要考虑到测试的风险,并抉择要执行哪些测试,并放弃哪些测试;测试计划的评审应该让开发人员参与;
测试模型的制作应该尽可能贴近用户,或者站在用户的使用立场上来观测软件,此时应该能发现更多的问题。

由于测试发现问题,在解决问题后还要重新测试,因此测试的时间可能会比实际更长一些

识别和注意少数重要的方面,而忽略多数次要的方面,有时候少数的问题足以致命,这些问题将是软件测试结果中重要性最高的错误。

错误的定位有时是很难的,要找出必然发生的前因后果,而不至于因为描述错误而误导开发人员。有时候确实存在错误不能重建的问题。解决办法之一是在错误报告中给予说明。

对错误的描述,应该是准确、完整而简练。因为描述的问题或者不完整的描述会引起开发人员的误解,其后果是可以想见的。

有时有经验的测试人员凭借直觉就可以发现一些问题,这可称为“错误猜测”。

测试人员容易犯2种错误:一是测试人员发生判断错误,将本没有错误的系统行为报告为错误,或者将错误指定了过高的严重级别,或者过高估计了问题的严重性,这样会引起开发人员的不信任,产生一种象“狼来了”一样的效果;二是测试人员将错误的严重性或优先级定得过低,从而产生“测试逃逸”,这样会造成产品质量的风险。以上两种错误应该尽量避免。

 

最后,我忽然想,测试实际上可以覆盖到硬件,甚至非计算机产品的测试,也许可以相互借鉴。

还有一种很奇特的感想,这种感想使我反而有些困惑不清了。我发现对测试来说,理论和实践的距离好象非常遥远,我先看了一本软件工程的书,然后写下了前面的一半内容,然后我又匆匆翻看了一本美国人的书,叫做《测试流程管理》,然后整理出了本文后一半的内容,该书中有着比本文多得多的各方面的实践经验。歌德说过,理论是苍白的,生命之树常青。我稍稍改变一下,就变成了:理论是苍白的,实践之树常青。也许测试是一种实践性很强的工作,大学教授们一般也不可能热衷于参加测试工作吧。

 

 

版权所有:UML软件工程组织