第五章软件测试 复习要求 1.了解软件测试的目的和原则。 2.了解软件错误的分类 3.了解软件测试的过程和策略。 4!.了解软件测试用例设计的方法,掌握逻辑覆盖、基本路径测试、因果图等测试用例设 计方法 5.了解程序静态测试的方法。 6.了解程序调试的概念。 7.掌握软件测试中的可靠性分析方法 内容提要 1.软件测试基础 (1)什么是软件测试 软件测试是为了发现错误而执行程序的过程。或者说,软件测试是根据软件开发各阶段 的规格说明和程序的内部结构而精心设计一批测试用例(即输入数据及其预期的输出结果) 并利用这些测试用例去运行程序,以发现程序错误的过程 软件测试在软件生存期中横跨两个阶段:通常在编写出每一个模块之后就对它做必要的 测试(称为单元测试)。模块的编写者与测试者是同一个人。编码与单元测试属于软件生存期 中的同一个阶段。在这个阶段结束之后,对软件系统还要进行各种综合测试,这是软件生存 期的另一个独立的阶段,即测试阶段,通常由专门的测试人员承担这项工作。 (2)软件测试的目的和原则 Grenford J Myers就软件测试目的提出以下观点: 测试是程序的执行过程,目的在于发现错误 一个好的测试用例在于能发现至今未发现的错误 一个成功的测试是发现了至今未发现的错误的测试 设计测试的目标是想以最少的时间和人力系统地找出软件中潜在的各种错误和缺陷。如 果我们成功地实施了测试,就能够发现软件中的错误。测试的附带收获是,它能够证明软件 的功能和性能与需求说明相符合。此外,实施测试收集到的测试结果数据为可靠性分析提供 了依据。 测试不能表明软件中不存在错误,它只能说明软件中存在错误 软件测试的原则: ①应当把“尽早地和不断地进行软件测试”作为软件开发者的座右铭 不应把软件测试仅仅看作是软件开发的一个独立阶段,而应当把它贯穿到软件开发的各 个阶段中。坚持在软件开发的各个阶段的技术评审,这样才能在开发过程中尽早发现和预防 错误,把出现的错误克服在早期,杜绝某些发生错误的隐患 ②测试用例应由测试输入数据和与之对应的预期输出结果这两部分组成
1 第五章 软件测试 一、复习要求 1. 了解软件测试的目的和原则。 2. 了解软件错误的分类。 3. 了解软件测试的过程和策略。 4. 了解软件测试用例设计的方法,掌握逻辑覆盖、基本路径测试、因果图等测试用例设 计方法。 5. 了解程序静态测试的方法。 6. 了解程序调试的概念。 7. 掌握软件测试中的可靠性分析方法 二、内容提要 1. 软件测试基础 (1) 什么是软件测试 软件测试是为了发现错误而执行程序的过程。或者说,软件测试是根据软件开发各阶段 的规格说明和程序的内部结构而精心设计一批测试用例(即输入数据及其预期的输出结果), 并利用这些测试用例去运行程序,以发现程序错误的过程。 软件测试在软件生存期中横跨两个阶段:通常在编写出每一个模块之后就对它做必要的 测试(称为单元测试)。模块的编写者与测试者是同一个人。编码与单元测试属于软件生存期 中的同一个阶段。在这个阶段结束之后,对软件系统还要进行各种综合测试,这是软件生存 期的另一个独立的阶段,即测试阶段,通常由专门的测试人员承担这项工作。 (2) 软件测试的目的和原则 Grenford J.Myers 就软件测试目的提出以下观点: ▪ 测试是程序的执行过程,目的在于发现错误; ▪ 一个好的测试用例在于能发现至今未发现的错误; ▪ 一个成功的测试是发现了至今未发现的错误的测试。 设计测试的目标是想以最少的时间和人力系统地找出软件中潜在的各种错误和缺陷。如 果我们成功地实施了测试,就能够发现软件中的错误。测试的附带收获是,它能够证明软件 的功能和性能与需求说明相符合。此外,实施测试收集到的测试结果数据为可靠性分析提供 了依据。 测试不能表明软件中不存在错误,它只能说明软件中存在错误。 软件测试的原则: ① 应当把“尽早地和不断地进行软件测试”作为软件开发者的座右铭。 不应把软件测试仅仅看作是软件开发的一个独立阶段,而应当把它贯穿到软件开发的各 个阶段中。坚持在软件开发的各个阶段的技术评审,这样才能在开发过程中尽早发现和预防 错误,把出现的错误克服在早期,杜绝某些发生错误的隐患。 ② 测试用例应由测试输入数据和与之对应的预期输出结果这两部分组成
测试以前应当根据测试的要求选择测试用例( Test case),用来检验程序员编制的程序, 因此不但需要测试的输入数据,而且需要针对这些输入数据的预期输出结果 ③程序员应避免检查自己的程序。 程序员应尽可能避免测试自己编写的程序,程序开发小组也应尽可能避免测试本小组开 发的程序。如果条件允许,最好建立独立的软件测试小组或测试机构。这点不能与程序的调 试( debuging)相混淆。调试由程序员自己来做可能更有效。 ④在设计测试用例时,应当包括合理的输入条件和不合理的输入条件。 合理的输入条件是指能验证程序正确的输入条件,不合理的输入条件是指异常的,临界 的,可能引起问题异变的输入条件。软件系统处理非法命令的能力必须在测试时受到检验。 用不合理的输入条件测试程序时,往往比用合理的输入条件进行测试能发现更多的错误 ⑤充分注意测试中的群集现象 在被测程序段中,若发现错误数目多,则残存错误数目也比较多。这种错误群集性现象 已为许多程序的测试实践所证实。根据这个规律,应当对错误群集的程序段进行重点测试, 以提高测试投资的效益 ⑥严格执行测试计划,排除测试的随意性 测试之前应仔细考虑测试的项目,对每一项测试做出周密的计划,包括被测程序的功能 输入和输出、测试内容、进度安排、资源要求、测试用例的选择、测试的控制方式和过程等 还要包括系统的组装方式、跟踪规程、调试规程,回归测试的规定,以及评价标准等。对于 测试计划,要明确规定,不要随意解释 ⑦应当对每一个测试结果做全面检查。 有些错误的征兆在输出实测结果时已经明显地出现了,但是如果不仔细地全面地检査测 试结果,就会使这些错误被遗漏掉。所以必须对预期的输出结果明确定义,对实测的结果仔 细分析检査,抓住征侯,暴露错误。 ⑧妥善保存测试计划,测试用例,出错统计和最终分析报告,为维护提供方便。 (3)确认和验证的关系 确认(Ⅷ alidation)是一系列的活动和过程,其目的是想证实在一个给定的外部环境中软 件的逻辑正确性。它包括需求規格说明的确认和程序的确认,而程序的确认又分为静态确认 与动态确认。静态确认一般不在计算机上实际执行程序,而是通过人工分析或者程序正确性 证明来确认程序的正确性:动态确认主要通过动态分析和程序测试来检査程序的执行状态, 以确认程序是否有问题。 验证( Verification),则试图证明在软件生存期各个阶段,以及阶段间的逻辑协调性、完 备性和正确性 确认与验证工作都属于软件测试。在对需求理解与表达的正确性、设计与表达的正确性、 实现的正确性以及运行的正确性的验证中,任何一个环节上发生了问题都可能在软件测试中 表现出来。 (4)测试信息流 测试信息流如图5.1所示。测试过程需要三类输入: 软件配置:包括软件需求规格说明、软件设计规格说明、源代码等 测试配置:包括测试计划、测试用例、测试驱动程序等; 测试工具:测试工具为测试的实施提供某种服务。例如,测试数据自动生成程序、 静态分析程序、动态分析程序、测试结果分析程序、以及驱动测试的工作台等。 测试之后,用实测结果与预期结果进行比较。如果发现出错的数据,就要进行调试。对 已经发现的错误进行错误定位和确定出错性质,并改正这些错误,同时修改相关的文档。修 正后的文档一般都要经过再次测试,直到通过测试为止
2 测试以前应当根据测试的要求选择测试用例(Test case),用来检验程序员编制的程序, 因此不但需要测试的输入数据,而且需要针对这些输入数据的预期输出结果。 ③ 程序员应避免检查自己的程序。 程序员应尽可能避免测试自己编写的程序,程序开发小组也应尽可能避免测试本小组开 发的程序。如果条件允许,最好建立独立的软件测试小组或测试机构。这点不能与程序的调 试(debuging)相混淆。调试由程序员自己来做可能更有效。 ④ 在设计测试用例时,应当包括合理的输入条件和不合理的输入条件。 合理的输入条件是指能验证程序正确的输入条件,不合理的输入条件是指异常的,临界 的,可能引起问题异变的输入条件。软件系统处理非法命令的能力必须在测试时受到检验。 用不合理的输入条件测试程序时,往往比用合理的输入条件进行测试能发现更多的错误。 ⑤ 充分注意测试中的群集现象。 在被测程序段中,若发现错误数目多,则残存错误数目也比较多。这种错误群集性现象, 已为许多程序的测试实践所证实。根据这个规律,应当对错误群集的程序段进行重点测试, 以提高测试投资的效益。 ⑥ 严格执行测试计划,排除测试的随意性。 测试之前应仔细考虑测试的项目,对每一项测试做出周密的计划,包括被测程序的功能、 输入和输出、测试内容、进度安排、资源要求、测试用例的选择、测试的控制方式和过程等, 还要包括系统的组装方式、跟踪规程、调试规程,回归测试的规定,以及评价标准等。对于 测试计划,要明确规定,不要随意解释。 ⑦ 应当对每一个测试结果做全面检查。 有些错误的征兆在输出实测结果时已经明显地出现了,但是如果不仔细地全面地检查测 试结果,就会使这些错误被遗漏掉。所以必须对预期的输出结果明确定义,对实测的结果仔 细分析检查,抓住征侯,暴露错误。 ⑧ 妥善保存测试计划,测试用例,出错统计和最终分析报告,为维护提供方便。 (3) 确认和验证的关系 确认(Validation)是一系列的活动和过程,其目的是想证实在一个给定的外部环境中软 件的逻辑正确性。它包括需求规格说明的确认和程序的确认,而程序的确认又分为静态确认 与动态确认。静态确认一般不在计算机上实际执行程序,而是通过人工分析或者程序正确性 证明来确认程序的正确性; 动态确认主要通过动态分析和程序测试来检查程序的执行状态, 以确认程序是否有问题。 验证(Verification),则试图证明在软件生存期各个阶段,以及阶段间的逻辑协调性、完 备性和正确性。 确认与验证工作都属于软件测试。在对需求理解与表达的正确性、设计与表达的正确性、 实现的正确性以及运行的正确性的验证中,任何一个环节上发生了问题都可能在软件测试中 表现出来。 (4) 测试信息流 测试信息流如图 5.1 所示。测试过程需要三类输入: ▪ 软件配置:包括软件需求规格说明、软件设计规格说明、源代码等; ▪ 测试配置:包括测试计划、测试用例、测试驱动程序等; ▪ 测试工具:测试工具为测试的实施提供某种服务。例如,测试数据自动生成程序、 静态分析程序、动态分析程序、测试结果分析程序、以及驱动测试的工作台等。 测试之后,用实测结果与预期结果进行比较。如果发现出错的数据,就要进行调试。对 已经发现的错误进行错误定位和确定出错性质,并改正这些错误,同时修改相关的文档。修 正后的文档一般都要经过再次测试,直到通过测试为止
通过收集和分析测试结果数据,对软件建立可靠性模型。 错 排错 改正的软件 测试 软件配置 测试配置 果 测试工具 分析 预测的可靠性 图5.1测试信息流 如果测试发现不了错误,那么可以肯定,测试配置考虑得不够细致充分,错误仍然潜伏 在软件中。这些错误最终不得不由用户在使用中发现,并在维护时由开发者去改正。但那时 改正错误的费用将比在开发阶段改正错误的费用要高出40倍到60倍。 (5)测试与软件开发各阶段的关系 软件开发过程是一个自顶向下,逐步细化的过程,而测试过程则是依相反的顺序安排的 自底向上,逐步集成的过程。低一级测试为上一级测试准备条件。参看图52,首先对每一个 程序模块进行单元测试,消除程序模块内部在逻辑上和功能上的错误和缺陷。再对照软件设 计进行集成测试,检测和排除子系统(或系统)结构上的错误。随后再对照需求,进行确认 测试。最后从系统全体出发,运行系统,看是否满足要求 需求分析 设计 集成测试一单元测试」一 球分析L概要设计。详细设 说明书」L说明书」ˉ说明书」ˉ代码」测试」测试 则试 图52软件测试与软件开发过程的关系 2.程序错误分类 由于人们对错误有不同的理解和认识,所以目前还没有一个统一的错误分类方法。错误 难于分类的原因,一方面是由于一个错误有许多征兆,因而它可以被归入不同的类。另一方 面是因为把一个给定的错误归于哪一类,还与错误的来源和程序员的心理状态有关 (1)按错误的影响和后果分类 ■较小错误:只对系统输出有一些非实质性影响。如,输出的数据格式不合要求等 中等错误:对系统的运行有局部影响。如输出的某些数据有错误或出现冗余 ■较严重错误:系统的行为因错误的干扰而出现明显不合情理的现象。比如开出了000
3 通过收集和分析测试结果数据,对软件建立可靠性模型。 图 5.1 测试信息流 如果测试发现不了错误,那么可以肯定,测试配置考虑得不够细致充分,错误仍然潜伏 在软件中。这些错误最终不得不由用户在使用中发现,并在维护时由开发者去改正。但那时 改正错误的费用将比在开发阶段改正错误的费用要高出 40 倍到 60 倍。 (5) 测试与软件开发各阶段的关系 软件开发过程是一个自顶向下,逐步细化的过程,而测试过程则是依相反的顺序安排的 自底向上,逐步集成的过程。低一级测试为上一级测试准备条件。参看图 5.2,首先对每一个 程序模块进行单元测试,消除程序模块内部在逻辑上和功能上的错误和缺陷。再对照软件设 计进行集成测试,检测和排除子系统(或系统)结构上的错误。随后再对照需求,进行确认 测试。最后从系统全体出发,运行系统,看是否满足要求。 图 5.2 软件测试与软件开发过程的关系 2. 程序错误分类 由于人们对错误有不同的理解和认识,所以目前还没有一个统一的错误分类方法。错误 难于分类的原因,一方面是由于一个错误有许多征兆,因而它可以被归入不同的类。另一方 面是因为把一个给定的错误归于哪一类,还与错误的来源和程序员的心理状态有关。 (1) 按错误的影响和后果分类 ▪ 较小错误:只对系统输出有一些非实质性影响。如,输出的数据格式不合要求等。 ▪ 中等错误:对系统的运行有局部影响。如输出的某些数据有错误或出现冗余。 ▪ 较严重错误:系统的行为因错误的干扰而出现明显不合情理的现象。比如开出了0.00
元的支票,系统的输出完全不可信赖 ■严重错误:系统运行不可跟踪,一时不能掌握其规律,时好时坏 ■非常严重的错误:系统运行中突然停机,其原因不明,无法软启动。 ■最严重的错误:系统运行导致环境破坏,或是造成事故,引起生命、财产的损失。 (2)按错误的性质和范围分类 B Beizer从软件测试观点出发,把软件错误分为5类 ①功能错误 ■规格说明错误:规格说明可能不完全,有二义性或自身矛盾 ■功能错误:程序实现的功能与用户要求的不一致。这常常是由于规格说明中包含错 误的功能、多余的功能或遗漏的功能所致 测试错误:软件测试的设计与实施发生错误。软件测试自身也可能发生错误。 测试标准引起的错误:对软件测试的标准要选择适当,若测试标准太复杂,则导致 测试过程出错的可能就大 ②系统错误 ■外部接口错误:外部接口指如终端、打印机、通信线路等系统与外部环境通信的手 段。所有外部接口之间,人与机器之间的通信都使用形式的或非形式的专门协议。如果协议 有错,或太复杂,难以理解,致使在使用中岀错。此外还包括对输入/输出格式错误理解 对输入数据不合理的容错等等。 内部接口错误:内部接口指程序之间的联系。它所发生的错误与程序内实现的细节 有关。例如,设计协议错、输入/输出格式错、数据保护不可靠、子程序访问错等。 ■硬件结构错误:这类错误在于不能正确地理解硬件如何工作。例如,忽视或错误地 理解分页机构、地址生成、通道容量、I/O指令、中断处理、设备初始化和启动等而导致的 出错。 操作系统错误:这类错误主要是由于不了解操作系统的工作机制而导致出错。。当然 操作系统本身也有错误,但是一般用户很难发现这种错误 ■软件结构错误:由于软件结构不合理或不清晰而引起的错误。这种错误通常与系统 的负载有关,而且往往在系统满载时才出现。这是最难发现的一类错误。例如,错误地设置 局部参数或全局参数:错误地假定寄存器与存储器单元初始化了:错误地假定不会发生中断 而导致不能封锁或开中断:错误地假定程序可以绕过数据的内部锁而导致不能关闭或打开内 部锁:错误地假定被调用子程序常驻内存或非常驻内存等等,都将导致软件出错 控制与顺序错误:这类错误包括:忽视了时间因素而破坏了事件的顺序:猜测事件 出现在指定的序列中;等待一个不可能发生的条件:漏掉先决条件;规定错误的优先级或程 序状态:漏掉处理步骤;存在不正确的处理步骤或多余的处理步骤等。 ■资源管理错误:这类错误是由于不正确地使用资源而产生的。例如,使用未经获准 的资源:使用后未释放资源;资源死锁:把资源链接在错误的队列中等等。 ③加工错误 算术与操作错误:指在算术运算、函数求值和一般操作过程中发生的错误。包括 数据类型转换错:除法溢出:错误地使用关系比较符:用整数与浮点数做比较等 ■初始化错误:典型的错误有:忘记初始化工作区,忘记初始化寄存器和数据区;错 误地对循环控制变量赋初值:用不正确的格式,数据或类型进行初始化等等 ■控制和次序错误:这类错误与系统级同名错误类似,但它是局部错误。包括:遗漏 路径;不可达到的代码;不符合语法的循环嵌套:循环返回和终止的条件不正确:漏掉处理 步骤或处理步骤有错等 ·静态逻辑错误:这类错误主要包括:不正确地使用CASE语句;在表达式中使用不
4 元的支票,系统的输出完全不可信赖。 ▪ 严重错误:系统运行不可跟踪,一时不能掌握其规律,时好时坏。 ▪ 非常严重的错误:系统运行中突然停机,其原因不明,无法软启动。 ▪ 最严重的错误:系统运行导致环境破坏,或是造成事故,引起生命、财产的损失。 (2) 按错误的性质和范围分类 B.Beizer 从软件测试观点出发,把软件错误分为 5 类。 ① 功能错误 ▪ 规格说明错误:规格说明可能不完全,有二义性或自身矛盾。 ▪ 功能错误:程序实现的功能与用户要求的不一致。这常常是由于规格说明中包含错 误的功能、多余的功能或遗漏的功能所致。 ▪ 测试错误:软件测试的设计与实施发生错误。软件测试自身也可能发生错误。 ▪ 测试标准引起的错误:对软件测试的标准要选择适当,若测试标准太复杂,则导致 测试过程出错的可能就大。 ② 系统错误 ▪ 外部接口错误:外部接口指如终端、打印机、通信线路等系统与外部环境通信的手 段。所有外部接口之间,人与机器之间的通信都使用形式的或非形式的专门协议。如果协议 有错,或太复杂,难以理解,致使在使用中出错。此外还包括对输入/输出格式错误理解, 对输入数据不合理的容错等等。 ▪ 内部接口错误:内部接口指程序之间的联系。它所发生的错误与程序内实现的细节 有关。例如,设计协议错、输入/输出格式错、数据保护不可靠、子程序访问错等。 ▪ 硬件结构错误:这类错误在于不能正确地理解硬件如何工作。例如,忽视或错误地 理解分页机构、地址生成、通道容量、I/O 指令、中断处理、设备初始化和启动等而导致的 出错。 ▪ 操作系统错误:这类错误主要是由于不了解操作系统的工作机制而导致出错。。当然, 操作系统本身也有错误,但是一般用户很难发现这种错误。 ▪ 软件结构错误:由于软件结构不合理或不清晰而引起的错误。这种错误通常与系统 的负载有关,而且往往在系统满载时才出现。这是最难发现的一类错误。例如,错误地设置 局部参数或全局参数;错误地假定寄存器与存储器单元初始化了;错误地假定不会发生中断 而导致不能封锁或开中断;错误地假定程序可以绕过数据的内部锁而导致不能关闭或打开内 部锁;错误地假定被调用子程序常驻内存或非常驻内存等等,都将导致软件出错。 ▪ 控制与顺序错误:这类错误包括:忽视了时间因素而破坏了事件的顺序;猜测事件 出现在指定的序列中;等待一个不可能发生的条件;漏掉先决条件;规定错误的优先级或程 序状态;漏掉处理步骤;存在不正确的处理步骤或多余的处理步骤等。 ▪ 资源管理错误:这类错误是由于不正确地使用资源而产生的。例如,使用未经获准 的资源;使用后未释放资源;资源死锁;把资源链接在错误的队列中等等。 ③ 加工错误 ▪ 算术与操作错误:指在算术运算、函数求值和一般操作过程中发生的错误。包括: 数据类型转换错;除法溢出;错误地使用关系比较符;用整数与浮点数做比较等。 ▪ 初始化错误:典型的错误有:忘记初始化工作区,忘记初始化寄存器和数据区;错 误地对循环控制变量赋初值;用不正确的格式,数据或类型进行初始化等等。 ▪ 控制和次序错误:这类错误与系统级同名错误类似,但它是局部错误。包括:遗漏 路径;不可达到的代码;不符合语法的循环嵌套;循环返回和终止的条件不正确;漏掉处理 步骤或处理步骤有错等。 ▪ 静态逻辑错误:这类错误主要包括:不正确地使用 CASE 语句;在表达式中使用不
正确的否定(例如用“>”代替“<”的否定):对情况不适当地分解与组合:混淆“或”与 异或”等 ④数据错误 动态数据错误:动态数据是在程序执行过程中暂时存在的数据。各种不同类型的动 态数据在程序执行期间将共享一个共同的存储区域,若程序启动时对这个区域未初始化,就 会导致数据出错。由于动态数据被破坏的位置可能与出错的位置在距离上相差很远,因此要 发现这类错误比较困难 静态数据错误:静态数据在内容和格式上都是固定的。它们直接或间接地出现在程 序或数据库中。由编译程序或其它专门程序对它们做预处理。这是在程序执行前防止静态错 误的好办法,但预处理也会出错。 数据内容错误:数据内容是指存储于存储单元或数据结构中的位串、字符串或数字。 数据内容本身没有特定的含义,除非通过硬件或软件给予解释。数据内容错误就是由于内容 被破坏或被错误地解释而造成的错误。 数据结构错误:数据结构是指数据元素的大小和组织形式。在同一存储区域中可以 定义不同的数据结构。数据结构错误主要包括结构说明错误及把一个数据结构误当做另一类 数据结构使用的错误。这是更危险的错误 ■数据属性错误:数据属性是指数据内容的含义或语义。例如,整数、字符串、子程 序等等。数据属性错误主要包括:对数据属性不正确地解释,比如错把整数当实数,允许不 同类型数据混合运算而导致的错误等 ⑤代码错误 主要包括:语法错误;打字错误;对语句或指令不正确理解所产生的错误。 (3)按软件生存期阶段分类 Good enough- Gerhart分类方法把软件的逻辑错误按生存期不同阶段分为4类。 ①问题定义(需求分析)错误 它们是在软件定义阶段,分析员研究用户的要求后所编写的文档中出现的错误。换句话 说,这类错误是由于问题定义不满足用户的要求而导致的错误。 ②规格说明错误 这类错误是指规格说明与问题定义不一致所产生的错误。它们又可以细分成: 不一致性错误:规格说明中功能说明与问题定义发生矛盾。 冗余性错误:规格说明中某些功能说明与问题定义相比是多余的 ■不完整性错误:规格说明中缺少某些必要的功能说明 不可行错误:规格说明中有些功能要求是不可行的 不可测试错误:有些功能的测试要求是不现实的。 ③设计错误 这是在设计阶段产生的错误,它使系统的设计与需求规格说明中的功能说明不相符。它 们又可以细分为: 设计不完全错误:某些功能没有被设计,或设计得不完全。 算法错误:算法选择不合适。主要表现为算法的基本功能不满足功能要求、算法不 可行或者算法的效率不符合要求 ·模块接口错误:模块结构不合理;模块与外部数据库的界面不一致,模块之间的界 面不一致。 ■控制逻辑错误:控制流程与规格说明不一致;控制结构不合理 ■数据结构错误:数据设计不合理;与算法不匹配:;数据结构不满足规格说明要求 ④编码错误
5 正确的否定(例如用“>”代替“<”的否定);对情况不适当地分解与组合;混淆“或”与 “异或”等。 ④ 数据错误 ▪ 动态数据错误:动态数据是在程序执行过程中暂时存在的数据。各种不同类型的动 态数据在程序执行期间将共享一个共同的存储区域,若程序启动时对这个区域未初始化,就 会导致数据出错。由于动态数据被破坏的位置可能与出错的位置在距离上相差很远,因此要 发现这类错误比较困难。 ▪ 静态数据错误:静态数据在内容和格式上都是固定的。它们直接或间接地出现在程 序或数据库中。由编译程序或其它专门程序对它们做预处理。这是在程序执行前防止静态错 误的好办法,但预处理也会出错。 ▪ 数据内容错误:数据内容是指存储于存储单元或数据结构中的位串、字符串或数字。 数据内容本身没有特定的含义,除非通过硬件或软件给予解释。数据内容错误就是由于内容 被破坏或被错误地解释而造成的错误。 ▪ 数据结构错误:数据结构是指数据元素的大小和组织形式。在同一存储区域中可以 定义不同的数据结构。数据结构错误主要包括结构说明错误及把一个数据结构误当做另一类 数据结构使用的错误。这是更危险的错误。 ▪ 数据属性错误:数据属性是指数据内容的含义或语义。例如,整数、字符串、子程 序等等。数据属性错误主要包括:对数据属性不正确地解释,比如错把整数当实数,允许不 同类型数据混合运算而导致的错误等。 ⑤ 代码错误 主要包括:语法错误;打字错误;对语句或指令不正确理解所产生的错误。 (3) 按软件生存期阶段分类 Good enough-Gerhart 分类方法把软件的逻辑错误按生存期不同阶段分为 4 类。 ① 问题定义(需求分析)错误 它们是在软件定义阶段,分析员研究用户的要求后所编写的文档中出现的错误。换句话 说,这类错误是由于问题定义不满足用户的要求而导致的错误。 ② 规格说明错误 这类错误是指规格说明与问题定义不一致所产生的错误。它们又可以细分成: ▪ 不一致性错误:规格说明中功能说明与问题定义发生矛盾。 ▪ 冗余性错误:规格说明中某些功能说明与问题定义相比是多余的。 ▪ 不完整性错误:规格说明中缺少某些必要的功能说明。 ▪ 不可行错误:规格说明中有些功能要求是不可行的。 ▪ 不可测试错误:有些功能的测试要求是不现实的。 ③ 设计错误 这是在设计阶段产生的错误,它使系统的设计与需求规格说明中的功能说明不相符。它 们又可以细分为: ▪ 设计不完全错误:某些功能没有被设计,或设计得不完全。 ▪ 算法错误:算法选择不合适。主要表现为算法的基本功能不满足功能要求、算法不 可行或者算法的效率不符合要求。 ▪ 模块接口错误:模块结构不合理;模块与外部数据库的界面不一致,模块之间的界 面不一致。 ▪ 控制逻辑错误:控制流程与规格说明不一致;控制结构不合理。 ▪ 数据结构错误:数据设计不合理;与算法不匹配;数据结构不满足规格说明要求。 ④ 编码错误