• 软件的质量主要取决于需求分析的质量
  • 程序的质量主要取决于软件设计的质量
  • 程序代码的质量取决于详细设计的质量

1,编码

1.1,选择程序设计语言

程序设计语言是人和计算机通信的最基本的工具,会影响人的思维和解题方式,影响人和计算机通信的方式和质量,影响其他人阅读和理解程序的难易程度。

选择适宜的程序设计语言的原因:根据设计去完成编码时,困难最少;可以减少需要的程序测试量;可以得到更容易阅读和更容易维护的程序。

高级语言优于汇编语言:

  • 汇编语言编码需要把软件设计翻译成机器操作的序列,既困难又容易出差错;
  • 高级语言写程序比用汇编语言写程序生产率可以提高好几倍;
  • 用高级语言写的程序容易阅读、容易测试、容易调试、容易维护。

理想标准:所选用的高级语言应该有理想的模块化机制,以及可读性好的控制结构和数据结构;为了便于调试和提高软件可靠性,语言特点应该使编译程序能够尽可能多地发现程序中的错误;为了降低软件开发和维护的成本,选用的高级语言应该有良好的对编译机制。

实用标准
系统用户的要求 如果开发的系统由用户负责维护,用户通常要求用他们熟悉的语言编写程序。
可以使用的编译程序 运行目标系统的环境中可以提供的编译程序往往限制了可以选用的语言的范围。
可以得到的软件工具 如果某种语言有支持程序开发的软件工具,则目标系统的实现和验证都变得比较容易。
工程规模

如果工程规模很庞大,现有的语言又不完全适用,设计并实现一个专用的语言,可能

是个正确的选择。

程序员的知识 选择一种已经所熟知的语言
软件的可移植性要求 选择一种标准化程度高,程序可移植性好的语言是很重要的。
软件的应用领域 FORTRAN适合工程和科学计算,COBOL适合商业领域应用,C语言适合实施应用领域。

1.2,编码风格

源程序代码的逻辑简明清晰、易读易懂是好程序的一个重要标准,为了做到这一点,应该遵循下述规则。

1,程序内部的文档:所谓程序内部的文档包括恰当的标识符、适当的注解和程序的视觉组织等。

  • 标识符:含义鲜明的名字、缩写规则一致、为名字加注解。
  • 注解:正确性,简要描述模块的功能、主要算法、接口特点、重要数据以及开发简史或解释包含这段代码的必要性。
  • 视觉组织:适当的阶梯形式使程序的层次结构清晰明显。

程序清单布局对于程序的可读性也有很大影响,应该利用适当的阶梯形式使程序的层次结构清晰明显。

2,数据说明原则:

  • 数据说明的次序应该标准化。
  • 当多个变量名在一个语句中说明时,应该按字母顺序排列这些变量。
  • 如果设计时使用了一个复杂的数据结构,则应该用注解说明用程序设计语言实现这个数据结构的方法和特点。

3,语句构造

  • 不要为了节省空间而把多个语句写在同一行;
  • 尽量避免复杂的条件测试;
  • 尽量减少对“非”条件的测试;
  • 避免大量使用循环嵌套和条件嵌套;
  • 利用括号使逻辑表达式或算术表达式的运算次序清晰直观。

4,输入输出规则

  • 对所有输入数据都进行检验;
  • 检查输入项重要组合的合法性;
  • 保持输入格式简单;
  • 使用数据结束标记,不要要求用户指定数据的数目;
  • 明确提示交互式输入的请求,详细说明可用的选择或边界数值;
  • 程序设计语言对格式有严格要求时,应保持输入格式一致;
  • 设计良好的输出报表;
  • 给所有输出数据加标志。

5,效率:主要指处理机时间和存储器容量两个方面。

  • 效率是性能要求,因此应该在需求分析阶段确定效率方面的要求;
  • 效率是靠好设计来提高的;
  • 程序的效率和程序的简单程度是一致的,不要牺牲程序的清晰性和可读性来不必要地提高效率。
程序运行时间 写程序之前先简化算术的和逻辑的表达式;
仔细研究嵌套的循环,以确定是否有语句可以从内层往外移;
尽量避免使用多维数组;
尽量避免使用指针和复杂的表;
使用执行时间短的算术运算;
不要混合使用不同的数据类型;
尽量使用整数运算和布尔表达式。
存储器效率

在大型计算机中必须考虑操作系统页式调度的特点,一般说来,使用能保持功能域的结构化控制结构,

是提高效率的好方法。
在微处理机中如果要求使用最少的存储单元,则应选用有紧缩存储器特性的编译程序,

在非常必要时可以使用汇编语言。
提高执行效率的技术通常也能提高存储器效率。提高存储器效率的关键同样是“简单”。

输入输出效率 所有输入输出都应该有缓冲,以减少用于通信的额外开销;
对二级存储器(如磁盘)应选用最简单的访问方法;
二级存储器的输入输出应该以信息组为单位进行;
如果“超高效的”输入输出很难被人理解,则不应采用这种方法。

2,软件测试

软件测试是保证软件质量的重要手段之一。软件开发和软件测试通常由不同的人员来完成,软件开发人员较少直接参与软件测试,但是其对软件测试也应该有一些了解。

软件测试的工作量通常占用软件开发工作的40%,在某些极端的情况下,例如那些关系到生命财产安全的软件所花费的测试成本,可能相当于软件工程其他开发步骤的3~5倍。

  • 对于用户来说,他们希望通过软件测试来发现软件中潜在的缺陷问题,以考虑是否继续接受该软件产品。
  • 对于开发者来说,他们希望测试成为软件产品中不存在缺陷和问题的证明过程,从而表明该软件产品已能满足用户需求。

软件测试和软件质量保证:软件测试从“破坏”的角度出发,力图找出软件的缺陷;软件质量保证从“建设”的角度出发,监督和改进过程,尽量减少软件的缺陷。软件质量保证的过程贯穿整个软件开发,从需求分析开始,到最后的系统上线,软件质量保证贯穿全部过程。

2.1,软件测试定义

从广义角度来看,软件测试包括在软件产品生命周期内所有的检查、评审和确认活动,如设计评审、系统测试等。从狭义角度来看,软件测试的范围要小得多,它单指对软件产品的质量进行测试。

软件测试的定义1:测试是使用人工和自动手段来运行或检测某个系统的过程,其目的在于检验系统是否满足规定的需求,或者弄清预期结果与实际结果之间的差别。

软件测试的定义2:

  • 测试是为了发现程序中的错误而执行程序的过程。
  • 好的测试方案是极可能发现迄今为止尚未发现的错误的测试方案。
  • 成功的测试是发现了至今为止尚未发现的错误的测试。

软件测试的定义3(Glen Myers):

  • 软件测试是为了发现软件隐藏的缺陷。
  • 一次成功的软件测试是发现了尚未被发现的缺陷。
  • 软件测试并不能保证软件没有缺陷。

应该认识到测试决不能证明程序是正确的。即使经过了最严格的测试之后,仍然可能还有没被发现的错误潜藏在程序中。另外,在综合测试阶段通常由其他人员组成测试小组来完成测试工作。

软件测试的目的:并不是为了证明程序是正确的,而是以最少的时间和人力,系统地找出软件中潜在的各种错误和缺陷。

2.2,软件测试准则

  • 所有测试都应该能追溯到用户需求。
  • 应该远在测试开始之前就制定出测试计划。
  • 把Pareto原理应用到软件测试中;Pareto原理说明,测试发现的错误中的80%很可能是由程序中20%的模块造成的。
  • 应该从“小规模”测试开始,并逐步进行“大规模”测试。
  • 穷举测试是不可能的。
  • 为了达到最佳的测试效果,应该由独立的第三方从事测试工作。  所谓“最佳效果”是指有最大可能性发现错误的测试。
  • 开发人员避免测试自己的程序。
  • 妥善保存测试计划、测试用例、出错统计和最终分析报告。

2.3,测试分类(方法)

从软件工程的总体把握来分:

(1)静态测试:针对测试不运行部分进行检查和审阅。静态测试又分为如下三种:

  • 代码审阅:检查代码设计的一致性,检查代码的标准性、可读性,包括代码结构的合理性。
  • 代码分析:主要针对程序进行交流分析,包括数据流分析、接口分析和表达式分析等。
  • 文档检查:主要检查各阶段的文档是否完备。

静态测试可找出的缺陷:不匹配的参数、不合适的循环嵌套和分值嵌套、不允许的递归、未使用过的变量、空指针的引用、可疑的计算等。

(2)动态测试:通过运行和试探发现缺陷。按照测试的内容又分为三类:

  • 功能确认与接口测试:包括各个单元功能的正确执行、单元间的接口,如单元接口、局部数据结构、重要的执行路径、错误处理的路径和边界条件等内容。
  • 覆盖率分析:主要对代码的执行路径覆盖范围进行评估,如语句覆盖、判定覆盖、条件覆盖、条件/判定覆盖、修正条件/判定覆盖、基本路径覆盖等,都是从不同要求出发来设计测试用例的。
  • 性能分析:代码运行缓慢是开发过程中的重要问题。如果应用程序的运行速度较慢,那么程序员不容易找到是哪里出现了问题;如果不能解决应用程序的性能问题,那么将降低并极大地影响应用程序的质量。查找和修改性能瓶颈称为调整整个代码性能的关键。

依据是否针对系统内部结构和具体实现算法可分为

  • 黑盒测试:(又称功能测试)把程序看作一个黑盒子,完全不考虑程序的内部结构和处理过程。黑盒测试是在程序接口进行的测试,只检查程序功能是否能按照规格说明书的规定正常使用,程序是否能适当地接收输入数据并产生正确的输出信息,程序运行过程中能否保持外部信息(例如数据库或文件)的完整性。
  • 白盒测试:(又称结构测试)是把程序看成装在一个透明的白盒子里,测试者完全知道程序的结构和处理算法。这种方法按照程序内部的逻辑测试程序,检测程序中的主要执行通路是否都能按预定要求正确工作。
  • 灰盒测试:是介于白盒测试与黑盒测试之间的一种测试,灰盒测试多用于集成测试阶段,不仅关注输出、输入的正确性,同时也关注程序内部的情况。灰盒测试不像白盒那样详细、完整,但又比黑盒测试更关注程序的内部逻辑,常常是通过一些表征性的现象、事件、标志来判断内部的运行状态。

从软件测试工程的大小来分,软件测试又分为:

(1)单元测试(主要白盒测试):测试中的最小单位,测试特殊的功能和代码模块。由于必须了解内部代码和设计的详细情况,该测试通常由开发者来完成。该测试的难易程度与代码设计的好坏直接相关。

(2)集成测试(主要灰盒测试):测试应用程序结合的部分来确定它们的功能是否正确,主要测试功能模块或独立的应用程序。这种测试的难易程度取决于系统的模块粒度。

(3)系统测试(主要黑盒测试):测试人员根据程序的功能来进行测试。

(4)验收测试:

  • α测试(内测):由测试人员模拟最终用户来完成。
  • β测试(公测):由最终用户在实际使用环境中使用来完成测试。

(5)平行测试:同时运行新开发的系统和即将被取代的旧系统,比较新旧两个系统的运行结果。通过平行测试,可以在准生产环境中运行新系统而不冒风险,从而对新系统进行全负荷测试来检验性能指标,为用户熟悉新系统赢得时间,并赢得更多时间来验证用户指南、使用手册等用户工具。

2.4,测试步骤

模块测试

(单元测试)

模块测试的目的是保证每个模块作为一个单元能正确运行。

在这个测试步骤中所发现的往往是编码和详细设计的错误。

子系统测试

(集成测试)

子系统测试是把经过单元测试的模块放在一起形成一个子系统来测试。

这个步骤着重测试模块的接口

系统测试

(集成测试)

系统测试是把经过测试的子系统装配成一个完整的系统来测试。

在这个过程中不仅应该发现设计和编码的错误,还应该验证系统确实能提供需求说明书中指定的功能,

而且系统的动态特性也符合预定要求。

这个测试步骤中发现的往往是软件设计中的错误,也可能发现需求说明中的错误

验收测试

(确认测试)

验收测试把软件系统作为单一的实体进行测试,测试内容与系统测试基本类似,

但是它是在用户积极参与下进行的,而且可能主要使用实际数据(系统将来要处理的信息)进行测试。

验收测试的目的是验证系统确实能够满足用户的需要,在这个测试步骤中发现的往往是系统需求说明书中的错误

2.5,测试阶段的信息流

软件配置:包括需求说明书、设计说明书和源程序清单等; (2)测试配置,包括测试计划和测试方案。

测试方案:不仅仅是测试时使用的输入数据(称为测试用例),还应该包括每组输入数据预定要检验的功能,以及每组输入数据预期应该得到的正确输出。

测试配置软件配置的一个子集,最终交出的软件配置应该包括上述测试配置以及测试的实际结果和调试的记录。

比较测试得出的实际结果预期结果,如果两者不一致则很可能是程序中有错误。

(1)如果经常出现要求修改设计的严重错误,那么软件的质量和可靠性是值得怀疑的,应该进一步仔细测试。
(2)如果看起来软件功能完成得很正常,遇到的错误也很容易改正,则仍然应该考虑两种可能:(1)软件的可靠性是可以接受的;(2)所进行的测试尚不足以发现严重的错误。
(3)如果一个错误也没有被发现,则很可能是因为对测试配置思考不充分,以致不能暴露软件中潜藏的错误。

软件可靠性模型使用错误率数据估计将来出现错误的情况,并进而对软件可靠性进行预测。

3,单元测试

单元测试是一种小粒度的测试,用以测试某个功能或代码块。单元测试即可由程序开发者来完成,也可由专业的软件测试人员来完成。由于单元测试属于难度较大的白盒测试,往往需要知道程序内部的设计和编码的细节才能进行测试,因此该部分主要由开发人员测试。

单元测试对象:结构化编程语言中的函数;面向对象编程语言中的接口、类和对象;

单元测试的特点:

  • 单元测试集中检测软件设计的最小单元——模块
  • 单元测试和编码属于软件过程的同一个阶段。
  • 在源程序代码通过编译程序的语法检查后,可以用详细设计描述作指南,对重要的执行通路进行测试,以便发现模块内部的错误。
  • 可以应用人工测试和计算机测试这样两种不同类型的测试方法,完成单元测试工作。
  • 单元测试主要使用白盒测试技术,而且对多个模块的测试可以并行地进行。

单元测试的意义:

  • 提高开发效率:借助专业的测试框架,单元测试能以自动化方式执行,从而提高开发者开发、测试的执行效率。
  • 提高软件代码质量:单元测试使用小成本发布、集成,有利于开发人员实时除错,同时引入系统重构理念,从而使代码具有更高的可扩展性。
  • 提升系统的可信赖度:单元测试可作为一种回归测试,支持在修复或更正后进行“回归测试”,从而确保代码的正确性。

3.1,测试重点

模块接口 参数的数目、次序、属性或单位系统与变元是否一致。
是否修改了只作输入用的变元。
全局变量的定义和用法在各个模块中是否一致。

局部数据模块

对于模块来说,局部数据结构是常见的错误来源。应该仔细设计测试方案,以便发现局部数据说明、初始化、默认值等方面的错误。

重要的执行通路

由于通常不可能进行穷尽测试,因此,在单元测试期间选择最有代表性、最可能发现错误的执行通路进行测试是十分关键的。应该设计测试方案用来发现由于错误的计算、不正确的比较或不适当的控制流而造成的错误。

出错处理通路

好的设计应该能预见出现错误的条件,并且设置适当的处理错误的通路。不仅应该在程序中包含出错处理通路,而且应该认真测试这种通路。
边界条件 边界测试是单元测试中最后的也可能是最重要的任务。
软件常常在它的边界上失效,例如,处理n元数组的第n个元素时,往往会发生错误。
使用刚好小于、刚好等于和刚好大于最大值或最小值的数据结构、控制量和数据值的测试方案,非常可能发现软件中的错误。

3.2,方法一:代码审查

代码检查是指由审查小组正式对源程序进行人工测试。它是一种非常有效的程序验证技术,对于典型的程序来说,可以查出30%~70%的逻辑设计错误和编码错误。

审查小组:组长(很有能力的程序员,而且没有直接参与这项工程),程序设计者,程序编写者,程序测试者。

审查过程:在审查会上由程序的编写者解释他是怎样用程序代码实现设计的,通常是逐个语句地讲述程序的逻辑,小组其他成员仔细倾听他的讲解,并力图发现其中的错误。审查会上需要对照程序设计常见错误清单,分析审查这个程序。当发现错误时由组长记录下来,审查会继续进行(审查小组的任务是发现错误而不是改正错误)。

在大多数情况下,通过向程序员提出关于他的程序的逻辑和他编写程序时所做的假设的疑问,可以发现的错误比由测试方案直接发现的错误还多。

代码审查比计算机测试优越的是:一次审查会上可以发现许多错误;用计算机测试的方法发现错误之后,通常需要先改正这个错误才能继续测试,即:采用代码审查的方法可以减少系统验证的总工作量。

人工测试和计算机测试是互相补充,相辅相成的,缺少其中任何一种方法都会使查找错误的效率降低。

3.3,方法二:计算机测试

模块不是一个独立的程序,因此必须为每个单元测试开发驱动软件和(或)存根软件。

驱动程序是一个“主程序”,它接收测试数据,把这些数据传送给被测试的模块,并且印出有关的结果。

存根程序代替被测试的模块所调用的模块,它使用被它代替的模块的接口,可能做最少量的数据操作,印出对入口的检验或操作结果,并且把控制归还给调用它的模块。

驱动程序和存根程序代表开销,也就是说为了进行单元测试必须编写测试软件,但是通常并不把它们作为软件产品的一部分交给用户。

模块的内聚程度高可以简化单元测试过程。如果每个模块只完成一种功能,则需要的测试方案数目将明显减少,模块中的错误也更容易预测和发现。

4,集成测试

集成测试是测试和组装软件的系统化技术。

非渐增式测试:先分别测试每个模块,再把所有模块按设计要求放在一起结合成所要的程序。

渐增式测试:下一个要测试的模块同已经测试好的那些模块结合起来进行测试,测试完以后再把下一个应该测试的模块结合进来测试。实际上同时完成单元测试和集成测试。

非渐增式测试把所有模块放在一起,作为一个整体来测试。测试时会遇到许多的错误,改正错误非常困难,因为在庞大的程序中想要诊断定位一个错误非常困难,而且改正一个错误之后,马上又会遇到新的错误,这个过程会继续下去,没有尽头。

渐增式测试与“一步到位”的非渐增式测试相反,它把程序划分成小段来构造和测试,在这个过程中比较容易定位和改正错误;对接口可以进行更彻底的测试;可以使用系统化的测试方法。因此,目前在进行集成测试时普遍采用渐增式测试方法。

4.1,渐增式测试-自顶向下

自顶向下集成方法是从主控制模块开始,沿着程序的控制层次向下移动,逐渐把各个模块结合起来。在把附属于(及最终附属于)主控制模块的那些模块组装到程序结构中去时,或者使用深度优先的策略,或者使用宽度优先的策略。

  • 深度优先的结合方法先组装在软件结构的一条主控制通路上的所有模块。选择一条主控制通路取决于应用的特点,并且有很大任意性。
  • 宽度优先的结合方法是沿软件结构水平地移动,把处于同一个控制层次上的所有模块组装起来。

使用深度优先的结合方法,选取左通路,首先结合模块M1,M2和M5;其次,M8或M6(如果为了使M2具有适当功能需要M6)将被结合进来。然后构造中央的和右侧的控制通路。使用宽度优先的结合方法,首先结合模块M2\,M3和M4(代替存根程序S4),然后结合下一个控制层次中的模块M5\,M6和M7;如此继续进行下去,直到所有模块都被结合进来为止。

模块结合进软件结构的具体过程由下述4个步骤完成:

  • ① 对主控制模块进行测试,测试时用存根程序代替所有直接附属于主控制模块的模块;
  • ② 根据选定的结合策略(深度优先或宽度优先),每次用一个实际模块代换一个存根程序(新结合进来的模块往往又需要新的存根程序);
  • ③ 在结合进一个模块的同时进行测试;
  • ④ 为了保证加入模块没有引进新的错误,可能需要进行回归测试(即全部或部分地重复以前做过的测试)。
  • 从②开始不断地重复进行上述过程,直到构造起完整的软件结构为止。

自顶向下的结合策略能够在测试的早期对主要的控制或关键的抉择进行检验。在一个分解得好的软件结构中,关键的抉择位于层次系统的较上层,因此首先碰到。
如果选择深度优先的结合方法,可以在早期实现软件的一个完整的功能并且验证这个功能
在自顶向下测试的初期,存根程序代替了低层次的模块,因此,在软件结构中没有重要的数据自下往上流。为了解决这个问题,测试人员有两种选择:①把许多测试推迟到用真实模块代替了存根程序以后再进行;②从层次系统的底部向上组装软件。

  • 4.2,渐曾式测试-自底向上

自底向上测试从“原子”模块(即在软件结构最低层的模块)开始组装和测试。因为是从底部向上结合模块,总能得到所需的下层模块处理功能,所以不需要存根程序。

用下述步骤可以实现自底向上的结合策略。

  • ① 把低层模块组合成实现某个特定的软件子功能的族;

  • ② 写一个驱动程序(用于测试的控制程序),协调测试数据的输入和输出;

  • ③ 对由模块组成的子功能族进行测试;

  • ④ 去掉驱动程序,沿软件结构自下向上移动,把子功能族组合起来形成更大的子功能族。

上述第②~④步实质上构成了一个循环。

4.3,不同集成测试策略的比较

自顶向下测试方法的主要优点:不需要测试驱动程序,能够在测试阶段的早期实现并验证系统的主要功能,而且能在早期发现上层模块的接口错误。
自顶向下测试方法的主要缺点:需要存根程序,可能遇到与此相联系的测试困难,低层关键模块中的错误发现较晚,而且用这种方法在早期不能充分展开人力。
自底向上测试方法的优缺点与上述自顶向下测试方法的优缺点刚好相反。

改进的自顶向下测试方法:基本上使用自顶向下的测试方法,但是在早期使用自底向上的方法测试软件中的少数关键模块。一般的自顶向下方法所具有的优点在这种方法中也都有,而且能在测试的早期发现关键模块中的错误;但是,它的缺点也比自顶向下方法多一条,即测试关键模块时需要驱动程序。

混合法:对软件结构中较上层使用的自顶向下方法与对软件结构中较下层使用的自底向上方法相结合。这种方法兼有两种方法的优点和缺点,当被测试的软件中关键模块比较多时,这种混合法可能是最好的折衷方法。

4.4,回归测试

在集成测试过程中,每当一个新模块结合进来时,程序就发生了变化:建立了新的数据流路径,可能出现了新的I/O操作,激活了新的控制逻辑。在集成测试的范畴中,回归测试是指重新执行已经做过的测试的某个子集,以保证上述这些变化没有带来非预期的副作用。
回归测试就是用于保证由于调试或其他原因引起的变化,不会导致非预期的软件行为或额外错误的测试活动。
回归测试可以通过人工地进行,也可以使用自动化的捕获回放工具自动进行。利用捕获回放工具,软件工程师能够捕获测试用例和实际运行结果,然后可以回放(即重新执行测试用例),并且比较软件变化前后所得到的运行结果。

测试用例:

(1)检测软件全部功能的代表性测试用例。
(2)专门针对可能受修改影响的软件功能的附加测试。
(3)针对被修改过的软件成分的测试。

在集成测试过程中,回归测试用例的数量可能变得非常大。因此,应该把回归测试集设计成只包括可以检测程序每个主要功能中的一类或多类错误的那样一些测试用例。

5,系统测试

系统测试不严格的讲可以叫做功能测试,它是一种典型的黑盒测试。系统测试主要值在模拟运行环境下,运用黑盒测试的方法,检验被测试系统是否满足需求规格说明书中列出的要求。

系统测试将经过集成测试的子系统装配成一个完整的系统来进行测试,用于检验系统是否满足确实能提供需求规格说明书中所要求的功能。系统测试的目的是对最终的软件产品进行全面的测试,以确定软件产品是否满足用户需求。

系统测试的主要内容:

  • 功能测试:测试软件系统的功能是否完备,其依据是需求文档(产品需求规格说明书)等。对于一个产品而言,保证其满足客户所需功能是最基本的要求,因此功能测试必不可少。
  • 健壮性测试:测试软件系统在异常情况下能否正常运行。健壮性有两层含义,一是系统的容错能力;二是系统的自恢复能力。
  • 性能测试:测试软件系统处理事务的速度,尤其是在多用户并发条件下的响应速度。性能测试一方面是为了测试软件性能能否符合需求;另一方面是为了得到某些性能数据供人们参考(例如作为宣传资料)。
  • 用户界面测试:主要测试软件系统的易用性和视觉效果等。
  • 安全性测试:测试软件系统防止非法入侵的能力。“安全”是相对而言的,一般地,如果黑客为非法入侵花费的代价(考虑时间、费用、危险等因素)高于得到的好处,那么这样的系统可以被认为是安全的。
  • 安装与卸载测试。

系统测试的结果:

  • 系统测试计划。
  • 系统测试用例。
  • 同测试报告。
  • 缺陷管理报告。

系统测试的成员:

  • 公司内独立的测试部门。
  • 被邀请参与系统测试的其他项目组的开发人员。
  • 本项目组的部分开发人员。
  • 公司内的质量保证人员。

6,确认测试

确认测试也称为验收测试,它的目标是验证软件的有效性。

验收测试对应软件开发的需求分析阶段。
验证指的是保证软件正确地实现了某个特定要求的一系列活动;确认指的是为了保证软件确实满足了用户需求而进行的一系列活动。

软件有效性的一个简单定义是:如果软件的功能和性能如同用户所合理期待的那样,软件就是有效的。
需求分析阶段产生的软件需求规格说明书,准确地描述了用户对软件的合理期望,因此是软件有效性的标准,也是进行确认测试的基础。

6.1,确认测试的范围

确认测试必须有用户积极参与,或以用户为主进行。用户应该参与设计测试方案,使用用户界面输入测试数据并且分析评价测试的输出结果。

确认测试通常使用黑盒测试法。应该仔细设计测试计划和测试过程,测试计划包括要进行的测试的种类及进度安排,测试过程规定了用来检测软件是否与需求一致的测试方案。

通过测试和调试要保证软件能满足所有功能要求,能达到每个性能要求,文档资料是准确而完整的,此外,还应该保证软件能满足其他预定的要求(例如安全性、可移植性、兼容性和可维护性等)。

确认测试有下述两种可能的结果:

(1)功能和性能与用户要求一致,软件是可以接受的。

(2)功能和性能与用户要求有差距。

6.2,软件配置复查

软件配置复查是确认测试的一个重要内容。复查的目的是保证软件配置的所有成分都齐全,质量符合要求,文档与程序完全一致,具有完成软件维护所必须的细节,而且已经编好目录。

除了按合同规定的内容和要求,由人工审查软件配置之外,在确认测试过程中还应该严格遵循用户指南及其他操作程序,以便检验这些使用手册的完整性和正确性。必须仔细记录发现的遗漏或错误,并且适当地补充和改正。

6.3,Alpha测试和Beta测试

Alpha测试Beta测试的过程,来发现那些看起来只有最终用户才能发现的错误。

Alpha测试 Beta测试
由用户在开发者的场所进行,并且在开发者对用户的“指导”下进行测试。
开发者负责记录发现的错误和使用中遇到的问题。
由软件的最终用户们在一个或多个客户场所进行。
与Alpha测试不同,开发者通常不在Beta测试的现场。
在受控的环境中进行的
开发者不能控制的环境中的“真实”应用
内测 公测

7,白盒测试

测试用例:把测试数据和预期的输出结果。不同的测试数据发现程序错误的能力差别很大,为了提高测试效率降低测试成本,应该选用高效的测试数据。因为不可能进行穷尽的测试,所以选用少量“最有效的”测试数据,做到尽可能完备的测试就更重要了。

设计测试方案的基本目标是,确定一组最可能发现某个错误或某类错误的测试数据。已经研究出许多设计测试数据的技术,这些技术各有优缺点;同一种技术在不同的应用场合效果可能相差很大,因此,通常需要联合使用多种设计测试数据的技术。

7.1,逻辑覆盖测试

逻辑覆盖是对一系列测试过程的总称,这组测试过程逐渐进行越来越完整的通路测试。

1,语句覆盖:选择足够多的测试数据,使被测程序中每个语句至少执行一次。

程序的执行路径应该是sacbed。只需两个判定表达式(A>1)AND(B=0)和(A=2)OR(X>1)都取真值。

语句覆盖对程序的逻辑覆盖很少,在上面例子中两个判定条件都只测试了条件为真的情况,如果条件为假时处理有错误,显然不能发现。语句覆盖是很弱的逻辑覆盖标准。

2,判定覆盖(分支覆盖):不仅每个语句必须至少执行一次,而且每个判定的每种可能的结果都应该至少执行一次,也就是每个判定的每个分支都至少执行一次。

程序的执行路径应该是① A=3,B=0,X=3 (覆盖sacbd) ② A=2,B=1,X=1 (覆盖sabed)

判定覆盖比语句覆盖强,但是对程序逻辑的覆盖程度仍然不高,上面的测试数据只覆盖了程序全部路径的一半。

3,条件覆盖:不仅每个语句至少执行一次,而且使判定表达式中的每个条件都取到各种可能的结果。

程序的执行路径应该是① A=2,B=0,X=4(满足A>1,B=0,A=2和X>1,执行路径sacbed) ② A=1,B=1,X=1(满足A≤1,B≠0,A≠2和X≤1,执行路径sabd)

条件覆盖通常比判定覆盖强,但满足条件覆盖的测试数据不一定满足判定覆盖。

4,判定条件覆盖:选取足够多的测试数据,使得判定表达式中的每个条件都取到各种可能的值,而且每个判定表达式也都取到各种可能的结果。

程序的执行路径应该是① A=2,B=0,X=4(满足A>1,B=0,A=2和X>1,执行路径sacbed) ② A=1,B=1,X=1(满足A≤1,B≠0,A≠2和X≤1,执行路径sabd)

但是,这两组测试数据也就是为了满足条件覆盖标准最初选取的两组数据,因此,有时判定/条件覆盖也并不比条件覆盖更强。

5,条件组合覆盖:是更强的逻辑覆盖标准,它要求选取足够多的测试数据,使得每个判定表达式中条件的各种可能组合都至少出现一次。

对于上例,共有8种可能的条件组合,它们分别是:

  • ① A=2,B=0,X=4(针对(1)和(5),执行路径sacbed)
  • ② A=2,B=1,X=1(针对(2)和(6),执行路径sabed)
  • ③ A=1,B=0,X=2(针对(3)和(7),执行路径sabed)
  • ④ A=1,B=1,X=1(针对(4)和(8),执行路径sabd)

满足条件组合覆盖标准的测试数据,也一定满足判定覆盖、条件覆盖和判定/条件覆盖标准。

条件组合覆盖是前述几种覆盖标准中最强的。但是,满足条件组合覆盖标准的测试数据并不一定能使程序中的每条路径都执行到,例如,上述4组测试数据都没有测试到路径sacbd。

6,点覆盖:如果连通图G的子图G′是连通的,而且包含G的所有结点,则称G′是G的点覆盖。

满足点覆盖标准要求选取足够多的测试数据,使得程序执行路径至少经过流图的每个结点一次,由于流图的每个结点与一条或多条语句相对应,显然,点覆盖标准和语句覆盖标准是相同的

7,边覆盖:如果连通图G的子图G″是连通的,而且包含G的所有边,则称G″是G的边覆盖。为了满足边覆盖的测试标准,要求选取足够多测试数据,使得程序执行路径至少经过流图中每条边一次。通常边覆盖和判定覆盖是一致的

8,路径覆盖:选取足够多测试数据,使程序的每条可能路径都至少执行一次(如果程序图中有环,则要求每个环至少经过一次)。

7.2,控制结构测试

1,基本路径测试是一种白盒测试技术。使用基本路径测试设计测试用例时,首先计算程序的环形复杂度,并用该复杂度为指南定义执行路径的基本集合,从该基本集合导出的测试用例可以保证程序中的每条语句至少执行一次,而且每个条件在执行时都将分别取真、假两种值。

① 根据过程设计结果画出相应的流图。

为了用基本路径测试技术测试下列的用PDL描述的求平均值过程,首先画出下图所示的流图。注意,为了正确地画出流图,这里把被映射为流图结点的PDL语句编了序号。

② 计算流图的环形复杂度。

环形复杂度定量度量程序的逻辑复杂性,按照详细设计的三个计算方法计算。

③ 确定线性独立路径的基本集合。

独立路径是指至少引入程序的一个新处理语句集合或一个新条件的路径,即独立路径至少包含一条在定义该路径之前不曾用过的边。

程序的环形复杂度决定了程序中独立路径的数量,而且这个数是确保程序中所有语句至少被执行一次所需的测试数量的上界。

上述程序的环形复杂度为6,因此共有6条独立路径。

  • 路径1:1-2-10-11-13
  • 路径2:1-2-10-12-13
  • 路径3:1-2-3-10-11-13
  • 路径4:1-2-3-4-5-8-9-2-…
  • 路径5:1-2-3-4-5-6-8-9-2-…
  • 路径6:1-2-3-4-5-6-7-8-9-2-…

④ 设计可强制执行基本集合中每条路径的测试用例。

应该选取测试数据使得在测试每条路径时都适当地设置好各个判定结点的条件。

2,条件测试

条件测试技术设计出的测试用例,能够检查程序模块中包含的逻辑条件。

条件成分的类型包括布尔算符、布尔变量、布尔括弧(括住简单条件或复合条件)、关系算符及算术表达式。

条件测试方法着重测试程序中的每个条件。条件测试策略有两个优点: ①容易度量条件的测试覆盖率; ②程序内条件的测试覆盖率可指导附加测试的设计。

条件测试的目的不仅是检测程序条件中的错误,而且是检测程序中的其他错误。如果程序P的测试集能有效地检测P中条件的错误,则它很可能也可以有效地检测P中的其他错误。

3,循环测试:是一种白盒测试技术,它专注于测试循环结构的有效性。在结构化的程序中通常只有3种循环,即简单循环、串接循环和嵌套循环。

(1)简单循环: 应该使用下列测试集来测试简单循环,其中n是允许通过循环的最大次数。跳过循环。只通过循环一次。通过循环两次。通过循环m次,其中m<n-1。通过循环n-1,n,n+1次。

(2)嵌套循环:如果把简单循环的测试方法直接应用到嵌套循环,测试数就会随嵌套层数的增加按几何级数增长,B.Beizer提出了一种能减少测试数的方法。跳过循环。

  1. 从最内层循环开始测试,把所有其他循环都设置为最小值。
  2. 对最内层循环使用简单循环测试方法,而使外层循环的迭代参数(例如,循环计数器)取最小值,并为越界值或非法值增加一些额外的测试。
  3. 由内向外,对下一个循环进行测试,但保持所有其他外层循环为最小值,其他嵌套循环为“典型”值。
  4. 继续进行下去,直到测试完所有循环。

(3)串接循环:如果串接循环的各个循环都彼此独立,则可以使用前述的测试简单循环的方法来测试串接循环。但是,如果两个循环串接,而且第一个循环的循环计数器值是第二个循环的初始值,则这两个循环并不是独立的。当循环不独立时,建议使用测试嵌套循环的方法来测试串接循环。

8,黑盒测试

黑盒测试着重测试软件功能。黑盒测试并不能取代白盒测试,它是与白盒测试互补的测试方法,它很可能发现白盒测试不易发现的其他类型的错误。

黑盒测试力图发现下述类型的错误: (1) 功能不正确或遗漏了功能;(2) 界面错误;(3) 数据结构错误或外部数据库访问错误;(4) 性能错误;(5) 初始化和终止错误。

应用黑盒测试技术,能设计出满足下述标准的测试用例集。

(1)所设计出的测试用例能够减少为达到合理测试所需要设计的测试用例的总数。

(2)所设计出的测试用例能够告诉人们,是否存在某些类型的错误,而不是仅仅指出与特定测试相关的错误是否存在。

8.1,等价划分

等价划分把程序的输入域划分成若干个数据类,据此导出测试用例。等价划分法力图设计出能发现若干类程序错误的测试用例,从而减少必须设计的测试用例的数目。

每类中的一个典型值在测试中的作用与这一类中所有其他值的作用相同。因此,可以从每个等价类中只取一组数据作为测试数据。这样选取的测试数据最有代表性,最可能发现程序中的错误。

使用等价划分法设计测试方案首先需要划分输入数据的等价类,为此需要研究程序的功能说明,从而确定输入数据的有效等价类和无效等价类。

划分等价类需要经验,下述的启发式规则可能有助于等价类划分。
(1) 如果规定了输入值的范围,则可划分出一个有效的等价类(输入值在此范围内),两个无效的等价类(输入值小于最小值或大于最大值)。
(2) 如果规定了输入数据的个数,则类似地也可以划分出一个有效的等价类和两个无效的等价类。
(3) 如果规定了输入数据的一组值,而且程序对不同输入值做不同处理,则每个允许的输入值是一个有效的等价类,此外还有一个无效的等价类(任一个不允许的输入值)。
(4) 如果规定了输入数据必须遵循的规则,则可以划分出一个有效等价类(符合规则)和若干个无效等价类(从各种不同角度违反规则)。
(5) 如果规定了输入数据为整型,则可以划分出正整数、零和负整数3个有效类。
(6) 如果程序的处理对象是表格,则应该使用空表,以及含一项或多项的表。

划分出等价类以后,根据等价类设计测试方案时主要使用下面两个步骤

  • 设计一个新的测试方案以尽可能多地覆盖尚未被覆盖的有效等价类,重复这一步骤直到所有有效等价类都被覆盖为止。
  • 设计一个新的测试方案,使它覆盖一个而且只覆盖一个尚未被覆盖的无效等价类,重复这一步骤直到所有无效等价类都被覆盖为止。

注意,通常程序发现一类错误后就不再检查是否还有其他错误,因此,应该使每个测试方案只覆盖一个无效的等价类。

8.2,边界值分析

使用边界值分析方法设计测试方案首先应该确定边界情况,通常输入等价类和输出等价类的边界。选取的测试数据应该刚好等于、刚刚小于和刚刚大于边界值。

经验表明,处理边界情况时程序最容易发生错误。例如,许多程序错误出现在下标、纯量、数据结构和循环等等的边界附近。因此,设计使程序运行在边界情况附近的测试方案,暴露出程序错误的可能性更大一些。

通常设计测试方案时总是联合使用等价划分边界值分析两种技术

8.3,错误推测

错误推测法在很大程度上靠直觉和经验进行。它的基本想法是列举出程序中可能有的错误和容易发生错误的特殊情况,并且根据它们选择测试方案。

应该仔细分析程序规格说明书,注意找出其中遗漏或省略的部分,以便设计相应的测试方案,检测程序员对这些部分的处理是否正确。

经验表明,在一段程序中已经发现的错误数目往往和尚未发现的错误数成正比。

等价划分法和边界值分析法都只孤立地考虑各个输入数据的测试功效,而没有考虑多个输入数据的组合效应,可能会遗漏了输入数据易于出错的组合情况。

选择输入组合的一个有效途径是利用判定表或判定树为工具,列出输入数据各种组合与程序应作的动作(及相应的输出结果)之间的对应关系,然后为判定表的每一列至少设计一个测试用例。

选择输入组合的另一个有效途径是把计算机测试和人工检查代码结合起来。

9,调试

调试(也称为纠错)作为成功测试的后果出现,即调试是在测试发现错误之后排除错误的过程。
软件错误的外部表现和它的内在原因之间可能并没有明显的联系。调试就是把症状和原因联系起来的尚未被人深入认识的智力过程。

9.1,调试过程

调试过程从执行一个测试用例开始,评估测试结果,如果发现实际结果与预期结果不一致,则这种不一致就是一个症状,它表明在软件中存在着隐藏的问题。调试过程试图找出产生症状的原因,以便改正错误。

调试过程总会有以下两种结果之一: ①找到了问题的原因并把问题改正和排除掉了; ②没找出问题的原因。在后一种情况下,调试人员可以猜想一个原因,并设计测试用例来验证这个假设,重复此过程直至找到原因并改正了错误。

9.2,调试途径

1,蛮干法

蛮干法可能是寻找软件错误原因的最低效的方法。仅当所有其他方法都失败了的情况下,才应该使用这种方法。

蛮干法按照“让计算机自己寻找错误”的策略,这种方法印出内存的内容,激活对运行过程的跟踪,并在程序中到处都写上WRITE(输出)语句,希望在这样生成的信息海洋的某个地方发现错误原因的线索。
在更多情况下这样做只会浪费时间和精力。在使用任何一种调试方法之前,必须首先进行周密的思考,必须有明确的目的,应该尽量减少无关信息的数量。

2,回溯法

回溯是一种相当常用的调试方法,当调试小程序时这种方法是有效的。具体做法:从发现症状的地方开始,人工沿程序的控制流往回追踪分析源程序代码,直到找出错误原因为止。
随着程序规模的扩大,应该回溯的路径数目变得越来越大,回溯法不适用于这种规模的程序。

3,原因排错法

对分查找法的基本思路是,如果已经知道每个变量在程序内若干个关键点的正确值,则可以用赋值语句或输入语句在程序中点附近“注入”这些变量的正确值,然后运行程序并检查所得到的输出。

归纳法是从个别现象推断出一般性结论的思维方法。使用这种方法调试程序时,首先把和错误有关的数据组织起来进行分析,以便发现可能的错误原因。然后导出对错误原因的一个或多个假设,并利用已有的数据来证明或排除这些假设。

演绎法从一般原理或前提出发,经过排除和精化的过程推导出结论。采用这种方法调试程序时,首先设想出所有可能的出错原因,然后试图用测试来排除每一个假设的原因。

9.3,软件可靠性和可用性

软件可靠性是程序在给定的时间间隔内,按照规格说明书的规定成功地运行的概率软件可靠性随着给定的时间间隔的加大而减少。

软件可用性是程序在给定的时间点,按照规格说明书的规定,成功地运行的概率。

可靠性和可用性之间的主要差别:可靠性意味着在0到t这段时间间隔内系统没有失效,而可用性只意味着在时刻t,系统是正常运行的。

软件工程:编码和测试相关推荐

  1. 软件工程——编码、测试、维护

    一.编码 (一)选择语言 任何一种语言都不是"十全十美"的,因此,在选择程序设计语言时,首先明确求解的问题对编码有什么要求,并把它们按轻重次序一一列出.然后根据这些要求去衡量可使用 ...

  2. 软件工程编码阶段_软件工程的编码阶段

    软件工程编码阶段 The coding phase in the software engineering paradigm is usually defined after the designin ...

  3. http协议里的chunked编码与测试

    http协议里的chunked编码与测试 如果有写过http下载的人,或多或少了解一点chunked编码的传输方式.例如笔者最初不知道这个http传输方式,以前能行的代码有一天就突然不行了,抓包才发现 ...

  4. 如何构建一个ERP系统(需求分析、系统架构、系统设计、系统编码、测试、交付程序及文文件)。

    如何构建一个ERP系统(需求分析.系统架构.系统设计.系统编码.测试.交付程序及相关文件).  ERP 系统 _ 需求分析: 一般 ERP 系统的功能是非常繁多的,既包括财务会计. OA .进销存等几 ...

  5. 职言 | 编码是测试自动化职业生涯的关键:你准备好了吗?

    Verily Life Sciences是一家健康管理公司,前身为Google Life Sciences.2015年,谷歌改组为Alphabet,业务调整之后,谷歌原有的健康业务分离出来.同一年,G ...

  6. 提高C++性能的编程技术笔记:编码优化+测试代码

    缓存:在现代处理器中,缓存经常与处理器中的数据缓存和指令缓存联系在一起.缓存主要用来存储使用频繁而且代价高昂的计算结果,这样就可以避免对这些结果的重复计算.如,循环内对常量表达式求值是一种常见的低性能 ...

  7. 现代软件工程讲义 9 测试 QA 的角色和分工

    测试的角色 (Test) 要独立出来么 ? 独立出来的测试角色怎么才能发挥作用? 有些成功人士和成功的公司号称没必要有独立的测试角色 (Test), 你怎么看? 最近又看到一些关于开发人员要不要负责测 ...

  8. python Excel 乱码 解决方案 编码 xlwings测试

    win764位系统,python2.7(arcgis10.7自带的), excel2010 今天用xlwings向Excel中添加数据,打开Excel发现中文是乱码,经过测试找到原因,是本py文件调用 ...

  9. 解决java中文乱码,编码识别测试,汇总

    1.手机显示中文:GBK,UTF-8正常,ISO-8859-1乱码. 2.写入内容到txt:UTF-8转GBK,直接stream.write(str.getBytes(StrCharset.GBK)) ...

最新文章

  1. List 如何根据对象的属性去重?Java 8 轻松搞定!
  2. ROS-kinetic 机器语音 之科大讯飞SDK
  3. springcloud——eureka小错误Caused by: java.net.UnknownHostException: eureka7003.com
  4. 动态规划(0-1背包)--- 改变一组数的正负号使得它们的和为一给定数
  5. 最全面试考点与面试技巧,大厂面经合集
  6. QT中DirectShowPlayerService::doSetUrlSource: Unresolved error code 0x80040216 ()问题的解决
  7. 2019年7月第一周总结-RabbitMQ总结
  8. Zabbix分布式监控(zabbix-proxy)的配置关键点
  9. cURL(wget)—— 测试 RESTful 接口及模拟 GET/POST/PUT/DELETE/OPTIONS 请求
  10. wap建站程序源码_角点科技:企业搭建网站选择建站公司需要注意什么?
  11. 【9933】单词的划分
  12. Boss说:你要是能搞懂这六个分布式技术栈,我给你薪资翻倍
  13. python输入的光标变成了横线_光标变成下划线
  14. 2021年美容师(高级)考试及美容师(高级)考试题
  15. 私有化短链接管理系统-魔众短链接系统 v1.0.0
  16. HTML 5:绘制旋转的太极图
  17. Glide 入门到精通之四——图片缩放和调整大小
  18. 14个适合后台管理系统快速开发的前端框架
  19. 采样坦克4音色编辑器-SampleTank Editor v4.0.0 WiN-MAC
  20. linux ip1180,Fedora Ubuntu 成功安装 佳能 ip1180 打印机驱动

热门文章

  1. Avfoundation 相机指定裁剪区域
  2. URL Schemes 的发展
  3. 如何零基础转行成为一个自信的前端达人
  4. 面试当中必考的数据结构---树种类大全和相关优秀博客总结
  5. 网站服务器过载,服务器过载保护
  6. 如何制作条形码报表(盈帆报表:efreprt.com)
  7. keil编译报错找不到core_cm3.h文件
  8. node.js学习笔记之简洁聊天室
  9. Iron WebScraper 网络爬虫
  10. 怎么通过django模板输出双花括号{{}}