5.1 软件测试背景介绍
在讲解JUnit之前,有必要介绍一下软件测试的相关知识。所谓软件测试,就是在软件投入使用前,对软件需求分析、设计规格说明和编码的最后审查,目的是要在软件投入生产之前,尽可能多地发现其中的错误。大量数据表明,软件测试的工作量往往占软件开发总工作量的40%以上,而且成本不菲,故而软件测试在整个开发过程中具有举足轻重的地位,需要特别重视。
5.1.1 软件测试的原则
软件测试的原则包括以下几点:
(1)尽早地不间断地进行软件测试。
(2)测试实例应由测试输入数据和与之对应的预期输出结果两部分组成。
(3)整体测试工作应该由独立的专业的软件测试机构来完成。
(4)在设计测试用例时,应当包括合理的输入条件和不合理的输入条件。不合理的输入条件是指异常的、临界的、可能引起问题异变的输入条件。
(5)充分注意测试中的群集现象。经验表明,测试后程序残存的错误数目与该程序中已发现的错误数目或检错率成正比。应该对错误群集的程序段进行重点测试。
(6)严格执行测试计划,排除测试的随意性。测试计划应包括:所测试软件的功能、输入和输出、测试内容、各项测试的进度安排、资源要求、测试资料、测试工具、测试用例的选择、测试的控制方法和过程、系统的组装方式、跟踪规划、调试规则、回归测试的规定,以及评价标准等。
(7)对每一个测试结果做全面的检查和核实。
(8)妥善保存测试计划、测试用例、出错统计和最终分析报告,为维护提供方便。
5.1.2 软件测试的对象
软件测试不等于程序测试。软件测试应该贯穿整个软件定义与整个开发期间。因此需求分析、概要设计、详细设计以及程序编码等各个阶段所得到的文档,包括需求规格说明、概要设计规格说明、详细设计规格说明以及源程序,都是软件测试的对象。
在对需求分析理解与表达的正确性、设计与表达的正确性、实现的正确性以及运行正确性的验证中,任何一个环节发生了问题都可能在软件测试中表现出来。
确认是一系列的活动和过程,其目的是想证实在一个给定的外部环境中软件的逻辑态。静态确认一般不在计算机上执行程序,而是通过人工分析或者程序正确性证明来确认程序的正确性,也就是通常所说的代码走读(code review)。动态确认主要是通过动态分析和程序测试来检查程序的执行状态,以确认程序是否有问题。
验证则试图证明在软件生存期间的各个阶段,以及各阶段的逻辑协调性、完备性和正确性。验证对象包括:用户要求、需求说明书、设计说明书、源程序和运行结果。
5.1.3 软件测试的种类
软件测试按照4个步骤进行:单元测试、集成测试、客户测试和开发者测试。
1.单元测试
单元测试是为检查个别模块服务的。如果对象需要访问外部的数据源(例如数据库),就需要一些模拟的对象(Mock Object)来模拟数据库,但这也只有在真实环境的数据与测试环境不同的时候(例如测试环境里没有真实的数据库才需要Mock Object)。
2.集成测试
这些测试像在用户测试和单元测试之间的十字路口上的测试。集成测试用来帮助测试应用程序的交互性。Mock Object不会出现在集成测试中,因为它会增加测试时间。同样,集成测试也经常需要存在特定的测试环境,比如在数据库中放一些测试数据。集成测试也可以使用外部的工具(例如,Cactus就是这样一个J2EE集成的工具包)。
3.用户测试
这是功能的、系统的并且认可的测试。系统中的行为检查都作为一个整体。在极限编程理论中,这些测试是由用户编写的,它给出测试案例提纲。
4.开发者测试
开发者测试就是那些开发者校验整段代码、新加的代码、新加的函数的测试。对于每个开发者而言,随时生成新的测试去检查代码是很重要的。组织这些测试和组织这些代码有着同样的重要性。
5.1.4 软件测试的过程
当软件设计工作完成后,就应该进行测试的准备工作了。一般来说,需要由熟悉整个系统设计的人员编写测试大纲和测试通用的规则、设计完整的测试用例,以便进行系统的全面测试。
软件测试一般分为以下几个步骤。
1.编写测试样本
测试人员要仔细阅读相关资料,全面熟悉系统,编写测试计划,设计测试用例,做好测试准备。
2.代码评审
通过静态分析(static analysis)和动态分析(dynamic analysis)对软件的源代码进行研读,查找错误或收集一些度量数据。
3.单元测试
单元测试是针对软件设计的最小单位——程序模块进行正确性检测的测试工作。目的在于发现每个模块的内部可能存在的错误。一般采用结构测试(白盒法)的用例,尽可能达到彻底测试,然后辅助以功能测试(黑盒法)的用例,使之对任何合理和不合理的输入都能鉴别和响应。高可靠性的模块是组成可靠系统的坚实基础。
4.集成测试
集成测试是将模块按照设计要求组装起来同时进行测试,主要目标是发现与接口有关的问题。如数据穿过接口时可能丢失;一个模块与另一个模块可能有由于疏忽的问题而造成有害影响;把子功能组合起来可能没有产生预期的功能效果;个别看起来是可以接受的错误可能会积累到不能接受的程度;全程数据结构可能有错误等。
5.验收测试
验收测试的目的是向未来的用户表明系统能够像预定的要求那样工作,经集成测试后,已经按照设计把所有的模块组装成一个完整的软件系统,接口错误也已经基本排除了,接着就应该进一步验证软件的有效性,这就是验收测试的任务,即软件的功能和性能如同用户所合理期待的那样。
5.1.5 软件测试的基本方法
软件测试的基本方法有下面两种:黑盒测试和白盒测试。
1.黑盒测试
黑盒测试又称功能测试或数据驱动测试,它是在已知产品所应具有的功能的情况下,通过测试来检测每个功能是否都能正常使用。这种测试是在软件的接口处进行的,测试人员不需要考虑程序内部的逻辑结构和内部特性,只依据程序的需求说明书,检查程序的功能是否符合它的功能说明。
黑盒测试主要是为了发现以下几个问题:
(1)是否有不正确的功能或者遗漏了某些功能。
(2)在接口上,输入能否正确接收,并且能否输出正确的结果。
(3)性能上是否能够满足要求。
(4)是否有初始化或者终止性错误。
2.白盒测试
白盒测试又称为结构测试或逻辑驱动测试,它是知道产品内部工作过程,通过测试来检测产品内部动作是否按照规格说明书的规定正常进行,按照程序内部的结构测试程序,检验程序中的每条通路是否按预定要求正常工作,但又不顾它的功能。白盒测试的主要方法是逻辑驱动、基路测试等,主要用于软件验证。
软件人员通过白盒测试方法,主要对程序进行如下检查:
(1)对程序模块的所有独立的执行路径至少测试一次。
(2)对所有的逻辑判定,取“真”与“假”的两种情况都要至少测试一次。
(3)在循环边界和运行界限内执行循环体。
(4)测试内部数据结构的有效性等。
测试作为软件开发的重要环节,越来越多地受到开发人员的重视。随着软件开发规模的增加、复杂程度的提高,开展软件测试工作的重要性越来越明显。完成全面的测试是提高软件产品品质必不可少的手段。