第七章、 实现.ppt
《第七章、 实现.ppt》由会员分享,可在线阅读,更多相关《第七章、 实现.ppt(144页珍藏版)》请在麦多课文档分享上搜索。
1、第七章、 实现,编码和测试统称为实现 编码 测试,2,7.1 编码,所谓编码就是把软件设计的结果翻译成计算机可以“理解”的形式用某种程序设计语言书写的程序。 程序设计语言的特性和编码途径会对程序的可靠性、可读性、可测试性和可维护性产生深远的影响。,3,7.1 编码,汇编语言的语句和计算机硬件操作有一一对应关系。 高级语言使用的概念和符号与人们通常使用的概念和符号比较接近,它的一个语句往往对应若干条机器指令。 程序员在相同时间可以写出的汇编语言语句和高级语言语句数目是相同的,因此在选择语言时,采用高级语言的效率要比汇编语言高。 汇编语言适用范围 对程序执行时间和利用的空间有很严格限制的情况。 需
2、要产生任意的甚至非法的指令序列。 体系结构特殊的处理机,在这类机器上不能实现高级语言编译程序。 大型系统中执行时间非常关键的(或直接依赖于硬件的)一小部分代码。,4,高级语言的理想标准,选用的高级语言应该有理想的模块化机制,以及可读性好的控制结构和数据结构。 语言特点应该使编译程序能够尽可能多地发现程序中的错误。 选用的语言应该有良好的独立编译机制。 选择高级语言的实用标准 系统用户的要求 如果所开发的系统由用户负责维护,用户通常要求用他们熟悉的语言书写程序。 可以使用的编译程序 运行目标系统的环境中可以提供的编译程序往往限制了可以选用的语言的范围。 可以得到的软件工具 如果某种语言有支持程序
3、开发的软件工具可以利用,则目标系统的实现和验证都变得比较容易。,5,工程规模 如果工程规模很庞大,现有的语言又不完全适用,那么设计并实现一种供这个工程项目专用的程序设计语言,可能是一个正确的选择。 程序员的知识 如果和其他标准不矛盾,那么应该选择一种已经为程序员所熟悉的语言。 软件可移植性要求 如果目标系统将在几台不同的计算机上运行,或者预期的使用寿命很长,那么选择一种标准化程度高、程序可移植性好的语言就是很重要的。 软件的应用领域 所谓的通用程序设计语言实际上并不是对所有应用领域都同样适用,因此,选择语言时应该充分考虑目标系统的应用范围。,6,7.1 .2 编码风格,源程序代码的逻辑简明清晰
4、、易读易懂是好程序的一个重要标准,为了做到这一点,应该遵循下述规则: 程序内部的文档(恰当的标识符、适当的注解和程序的视觉组织等 ) 恰当的标识符 选取含义鲜明的名字,使它能正确地提示程序对象所代表的实体。 如果使用缩写,那么缩写规则应该一致,并且应该给每个名字加注解。,7,一般的命名约定,有不少人编程时用拼音给函数或变量命名,这样做并不能说明你很爱国,却会让用此程序的人迷糊(很多南方人不懂拼音)。程序中的英文一般不会太复杂,用词要力求准确。 匈牙利命名法是Microsoft公司倡导的 Maguire 1993,虽然很烦琐,但用习惯了也就成了自然。没有人强迫你采用何种命名法,但有一点应该做到:
5、自己的程序命名必须一致。(1)宏定义用大写字母加下划线表示,如MAX_LENGTH; (2)函数用大写字母开头的单词组合而成,如SetName, GetName ; (3)指针变量加前缀p,如 *pNode ; (4)BOOL 变量加前缀b,如 bFlag ; (5)int 变量加前缀i,如 iWidth ; (6)float 变量加前缀f,如 fWidth ; (7)double变量加前缀d,如 dWidth ; (8)字符串变量加前缀str,如 strName ; (9)枚举变量加前缀e,如 eDrawMode ; (10)类的成员变量加前缀m_,如 m_strName, m_iWidth
6、 ;,8,适当的注解 通常在每个模块开始处有一段序言性的注解,简要描述模块的功能、主要算法、接口特点、重要数据以及开发简史。 插在程序中间与一段程序代码有关的注解,主要解释包含这段代码的必要性。 对于用高级语言书写的源程序,不需要用注解的形式把每个语句翻译成自然语言,应该利用注解提供一些额外的信息。 应该用空格或空行清楚地区分注解和程序。 程序的视觉组织 程序清单的布局对于程序的可读性也有很大影响,应该利用适当的阶梯形式使程序的层次结构清晰明显。,7.1 .2 编码风格,9,7.1 .2 编码风格,数据说明 数据说明的次序应该标准化(例如,按照数据结构或数据类型确定说明的次序)。 当多个变量名
7、在一个语句中说明时,应该按字母顺序排列这些变量。 如果设计时使用了一个复杂的数据结构,则应该用注解说明用程序设计语言实现这个数据结构的方法和特点。,10,7.1 .2 编码风格,语句构造 构造语句时应该遵循的原则是,每个语句都应该简单而直接,不能为了提高效率而使程序变得过分复杂。 不要为了节省空间而把多个语句写在同一行; 尽量避免复杂的条件测试; 尽量减少对“非”条件的测试; 避免大量使用循环嵌套和条件嵌套; 利用括号使逻辑表达式或算术表达式的运算次序清晰直观。,11,7.1 .2 编码风格,输入输出 对所有输入数据都进行检验; 检查输入项重要组合的合法性; 保持输入格式简单; 使用数据结束标
8、记,不要要求用户指定数据的数目; 明确提示交互式输入的请求,详细说明可用的选择或边界数值; 当程序设计语言对格式有严格要求时,应保持输入格式一致; 设计良好的输出报表; 给所有输出数据加标志。,12,7.1 .2 编码风格,效率 效率主要指处理机时间和存储器容量两个方面。 在讨论提高效率前,应该记住3条原则: 效率是性能要求,因此应该在需求分析阶段确定效率方面的要求。 效率是靠好设计来提高的。 程序的效率和程序的简单程度是一致的。不要牺牲程序的清晰性和可读性来不必要地提高效率。 从三个方面讨论程序效率的问题。,13,程序运行时间 写程序之前先简化算术的和逻辑的表达式; 仔细研究嵌套的循环,以确
9、定是否有语句可以从内层往外移; 尽量避免使用多维数组; 尽量避免使用指针和复杂的表; 使用执行时间短的算术运算; 不要混合使用不同的数据类型; 尽量使用整数运算和布尔表达式。 在效率是决定性因素的应用领域,尽量使用有良好优化特性的编译程序,以自动生成高效目标代码。,7.1 .2 编码风格,14,存储器效率 在大型计算机中必须考虑操作系统页式调度的特点,一般说来,使用能保持功能域的结构化控制结构,是提高效率的好方法。 在微处理机中如果要求使用最少的存储单元,则应选用有紧缩存储器特性的编译程序,在非常必要时可以使用汇编语言。 提高执行效率的技术通常也能提高存储器效率。提高存储器效率的关键同样是简单
10、。,7.1 .2 编码风格,15,3、输入输出效率 如果用户为了给计算机提供输入信息或为了理解计算机输出的信息,所需花费的脑力劳动是经济的,那么人和计算机通信的效率就高。因此,简单清晰同样是提高人机通信效率的关键。 硬件之间的通信效率比较复杂,但从写程序的角度看,有些简单原则可以提高输入输出效率: 所有输入输出都应该有缓存,以减少用于通信的额外开销。 对二级存储器应该选用最简单的访问方法。 二级缓存器的输入输出应该以信息组为单位进行。 如果“超高效的”输入输出很难被人理解,则不采用这种方法。,7.1 .2 编码风格,16,7.2 软件测试基础,测试的目的就是在软件投入生产运行之前,尽可能多地发
11、现软件中的错误。 目前软件测试仍然是保证软件质量的关键步骤。软件测试在软件生命周期中横跨两个阶段。 通常在编写出每个模块之后就对它做必要的测试(称为单元测试),模块的编写者和测试者是同一个人,编码和单元测试属于软件生命周期的同一个阶段。 对软件系统进行各种综合测试,通常由专门的测试人员承担这项工作。,17,7.2.1 软件测试的目标,测试的正确定义是“为了发现程序中的错误而执行程序的过程”。 测试只能查找出程序中的错误,不能证明程序中没有错误。 一般测试工作通常由非编码人员组成的小组来测试完成。,18,7.2.2 软件测试准则,所有测试都应该能追溯到用户需求 应该在测试前制定测试计划 把Par
12、eto原理应用到软件测试中 应该从“小规模”开始测试,逐步进行大规模测试。 穷举测试是不可能的 为了达到最佳的测试效果,应该由独立的第三方从事测试工作。,19,7.2.3 测试方法,黑盒测试法(功能测试)把程序看成一个黑盒子,完全不考虑程序的内部结构和处理过程。 黑盒测试是在程序接口进行的测试,它只检查程序功能是否能按照规格说明书的规定正常使用,程序是否能适当地接收输入数据产生正确的输出信息,并且保持外部信息的完整性。,20,7.2.3 测试方法,白盒测试法(结构测试)把程序看成装在一个透明的白盒子里,也就是完全了解程序的结构和处理过程。这种方法按照程序内部的逻辑测试程序,检验程序中的每条通路
13、是否都能按预定要求正确工作。,21,7.2.4软件测试的步骤,模块测试模块测试的目的是保证每个模块作为一个单元能正确运行,所以模块测试通常又称为单元测试。在这个测试步骤中所发现的往往是编码和详细设计的错误。,22,7.2.4 软件测试的步骤,子系统测试子系统测试是把经过单元测试的模块放在一起形成一个子系统来测试。模块相互间的协调和通信是这个测试过程中的主要问题,因此这个步骤着重测试模块的接口。,23,7.2.4 软件测试的步骤,系统测试系统测试是把经过测试的子系统装配成一个完整的系统来测试。在这个测试步骤中发现的往往是软件设计中的错误,也可能发现需求说明中的错误。 不论是子系统测试还是系统测试
14、,都兼有检测和组装两重含义,通常称为集成测试。,24,7.2.4 软件测试的步骤,验收测试验收测试的目的是验证系统确实能够满足用户的需要,在这个测试步骤中发现的往往是系统需求说明书中的错误。,25,7.2.4 软件测试的步骤,平行运行 所谓平行运行就是同时运行新开发出来的系统和将被它取代的旧系统,以便比较新旧两个系统的处理结果。 可以在准生产环境中运行新系统而又不冒风险; 用户能有一段熟悉新系统的时间; 可以验证用户指南和使用手册之类的文档; 能够以准生产模式对新系统进行全负荷测试,可以用测试结果验证性能指标。,26,7.2.5测试阶段的信息流,27,7.2.5 测试阶段的信息流,测试阶段的信
15、息流。输入信息有两类: 软件配置,包括需求说明书,设计说明书和源程序清单等; 测试配置,包括测试计划和测试方案。 所谓测试方案不仅仅是测试时使用的输入数据(称为测试用例),还应该包括每组输入数据预定要检验的功能,以及每组输入数据预期应该得到的正确输出。,28,7.3 单元测试,单元测试可以使用白盒测试法,而且对多个模块的测试可以并行地进行。在单元测试期间主要评价模块的下述五个特性。,29,1. 模块接口,首先应该对通过模块接口的数据流进行测试。在对接口进行测试时主要检查下述各点: 参数和(由调用模块送来的)变元的数目是否相等? 参数和(由调用模块送来的)变元的属性是否匹配? 参数和(由调用模块
16、送来的)变元的单位系统是否匹配? 是否修改了只做输入用的变元? 全程变量的定义和用法在各个模块中是否一致?,30,2. 局部数据结构,对于一个模块而言,局部数据结构是常见的错误来源。应该仔细设计测试方案,以便发现下述类型的错误: 错误的或不相容的说明; 使用尚未赋值或尚未初始化的变量; 错误的初始值或不正确的缺省值; 错误的变量名字(拼写错或截短了); 数据类型不相容; 上溢、下溢或地址异常。,31,3. 重要的执行通路,应该设计测试方案用来发现由于错误的计算、不正确的比较或不适当的控制流而造成的错误。 通常不可能进行群尽测试,因此,在单元测试期间选择最有代表性、最可能发现错误的执行通路进行测
17、试就是十分关键的。,32,3. 重要的执行通路,一些常见的错误: 比较数据类型不同的量; 逻辑运算符不正确或优先次序的错误; 当由于精度问题两个量不会相等时,程序中却期待着相等条件的出现; “差1”错(即,多循环一次或少循环一次); 错误的或不存在的循环终止条件; 当遇到发散的迭代时不能终止循环; 错误地修改循环变量。,33,4. 出错处理通路,当评价出错处理通路时,应该着重测试下述一些可能发生的错误: 对错误的描述是难于理解的; 记下的错误与实际遇到的错误不同; 在对错误进行处理之前,错误条件已经引起系统干预; 对错误的处理不正确; 描述错误的信息不足以帮助确定造成错误的位置。,34,5.
18、边界条件,边界测试是单元测试中最后的也可能是最重要的任务。 软件常常在它的边界上失效,例如,处理n元数组的第n个元素时,或做到i次循环中的第i次重复时,往往会发生错误。 使用刚好小于、刚好等于和刚好大于最大值或最小值的数据结构、控制量和数据值的测试方案,非常可能发现软件中的错误。,35,7.3.2 代码审查,人工测试源程序可以由编写者本人非正式地进行,也可以由审查小组正式进行。后者称为代码审查,它是一种非常有效的程序验证技术,对于典型的程序来说,可以查出30%70%的逻辑设计错误和编码错误。 审查小组最好由下述四人组成: 组长,他应该是一个很有能力的程序员,而且没有直接参与这项工程。 程序的设
19、计者。 程序的编写者。 程序的测试者。,36,7.3.3 计算机测试,模块并不是一个独立的程序,因此必须为每个单元测试开发驱动软件和(或)存根软件。 通常驱动程序也就是一个“主程序”,它接收测试数据,把这些数据传送给被测试的模块,并且印出有关的结果。 存根程序代替被测试的模块所调用的模块。因此存根程序也可以称为“虚拟子程序”。它使用被它代替的模块的接口,可能做最少量的数据操作,印出对入口的检验或操作结果,并且把控制归还给调用它的模块。,37,7.4 集成测试,集成测试是组装软件的系统技术,主要目标是发现与接口有关的问题。例如: 数据穿过接口时可能丢失; 一个模块对另一个模块可能有由于疏忽而造成
20、的有害影响; 把子功能组合起来可能不产生预期的主功能; 个别看来是可以接受的误差可能积累到不能接受的程度; 全程数据结构可能有问题等等。,38,模块组装成程序的方法,非渐增式测试方法: 是先分别测试每个模块,再把所有模块按设计要求放在一起结合成所要的程序。 渐增式测试方法: 是把下一个要测试的模块同已经测试好的那些模块结合起来进行测试,测试完以后再把下一个应该测试的模块结合进来测试。这种方法实际上同时完成单元测试和集成测试。,39,这两种方法哪种更好一些呢?,因为非渐增式测试方法分别测试每个模块,需要编写的测试软件通常比较多,所以需要的工作量比较大;渐增式的测试方法利用已测试过的模块作为部分测
21、试软件,因此开销比较小。 渐增式测试可以较早发现模块间的接口错误;非渐增式测试最后才把模块组装在一起,因此接口错误发现得晚。,40,这两种方法哪种更好一些呢?,非渐增式测试一下子把所有模块组合在一起,如果发现错误则较难诊断定位;反之,使用渐增式测试方法时,如果发生错误则往往和最近加进来的那个模块有关。 渐增式测试方法把已经测试好的模块和新加进来的那个模块一起测试,已测试好的模块可以在新的条件下受到新的检验,因此,这种方法对程序的测试更彻底。,41,这两种方法哪种更好一些呢?,渐增式测试需要较多的机器时间,这是因为测试每个模块时所有已经测试完的模块也都要跟着一起运行,当程序规模较大时增加的机器时
22、间是相当明显的。 使用非渐增式测试方法可以并行测试所有模块,因此能充分利用人力,加快工程进度。 总的说来,渐增式测试方法比较好。,42,7.4.1 自顶向下结合,自顶向下的结合方法是一个日益为人们广泛采用的组装软件的途径。 从主控制模块(“主程序”)开始,沿着软件的控制层次向下移动,从而逐渐把各个模块结合起来。 在把附属于(以及最终附属于)主控制模块的那些模块组装到软件结构中去时,或者使用深度优先的策略,或者使用宽度优先的策略。,43,自顶向下结合,44,自顶向下结合,深度优先的结合方法: 先组装在软件结构的一条主控制通路上的所有模块。 选择一条主控制通路取决于应用的特点,并且有很大任意性。
23、宽度优先的结合方法: 是沿软件结构水平地移动,把处于同一个控制层次上的所有模块组装起来。,45,把模块结合进软件结构的具体步骤,对主控制模块进行测试,测试时用存根程序代替所有直接附属于主控制模块的模块; 根据选定的结合策略(深度优先或宽度优先),每次用一个实际模块代换一个存根程序(新结合进来的模块往往又需要新的存根程序); 在结合进一个模块的同时进行测试; 为了保证加入模块没有引进新的错误,可能需要进行回归测试(即,全部或部分地重复以前做过的测试)。,46,自顶向下结合方法的优点,自顶向下的结合策略能够在测试的早期对主要的控制或关键的抉择进行检验。早期认识到这类问题是很有好处的。 如果选择深度
24、优先的结合方法,可以在早期实现软件的一个完整的功能并且验证这个功能。可以增强开发人员和用户双方的信心。,47,自底向上结合,自底向上测试从“原子”模块(即在软件结构最低层的模块)开始组装和测试。 因为是从底部向上结合模块,总能得到需要的下层模块处理功能,所以不需要存根程序。,48,自底向上结合策略的实现步骤,把低层模块组合成实现某个特定的软件子功能的族; 写一个驱动程序(用于测试的控制程序),协调测试数据的输入和输出; 对由模块组成的子功能族进行测试; 去掉驱动程序,沿软件结构自下向上移动,把子功能族组合起来形成更大的子功能族。,49,自底向上结合 示意图,50,不同集成测试策略的比较,自顶向
- 1.请仔细阅读文档,确保文档完整性,对于不预览、不比对内容而直接下载带来的问题本站不予受理。
- 2.下载的文档,不会出现我们的网址水印。
- 3、该文档所得收入(下载+内容+预览)归上传者、原创作者;如果您是本文档原作者,请点此认领!既往收益都归您。
下载文档到电脑,查找使用更方便
2000 积分 0人已下载
下载 | 加入VIP,交流精品资源 |
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第七 实现 PPT
