2019年12月15日1信息科学与工程学院软件工程导论2014年4月2019年12月15日2第7章实现实现:编码和测试统称为实现编码:就是把软件设计结果翻译成用某种程序设计语言书写的程序程序设计语言:人与计算机通信的基本工具,指挥计算机按人的意志工作1946—1954:机器语言和汇编语言,与硬件操作一一对应1954:第一个高级语言FORTRAN语言高级语言的种类:基础语言----Fortran,Basic,Cobol,Algol结构化语言----Pl/1,Pascal,C,Ada专用语言-------特殊应用如LISP,Prolog2019年12月15日37.1编码选择语言的理想标准为便于程序测试和维护,减少生存周期的总成本,选用高级语言应用理想的模块化机制,以及可读性好的控制结构和数据结构。为便于调试和提高软件可靠性,应选用编译程序能够尽可能多地发现程序中错误的语言。为降低软件开发和维护成本,选用的语言应具有良好的独立的编译机制。2019年12月15日47.1.1选择程序设计语言选用语言综合考虑标准系统用户的要求可以使用的编译程序可以得到的软件工具程序员的知识软件可移植性要求软件应用领域工程规模如果所开发的系统由用户负责维护,用户通常要求用他们熟悉的语言书写程序。运行目标系统的环境中可以提供的编译程序往往限制了可以选用的语言的范围。如果某种语言有支持程序开发工具可以利用,则目标的实现和验证都变得比较容易。标准化程度高、程序可移植性好是选择语言的重要标准最好是选择程序员最熟悉的语言如果工程规模庞大,应设计供该项目专用的程序设计语言FORTRAN语言适合工程和科学计算;C语言适合系统和实时应用领域。。。2019年12月15日57.1.2编码风格源程序代码的逻辑简明清晰、易读易懂是好程序的一个重要标准,为了做到这一点,应该遵循下述规则:⑴程序内部的文档(包括恰当的标识符、适当的注解和程序的视觉组织等)恰当的标识符选取含义鲜明的名字,使它能正确地提示程序对象所代表的实体。如果使用缩写,那么缩写规则应该一致,并且应该给每个名字加注解。2019年12月15日67.1.2编码风格恰当的注解通常在每个模块开始处有一段序言性的注解,简要描述模块的功能、主要算法、接口特点、重要数据以及开发简史。插在程序中间与一段程序代码有关的注解,主要解释包含这段代码的必要性。对于用高级语言书写的源程序,不需要用注解的形式把每个语句翻译成自然语言,应该利用注解提供一些额外的信息。应该用空格或空行清楚地区分注解和程序。程序的视觉组织程序清单的布局对于程序的可读性也有很大影响,应该利用适当的阶梯形式使程序的层次结构清晰明显2019年12月15日77.1.2编码风格⑵数据说明编程序时需确定数据说明的风格。为了使数据更容易理解和维护,应该遵循一些比较简单的原则:数据说明的次序应该标准化,如按照数据结构或数据类型确定说明的次序;当多个变量名在一个语句中说明时,应该按字母顺序排列这些变量。如果设计时使用了一个复杂的数据结构,则应该用注释说明用程序设计语言实现这个数据结构的方法和特点。含义及规则2019年12月15日87.1.2编码风格⑶语句构造语句构造基本规则不要为了节省空间而把多个语句写在同一行尽量避免复杂的条件测试尽量减少对“非”条件的测试避免大量使用循环嵌套和条件嵌套利用括号使逻辑表达式或算术表达式的运算次序清晰直观2019年12月15日97.1.2编码风格⑷输入输出I/O是几乎所有应用程序都要涉及到的,设计和编写程序时,应考虑相关规则对所有输入数据都进行检验;检查输入项重要组合的合法性;保持输入格式简单;用数据结构标记,不要要求用户指定数据的数目;明确提示交互式输入的请求,详细说明可用的选择或边界数值;当程序设计语言的格式有严格要求时,保持输入格式一致;设计良好的输出报表;给所有输出数据加标志。2019年12月15日107.1.2编码风格⑸效率效率主要指处理机时间和存储器容量两个方面。在讨论提高效率前,应该记住3条原则:效率是性能要求,因此应该在需求分析阶段确定效率方面的要求。效率是靠好设计来提高的。程序的效率和程序的简单程度是一致的。不要牺牲程序的清晰性和可读性来不必要地提高效率。从三个方面进一步讨论效率问题:2019年12月15日117.1.2编码风格⑸效率1.程序运行时间写程序之前先简化算术的和逻辑的表达式;仔细研究嵌套的循环,以确定是否有语句可以从内层往外移尽量避免使用多维数组;尽量避免使用指针和复杂的表;使用执行时间短的算术运算;不要混合使用不同的数据类型;尽量使用整数运算和布尔表达式。2019年12月15日127.1.2编码风格⑸效率2.存储器效率在大型计算机中必须考虑操作系统页式调度的特点,一般说来,使用能保持功能域的结构化控制结构,是提高效率的好方法。在微处理机中,如果要求使用最少的存储单元,则应选用有紧缩存储器特性的编译程序,在非常必要时可以使用汇编语言。2019年12月15日137.1.2编码风格⑸效率3.输入输出的效率简单清晰同样是提高人机通信效率的关键。硬件之间的通信效率比较复杂,但从写程序的角度看,有些简单原则可以提高输入输出效率:所有输入输出都应该有缓存,以减少用于通信的额外开销。对二级存储器应该选用最简单的访问方法。二级缓存器的输入输出应该以信息组为单位进行。如果“超高效的”输入输出很难被人理解,则不采用这种方法2019年12月15日147.1.2编码风格不要一味地追求程序的效率,应当在满足正确性、可靠性、健壮性、可读性等质量因素的前提下,设法提高程序的效率;以提高程序的全局效率(指站在整个系统的角度上考虑的效率)为主,提高局部效率(是指站在模块或函数角度上考虑的效率)为辅;不要追求紧凑的代码,因为紧凑的代码并不能产生高效的机器码;有时候时间效率和空间效率可能对立,此时应当分析那个更重要,作出适当的折衷;程序员使用语言编写程序,但不知道源程序究竟如何变成可执行代码、变成什么可执行代码,这些可执行代码的执行时间是长是短。因此,要从根本上提高程序的效率,需要程序员长时间的编程经验积累。程序效率的提高是无止尽的2019年12月15日157.2软件测试基础测试与测试的目标(G.Myers)测试:为了发现程序中的错误而执行程序的过程好的测试方案是极可能发现迄今为止尚未发现的错误的测试方案成功的测试是发现了至今为止尚未发现的错误的测试7.2.1软件测试的目标2019年12月15日167.2.2软件测试准则所有测试都应该能追溯到用户需求应该在测试前制定测试计划把Pareto原理应用到软件测试中应该从“小规模”开始测试,逐步进行大规模测试。穷举测试是不可能的为了达到最佳的测试效果,应该由独立的第三方从事测试工作。2019年12月15日177.2.3测试方法测试方法黑盒测试:已经知道了软件产品应该具有的功能,通过测试来检验是否每个功能都能正常使用。该测试方法又称功能测试黑盒测试是在程序接口进行的测试,它只检查程序功能是否能按照规格说明书的规定正常使用,程序是否能适当地接收输入数据产生正确的输出信息,并且保持外部信息的完整性白盒测试:知道软件产品内部的工作过程,通过测试来检验产品内部动作是否按照规格说明书的规定正常进行。这种测试方法又称结构测试白盒测试方法按照程序内部的逻辑测试程序,检验程序中的每条通路是否都能按预定要求正确工作2019年12月15日187.2.4测试步骤模块测试子系统测试系统测试平行运行目的:保证每个模块作为一个单元能够正确运行,又称为单元测试•集成测试、组装测试、联合测试•重点在于测试模块之间的接口•将经过测试的子系统装配成一个完整的系统来测试;•发现设计和编码的错误,验证系统是否满足需求说明所定义的功能及其动态特性;•也称为集成测试。同时运行新旧两个系统,并且对处理的结果进行比较,以确定新系统是否满足相关性能指标。验收测试•有用户参加的系统测试•验证是否满足用户的需要2019年12月15日197.2.5测试阶段的信息流测试软件配置测试配置测试结果预期结果评价错误错误率数据调试可靠性模型正确可靠性预测包括需求说明书、设计说明书、源程序清单等包括测试计划和测试方案测试与软件开发各个阶段的关系软件开发过程是一个自顶向下,逐步细化的过程软件计划阶段定义软件作用域软件需求分析建立软件信息域、功能和性能需求、约束等软件设计把设计用某种程序设计语言转换成程序代码测试过程是依相反顺序安排的自底向上,逐步集成的过程2019年12月15日20测试与软件开发各个阶段的关系(示意图)2019年12月15日217.3单元测试单元测试又称模块测试,是针对软件设计的最小单位─程序模块,进行正确性检验的测试工作。其目的在于发现各模块内部可能存在的各种差错单元测试需要从程序的内部结构出发设计测试用例。多个模块可以平行地独立进行单元测试在单元测试时,测试者需要依据详细设计说明书和源程序清单,了解该模块的I/O条件和模块的逻辑结构,主要采用白盒测试技术,辅之以黑盒测试的测试用例,使之对任何合理的输入和不合理的输入,都能鉴别和响应2019年12月15日227.3单元测试单元测试重点模块接口局部数据结构重要的执行通路出错处理通路影响上述各方面特性的边界条件(1)模块接口在单元测试的开始,应对通过被测模块的数据流进行测试,测试项目包括调用本模块的输入参数是否正确本模块调用子模块时输入给子模块的参数是否正确全局量的定义在各模块中是否一致2019年12月15日237.3单元测试(2)局部数据结构测试不正确或不一致的数据类型说明使用尚未赋值或尚未初始化的变量错误的初始值或错误的缺省值变量名拼写错或书写错不一致的数据类型全局数据对模块的影响(3)重要执行通路测试选择适当的测试用例,对模块中重要的执行路径进行测试应当设计测试用例查找由于错误的计算、不正确的比较或不正常的控制流而导致的错误对基本执行路径和循环进行测试可以发现大量的路径错误2019年12月15日247.3单元测试(4)错误处理测试出错的描述是否难以理解出错的描述是否能够对错误定位显示的错误与实际的错误是否相符对错误条件的处理正确与否在对错误进行处理之前,错误条件是否已经引起系统的干预等(5)边界测试注意数据流、控制流中刚好等于、大于或小于确定的比较值时出错的可能性。对这些地方要仔细地选择测试用例,认真加以测试如果对模块运行时间有要求的话,还要专门进行关键路径测试,以确定最坏情况下和平均意义下影响模块运行时间的因素2019年12月15日257.4集成测试集成测试是组装软件的系统化技术;组装测试,联合测试通常,在单元测试的基础上,需要将所有模块按照设计要求组装成为系统。这时需要考虑的问题是:在把各个模块连接起来的时侯,穿越模块接口的数据是否会丢失;一个模块的功能是否会对另一个模块的功能产生不利的影响;各个子功能组合起来,能否达到预期要求的父功能;全局数据结构是否有问题;单个模块的误差累积起来,是否会放大,从而达到不能接受的程度。在单元测试的同时可进行组装测试,发现并排除在模块连接中可能出现的问题,最终构成要求的软件系统2019年12月15日267.4集成测试子系统的组装测试特别称为部件测试,它所做的工作是要找出组装后的子系统与系统需求规格说明之间的不一致。通常,把模块组装成为程序的方式有两种一次性组装方式:又称为非渐增式测试增殖式组装方式:其中又分为自顶向下、自底向上和两种方法混合测试方式,又称渐增式测试一次性组装方式它是一种非增殖式组装方式。也叫做整体拼装使用这种方式,首先对每个模块分别进行模块测试,然后再把所有模块组装在一起进行测试,最终得到要求的软件系统2019年12月15日277.4集成测试系统结构图单元测试整体组装一次性组装方式(bigbang)2019年12月15