版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
软件工程
第七章实现
通常把编码和测试统称为实现。
所谓编码就是把软件设计结果翻译成某种程序设计语言书写的程序。
测试的目的就是在软件投入生产性运行之前,尽可能多地发现软件中的错误。
目前,软件测试仍然是保证软件质量的关键步骤,它是对软件规格说明、设计和编码的最后复审。
软件测试在软件生命周期中横跨两个阶段。通常在编写出每个模块之后就对它做必要的测试(称为单元测试),编码和单元测试属于软件生命周期中的同一个阶段。在这个阶段之后,对软件系统还应该进行各种综合测试,这是软件生命周期中的另一个独立的阶段,通常由专门的测试人员承担这项工作。
一般情况下,软件测试的工作量占软件开发总工作量的40%以上。
7.1编码7.1.1选择程序设计语言无论从编程效率还是从可读性考虑,高级语言都明显优于汇编语言,因此除了不适于采用高级语言的特殊应用领域或大型系统中执行时间非常关键的小部分代码用汇编语言编写外,其他程序都应该用高级语言书写。
理想的高级语言有良好的模块化机制,可读性好的控制结构和数据结构;语言的特点使编译程序能够尽可能多的发现程序代码中的错误;良好的独立编译机制。
实际选取语言时,不能仅使用理论上的标准,还需要考虑实用方面的限制。选择程序设计语言的实用标准:(1)系统用户的要求。如果所开发的系统由用户负责维护,用户通常要求用他们熟悉的语言开发;(2)可以使用的编译程序;(3)可以得到的软件工具;(4)工程规模;(5)程序员的知识;(6)软件可移植性要求;(7)软件的应用领域。7.1.2编码风格源程序代码的逻辑简明清晰、易读易懂是好程序的一个重要标志,为了做到这一点,应遵循以下原则:1.程序内部应该有很好的文档所谓程序内部的文档包括恰当的标示符、适当的注解和程序的视觉组织等等。2.数据说明应该易于理解便于查阅3.语句构造应该尽可能简单直观
语句构造应遵循下述规则:不要为了节省空间而把多个语句放在同一行;尽量避免复杂的条件测试;尽量减少对“非”条件的测试;避免大量使用循环嵌套和条件嵌套;利用括号使逻辑表达式或算术表达式的运算次序清晰直观。4.输入输出风格遵循人机界面设计准则,力求做到数据输入安全方便,信息输出清晰易懂。
输入输出设计风格的规则:对所有输入数据都进行检验;检查输入项重要组合的合法性;保持输入格式简单;使用数据结束标记,不要要求用户指定数据的数目;明确提示交互式输入的请求,详细说明可用的选择或边界数值;当程序设计语言对格式有严格要求时,应保持输入格式一致;设计良好的输出报表;给所有输出数据加标志。5.效率能满足用户需求即可
效率主要指处理机时间和存储器容量两个方面。应该明确:
效率是性能要求,应在需求分析阶段确定效率的要求;
效率是靠好的设计来实现的;
程序的效率和程序的简单程度是一致的,不要牺牲程序的清晰性和可读性来不必要的提高效率。下面从三个方面讨论效率问题。(1)程序运行时间
编写程序时可以应用下述规则:写程序之前先简化算术的和逻辑的表达式;仔细研究嵌套的循环,以确定是否有语句可以从内层往外移;尽量避免使用多维数组;尽量避免使用指针和复杂的表;使用执行时间短的算术运算;不要混合使用不同的数据类型;尽量使用整数运算和布尔表达式。(2)存储器效率在大型计算机中必须考虑操作系统页式调度的特点,一般说来,使用保持功能域的结构化控制结构,是提高效率的好方法。(3)输入输出的效率
简单清晰是提高人机通信效率的关键。7.2软件测试基础(1)测试是为了发现程序中的错误而执行程序的过程;7.2.1软件测试的目标什么是测试?它的目标是什么?G.Myers给出了关于测试的一些规则,或者说是测试的目标或定义:(2)好的测试方案是极可能发现迄今为止尚未发现的错误的测试方案;(3)成功的测试是发现了迄今为止尚未发现的错误的测试。
从上述规则可以看出,测试的正确定义是:‘为了发现程序中的错误而执行程序的过程’。7.2.2软件测试准则怎样才能达到软件测试的目标呢?应遵循下述准则:(1)所有测试都应该能追溯到用户需求;(2)应该远在测试开始之前就制定出测试计划;(3)把Pareto原理应用到软件测试中。Pareto原理说明,测试发现的错误中的80%很可能是由于程序中20%的模块造成的;(4)应该从“小规模”测试开始,并逐步进行“大规模”测试;(5)穷举测试是不可能的;(6)为了达到最佳的测试效果,应该由独立的第三方从事测试工作。7.2.3测试方法外部特性内部特性
怎样对程序进行测试?有两种方法:黑盒法白盒法程序模块的特性模块接口功能内部处理逻辑内部数据结构黑盒测试法:
不考虑程序的内部结构和处理过程,只是在程序接口进行的测试,只检查程序功能是否能按照规格说明书的规定正常使用,程序是否能适当的接收输入数据产生正确的输出信息,并且保持外部信息(如数据库或文件)的完整性。又称为功能测试。白盒测试法:
完全了解程序的内部结构和处理过程,按照程序内部的逻辑测试程序,检验程序中的每条通路是否能按预定要求正确工作。又称为结构测试。穷尽测试:包含所有可能情况的测试。
黑盒测试法和白盒测试法能否做到穷尽测试?
黑盒法要做到穷尽测试,至少必须对所有输入数据的各种可能值的排列组合都进行测试。
白盒法要做到穷尽测试,程序中每条可能的通路至少都应该执行一次(严格地说每条通路都应该在每种可能的输入数据下执行一次)。
事实如何?黑盒法例子:
一个程序需要三个整数型的输入数据,如果计算机字长16位,则每个整数可能取得值有216个,三个输入数据的各种可能值的排列组合共有:
216·216·216=248
近似为3*1014
也就是说,大约需要把这个程序执行3*1014次才能做到‘穷尽测试’。
假定每执行一次程序需要一毫秒,执行这么多次大约需要一万年。循环20次
白盒法例子:结论:??
一段程序对嵌套的IF语句循环执行20次,如下图:共有520条可能的执行通路7.2.4测试步骤
大型软件系统通常由若干个子系统组成,每个子系统又由许多模块组成。因此,大型软件系统的测试基本上由以下几个步骤组成:模块测试子系统测试系统测试验收测试平行运行软件测试步骤集成测试单元测试确认测试7.2.5测试阶段的信息流评价测试结果预期结果可靠性模型错误率数据可靠性预测调试错误正确测试测试配置软件配置图7.1测试阶段的信息流
7.3单元测试单元测试集中检验软件设计的最小单元-----模块。单元测试可以使用白盒法,用详细设计描述做指南,对重要的执行通路进行测试,以便发现模块内部的错误。单元测试可以对多个模块并行进行。7.3.1测试重点在单元测试期间主要评价模块的下述五个特性:模块接口;局部数据结构;重要的执行通路;出错处理通路;影响上述方面特性的边界条件。对接口进行测试主要检查下述各点:(1)参数数目和由调用模块送来的变元数目是否相等?(2)参数的属性和变元的属性是否匹配?(3)参数和变元的单位系统是否匹配?(4)传送给被调用模块的变元数目是否等于那个模块的参数数目?(5)传送给被调用模块的变元属性和参数的属性是否一致?(6)传送给被调用模块的变元的单位系统和该模块参数的单位系统是否一致?(7)传送给内部函数的变元属性、数目和次序是否正确?(8)是否修改了只做输入用的变元?(9)全程变量的定义和用法在各个模块中是否一致?
如果一个模块完成外部的输入或输出时,还应检查下述各点:(1)文件属性是否正确?(2)打开文件语句是否正确?(3)格式说明书与输入/输出语句是否一致?(4)缓冲区大小与记录长度是否匹配?(5)使用文件之前先打开了文件了吗?(6)文件结束条件处理了吗?(7)输入/输出错误检查并处理了吗?(8)输出信息中有文字书写错误吗?
对于局部数据结构的检查主要有:(1)错误的或不相容的说明;(2)使用尚未赋值或尚未初始化的变量;(3)错误的初始值或不正确的缺省值;(4)错误的变量名字(拼写错或截短了);(5)数据类型不相容;(6)上溢、下溢或地址异常。
在计算中比较常见的错误是:(1)计算次序不对或误解了运算符的优先次序;(2)混合运算(运算对象的类型彼此不相容);(3)变量初始值不正确;(4)精度不够;(5)表达式的符号表示错误。
测试方案中应包含对比较和控制流方面一些错误的检测:(1)比较数据类型不同的量;(2)逻辑运算符不正确或优先次序的错误;(3)当由于精度问题两个量不会相等时,程序中却期待着相等条件的出现;(4)‘差1’错(即多循环一次或少循环一次);(5)错误的或不存在的循环终止条件;(6)当遇到发散的迭代时不能终止循环;(7)错误地修改循环变量。7.3.2代码审查
对于典型的程序来说,代码审查可以查出30%-70%的逻辑设计错误和编码错误。审查小组的组成:(1)组长,应该是一个很有能力的程序员,而且没有直接参与这项工作;(2)程序的设计者;(3)程序的编程者;(4)程序的测试者;7.3.3计算机测试
在单元测试过程中,必须为每一个单元测试开发驱动软件和(或)存根软件。即:驱动软件被测试模块存根软件测试软件
7.4集成测试集成测试是组装软件的系统技术,主要目标是发现与接口有关的问题。集成测试过程渐增式非渐增式
非渐增式测试:先分别测试每个模块,再把所有模块按设计要求放在一起结合成所要的程序。
渐增式测试:把下一个要测试的模块同已经测试好的那些模块结合起来进行测试,测试完以后再把下一个应该测试的模块结合起来进行测试。
渐增式测试与非渐增式测试的比较:
第一,因为非渐增式测试方法分别测试每个模块,需要编写的测试软件(驱动程序和存根程序)通常比较多,所以需要的工作量较大;渐增式测试方法利用已测试过的模块作为部分测试软件,因此开销比较小。第二,渐增式测试可以较早发现模块间的接口错误;非渐增式测试最后才把模块组装在一起,因此接口错误发现的晚。
第三,非渐增式测试一下子把所有模块组合在一起,如果发现错误则较难诊断定位;反之,使用渐增式测试方法时,如果发生错误则往往和最近加进来的那个模块有关。
第四,渐增式测试方法把已经测试好的模块和新加进来的那个模块一起测试,已测试好的模块可以在新的条件下受到新的检验,因此,这种方法对程序的测试更彻底。
第五,渐增式测试需要较多的机器时间,这是因为测试每个模块时所有已经测试完的模块也都要跟着一起运行。
第六,使用非渐增式测试方法可以并行测试所有模块,因此能充分利用人力,加快工程进度。以上比较,可以看出前四条是渐增式测试方法的优点,后两条是它的缺点。
7.4.1自顶向下结合集成测试非渐增式渐增式深度优先策略宽度优先策略自顶向下自底向上
自顶向下的结合方法是一个日益为人们广泛采用的组装软件的途径。从主控制模块(主程序)开始,沿着软件的控制层次向下移动,从而逐渐把各个模块结合起来。在把附属于(以及最终附属于)主控制模块的那些模块组装到软件结构中时,或者使用深度优先策略,或者使用广度优先策略。
把模块结合进软件结构的具体过程有下述四个步骤完成:第一步,对主控制模块进行测试,测试时用存根模块代替所有直接附属于主控制模块的模块;第二步,根据选定的结合策略(深度优先或宽度优先),每次用一个实际模块代换一个存根程序(新结合进来的模块往往又需要新的存根程序);第三步,在结合进一个模块的同时进行测试;
第四步,为了保证加入模块没有引进新的错误,可能需要进行回归测试(即,全部或部分地重复以前做过的测试)。从第二步开始不断地重复进行上述过程,直到构造起完整的软件结构为止。S4M1S7M3M2M6M5M8图7.3自顶向下结合7.4.2自底向上结合
自底向上测试从‘原子’模块(即在软件结构最底层的模块)开始组装和测试。因为是从底部向上结合模块,总能得到需要的下层模块处理功能,所以不需要存根程序。
用下述步骤可以实现自底向上的结合策略:(1)把底层模块组合成实现某个特定的软件子功能的族;(2)写一个驱动程序(用于测试的控制程序),协调测试数据的输入和输出;(3)对由模块组成的子功能族进行测试;(4)去掉驱动程序,沿软件结构自下向上移动,把子功能族组合起来形成更大的子功能族。上述第二步到第四步实质上构成了一个循环。图7.5描绘了自底向上的结合过程。M2MbMcD2
族2D3
族3D1
族1图7.4自底向上结合7.4.3不同集成测试策略的比较
集成测试的两种策略,哪种方法更好一些?一般说来,一种方法的优点正好对应另一种方法的缺点。
自顶向下测试方法的主要优点是:不需要测试驱动程序,能够在测试阶段的早期实现并验证系统的主要功能,而且能在早期发现上层模块的接口错误。
主要缺点是:需要存根程序,可能遇到与此相联系的测试困难,低层关键模块中的错误发现较晚,而且在早期不能充分展开人力。
自底向上测试方法的优缺点与自顶向下测试方法的优缺点正好相反。
一般说来,纯粹的自顶向下或纯粹的自底向上的测试策略可能都不实用,人们在实践中创造出许多混合策略:
改进的自顶向下测试方法:基本上使用自顶向下的测试方法,但在早期,就使用自底向上的方法测试软件中的少数关键模块。一般的自顶向下方法的优点在该方法中也都有,而且能在测试的早期发现关键模块中的错误;但是,它的缺点也比自顶向下方法多一条,即测试关键模块时需要驱动程序。
混合法:对软件结构中较上层,使用的是自顶向下方法,对软件结构中较下层,使用的是自底向上方法,两者相结合。这种方法兼有两种方法的优点和缺点。该方法是一种折衷的方法。7.4.4回归测试所谓回归测试是指重新执行已经做过的测试的某个子集,以保证程序变化时没有带来非预期的副作用。回归测试集包括下述三种不同的测试用例:(1)监测软件全部功能的代表性测试用例;(2)专门针对可能受修改影响的软件功能的附加测试;(3)针对被修改过的软件成分的测试。
7.5确认测试确认测试也称为验收测试,它的目标是验证软件的有效性。验证,指的是保证软件正确地实现了某个特定要求的一系列活动;确认指的是为了保证软件确实满足了用户需求而进行的一系列活动。什么是软件有效性?如果软件的功能和性能如同用户所合理地期待的那样,则软件是有效的。
验收测试的范围与系统测试的范围类似,但是也有一些差别,例如:(1)某些已经测试过的纯粹技术性的特点可能不需要再次测试;(2)对用户特别感兴趣的功能或性能,可能需要增加一些测试;(3)通常主要使用生产中的实际数据进行测试;(4)可能需要设计并执行一些与用户使用步骤有关的测试。7.5.1确认测试的范围确认测试必须由用户积极参与,或者以用户为主。用户应该参加设计测试方案,使用用户接口输入测试数据并且分析评价测试的输出结果。确认测试一般使用黑盒法。应该仔细设计测试计划和测试过程,测试计划包括:要进行的测试种类和进度安排;测试过程规定用来检验软件是否与需求一致的测试方案。
通过测试要保证软件能满足所有功能要求,能达到每个性能要求,文档资料是准确而完整的。验收测试有两种可能的结果:(1)功能和性能与用户要求一致,软件是可以接受的;(2)功能或性能与用户要求有差距。补充:系统测试系统测试是把软件、硬件和环境连在一起全面的测试。测试的内容同被测试系统的特点有关。测试某个具体系统时,可根据情况选择下面其中的几种:(1)功能测试(FunctionTesting)检查系统是否真正实现了需求说明书描述的每一个功能。(2)容量测试(VolumeTesting)容量测试是让系统经受大数据量的考验。例如,让编译程序编译一个特别长的源程序;让连结程序连结成千个模块。(3)紧张度测试(StressTesting,压力测试)紧张度测试是使系统在高度紧张的情况下运行,即在很短的时间内,使数据量达到峰值。例如,对支持15道多道程序的操作系统,紧张度测试可以使它同时运行15个作业;对支持64个终端的分时系统,其紧张度测试可以使64个终端用户同时进入系统。(4)使用性测试(UsabilityTesting)使用性测试从使用是否合理、方便的角度对系统进行检验。包括用户界面是否合理?风格上是否统一?操作是否方便?…等。(5)安全性测试(SecurityTesting)安全性测试就是设法选一些测试用例来破坏系统的安全机制。例如,破坏数据管理系统的数据保密机制。(6)性能测试(PerformanceTesting)性能测试就是在一定工作负荷和条件下的响应时间及吞吐量。(7)可靠性测试(ReliabilityTesting)软件可靠性:在规定条件下,在规定时间内,软件不引起系统失效的概率。(8)恢复测试(RecoveryTesting)
操作系统、数据库管理系统都有恢复机制,在失误之后,系统可以重新恢复工作。恢复测试的目的是检验这些机制的功能。此时可以故意制造一些数据错误和程序错误,也可以模拟硬件错误,以观察系统的反应,看其能否在出错后恢复。(9)文档测试(DocumentationTesting)检查用户文档的精确性和清晰性。7.5.2软件配置复查验收测试的另一个重要内容是复查软件配置。复查的目的是保证软件配置的所有成分都齐全,各方面的质量都符合要求,文档与程序一致,具有维护阶段所必需的细节,而且已经编排好目录。7.5.3Alpha和Beta测试
Alpha测试由用户在开发者的场所进行,并且在开发者对用户的“指导”下进行测试,是在受控的环境中进行的。
Beta测试由软件的最终用户在一个或多个客户场所进行,开发者通常不在测试现场,因此Beta测试是软件在开发者不能控制的环境中的“真实”应用。
7.6白盒测试技术所谓测试方案包括预定要测试的功能,应该输入的测试数据和预期的结果。要介绍的设计技术主要有:适应于黑盒测试的等价划分、边界值分析以及错误推测法等;适应于白盒测试的逻辑覆盖法。通常的做法是:用黑盒法设计基本的测试方案,再用白盒法补充一些方案。7.6.1逻辑覆盖逻辑覆盖语句覆盖判定覆盖条件覆盖判定/条件覆盖条件组合覆盖点覆盖边覆盖路径覆盖
所谓逻辑覆盖是对一系列测试过程的总称,这组测试过程逐渐进行越来越完整的通路测试。测试数据执行(或叫覆盖)程序逻辑的程度可以根据覆盖源程序语句的详尽程度,大致划分成以下不同的覆盖标准:入口A>1ANDB=0A=2ORX>1返回X=X/AX=X+1TFFTsabdce
1、语句覆盖
含义:选择足够多的测试数据,使被测试程序中每个语句至少执行一次。PROCEDUREEXAMPLE(A,B:REAL;VARX:REAL)BEGINIF(A>1)AND(B=0)THENX:=X/AIF(A=2)OR(X>1)THENX:=X+1END;例如:程序段程序流程图入口A>1ANDB=0A=2ORX>1返回X=X/AX=X+1TFFTsabdce
为了使每个语句都执行一次,程序的执行路径应该是sacbed,为此只要输入下面的测试数据(实际上X可以是任意值):A=2,B=0,X=4
语句覆盖对程序的逻辑覆盖很少。在该例中,两个判定条件都只测了条件为真的情况,如果条件为假时有错误,显然不能发现。此外,语句覆盖只关心判定表达式的值,而没有分别测试判定表达式中每个条件取不同值的情况。2.判定覆盖(又称分支覆盖)入口A>1ANDB=0A=2ORX>1返回X=X/AX=X+1TFFTsabdce
对于该例来说,能够分别覆盖路径sacbed和sabd的两组测试数据,或者可以分别覆盖路径sacbd和sabed的两组测试数据,都满足判定覆盖标准。例如,测试数据:
含义:不仅每个语句必须至少执行一次,而且每个判定的每种可能的结果都应该至少执行一次,也就是每个判定的每个分支都至少执行一次。(1)A=3,B=0,X=3(覆盖sacbd)
判定覆盖比语句覆盖强,但对程序的逻辑覆盖程度仍然不高。该测试数据只覆盖了程序全部路径的一半。(2)A=2,B=1,X=1(覆盖sabed)3.条件覆盖入口A>1ANDB=0A=2ORX>1返回X=X/AX=X+1TFFTsabdce
例中共有两个判定表达式,每个表达式中有两个条件,为做到条件覆盖,应选取测试数据使得在a点有下述各种结果出现:
A>1,A<=1,B=0,B<>0在b点有下述各种结果出现:
A=2,A<>2,X>1,X<=1
用下面两组测试数据,即可满足上述覆盖标准:
含义:不仅每个语句必须至少执行一次,而且使判定表达式中的每个条件都取到各种可能的结果。(1)A=2,B=0,X=4
(满足A>1,B=0,A=2和X>1的条件,执行路径sacbed)(2)A=1,B=1,X=1
(满足A<=1,B<>0,A<>2和X<=1的条件,执行路径sabd)
入口A>1ANDB=0A=2ORX>1返回X=X/AX=X+1TFFTsabdce
条件覆盖通常比判定覆盖强,因为它使判定表达式中每个条件都取到了两个不同的结果,判定覆盖却只关心整个判定表达式的值。但是,也可能有相反的情况,虽然每个条件都取到了两个不同的结果,判定表达式却始终只取一个值。例如,取下面两组测试数据,则只满足条件覆盖并不满足判定覆盖标准(第二个判定表达式的值总为真)。(1)A=2,B=0,X=1
满足A>1,B=0,A=2和X<=1的条件,执行路径sacbed。(2)A=1,B=1,X=2
满足A<=1,B<>0,A<>2和X>1的条件,执行路径sabed。4.判定/条件覆盖入口A>1ANDB=0A=2ORX>1返回X=X/AX=X+1TFFTsabdce
对该图而言,下面两组测试数据满足判定/条件覆盖标准:(1)A=2,B=0,X=4(2)A=1,B=1,X=1
含义:选取足够多的测试数据,使得判定表达式中的每个条件都取到各种可能的值,而且每个判定表达式也都取到各种可能的结果。5.条件组合覆盖入口A>1ANDB=0A=2ORX>1返回X=X/AX=X+1TFFTsabdce
在该例中,共有8种可能的组合,分别为:(1)A>1,B=0(2)A>1,B<>0(3)A<=1,B=0(4)A<=1,B<>0(5)A=2,X>1(6)A=2,X<=1(7)A<>2,X>1(8)A<>2,X<=1
含义:选取足够多的测试数据,使得判定表达式中条件的各种可能组合都至少出现一次。
下面的四组测试数据可以使上面列出的八种条件组合每种至少出现一次:(1)A=2,B=0,X=4
(针对1,5两种组合,执行路径sacbed)(2)A=2,B=1,X=1
(针对2,6两种组合,执行路径sabed)(3)A=1,B=0,X=2
(针对3,7两种组合,执行路径sabed)(4)A=1,B=1,X=1
(针对4,8两种组合,执行路径sabd)6.点覆盖
在5.5节中已介绍从程序流程图导出程序图的方法。在正常情况下程序图是连通的有向图,图中每个节点相当于程序流程图中的一个框(一个或多个语句)。
点覆盖含义:选取足够多的测试数据,使得程序执行路径至少经过程序图中每个节点一次。
显然,点覆盖标准和语句覆盖标准是相同的。7.边覆盖
含义:选取足够多的测试数据,使得程序执行路径至少经过程序图中每条边一次。
通常边覆盖标准和判定覆盖标准是相同的。8.路经覆盖
含义:选取足够多的测试数据,使程序的每条可能路径都至少执行一次(如果程序图中有环,则要求每个环至少经过一次)。入口A>1ANDB=0A=2ORX>1返回X=X/AX=X+1TFFTsabdce
在该程序流程图中,可能的执行路径有四条,是:sabd、sabed、sacbd和sacbed。下面四组测试数据可以满足路径覆盖要求:(1)A=1,B=1,X=1(执行路径sabd)(2)A=1,B=1,X=2(执行路径sabed)(3)A=3,B=0,X=1(执行路径sacbd)(4)A=2,B=0,X=4(执行路径sacbed)
7.6.2控制结构测试
1.基本路径测试
基本路径测试是TomMcCabe提出的一种白盒测试方法。该方法测试时,首先计算程序的环形复杂度,并用该复杂度为指南定义执行路径的基本集合,从该集合导出的测试用例可以保证程序中的每条语句至少执行一次,而且每个条件在执行时都将分别取真、假两种值。
使用基本路径测试技术的测试步骤如下:
第一步,根据过程设计结果画出相应的流图;第二步,计算流图的环形复杂度;第三步,确定线性独立路径的基本集合;所谓独立路径是指至少引入程序的一个新处理语句集合或一个新条件的路径。用流图术语描述,至少包含一条在定义该路径之前不曾用过的边。
第四步,设计可强制执行基本集合中每条路径的测试用例;12345687121011139图7.6求平均值过程的流图
例,图7.6为讲义P166页的求平均值过程的流图。经计算其环形复杂度为6。(V(G)=E-N+2=17-13+2=6)
对于该流图,由于其环形复杂度为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-…
路径4、5、6后面的省略号(…)表示,可以后接通控制结构其余部分的任意路径。
具体测试用例设计讲义P1672.条件测试用条件测试技术设计出的测试用例,能够检查程序模块中包含的逻辑条件。一个简单条件是一个布尔变量或一个关系表达式,在布尔变量或关系表达式之前可能有一个NOT算符。关系表达式的表示如下:
E1<关系算符>E2
其中,E1和E2是算术表达式,而<关系算符>是下列算符之一:“<”,“<=”,“=”,“<>”,“>”或“>=”。复合条件由两个或多个简单条件、布尔算符和括弧组成。布尔算符有OR(“|”),AND(“&”)和NOT(“¬”)。因此,条件成分的类型包括布尔算符、布尔变量、布尔括弧(包括简单条件或复合条件)、关系算符及算术表达式。
如果条件不正确,则至少条件的一个成分不正确。因此,条件错误的类型如下:布尔算符错(布尔算符不正确,遗漏布尔算符或有多余的布尔算符)布尔变量错布尔括弧错关系算符错算术表达式错
条件测试方法着重测试程序中的每个条件。下面将要讲述的条件测试策略有两个优点:(1)容易度量条件的测试覆盖率;(2)程序内条件的测试覆盖率可指导附加测试的设计。
条件测试的目的不仅是检测程序条件中的错误,而且是检测程序中的其他错误。如果程序P的测试集能有效地检测P中条件的错误,则它很可能也可以有效地检测P中的其他错误。此外,如果一个测试策略对检测条件错误是有效的,则很可能该策略对检测程序的其他错误也是有效的。分支测试可能是最简单的条件测试策略:对于复合条件C来说,C的真分支和假分支以及C中的每个简单条件,都应该至少执行一次。
域测试要求对一个关系表达式执行3个或4个测试。对于形式为
E1<关系算符>E2的关系表达式来说,需要3个测试分别使E1的值大于、等于或小于E2的值。如果<关系算符>错误而E1和E2正确,则这3个测试能够发现关系算符的错误。为了发现E1和E2中的错误,让E1值大于或小于E2值的测试数据应该使这两个值之间的差别尽可能小。
包含n个变量的布尔表达式需要2n个(每个变量分别取真或假这两个可能值的组合数)测试。这个策略可以发现布尔算符、变量和括弧的错误,但是,该策略仅在n很小时才是实用的。
K.C.Tai提出了一种被才称为BRO(branchandrelationaloperator)测试的条件测试策略。如果在条件中所有布尔变量和关系算符都只出现一次而且没有公共变量,则BRO测试保证能发现该条件中的分支错和关系算符错。
BRO测试利用条件C的条件约束来设计测试用例。包含n个简单条件的条件C的条件约束定义为(D1,D2,…,Dn),其中Di(0<i≤n)表示条件C中第i个简单条件的输出约束。如果在条件C的一次执行过程中,C中每个简单条件的输出都满足D中对应的约束,则称C的这次执行覆盖了C的条件约束D。对于布尔变量B来说,B的输出约束指出,B必须是真(t)或假(f)。类似地,对于关系表达式来说,用符号>,=和<指定表达式的输出约束。作为第一个例子,考虑下列条件
C1:B1&B2
其中,B1和B2是布尔变量.C1的条件约束形式为(D1,D2),其中D1和D2中的每一个都是“t”或“f”。值(t,f)是C1的一个条件约束,并由使B1值为真B2值为假的测试所覆盖。BRO测试策略要求,约束集{(t,t),(f,t),(t,f)}被C1的执行所覆盖。如果C1因布尔算符错误而不正确,则至少上述约束集中的一个约束将迫使C1失败。作为第二个例子,考虑下列条件
C2:B1&(E3=E4)其中,B1是布尔变量,E3和E4是算术表达式。C2的条件约束形式为(D1,D2),其中D1是“t”或“f”
,D2是>,=或<。除了C2的第二个简单条件是关系表达式之外,C2和C1相同,因此,可以通过修改C1的约束集{(t,t),(f,t),(t,f)}得出C2的约束集。注意,对于(E3=E4)来说,“t”意味“=”,而“f”
意味着“<”或“>”,因此,分别用(t,=)和(f,=)替换(t,t)和(f,t),并用(t,<)和(t,>)替换(t,f),就得到C2的约束集{(t,=),(f,=),(t,<),(t,>)}。
覆盖上述条件约束集的测试,保证可以发现C2中布尔算符和关系算符的错误。作为第三个例子,考虑下列条件
C3:(E1>E2)&(E3=E4)
其中,E1、E2、E3和E4是算术表达式。C3的条件约束形式为(D1,D2),而D1和D2的每一个都是>,=或<。除了C3的第一个简单条件是关系表达式之外,C3和C2相同,因此,可以通过修改C2的约束集得到C3的约束集,结果为:{(>,=),(=,=),(<,=),(>,<),(>,>)}
覆盖上述条件约束集的测试,保证可以发现C3中关系算符的错误。3.循环测试循环是绝大多数软件算法的基础,但是,在测试软件时却往往未对循环结构进行足够的测试。循环测试是一种白盒测试技术,它专注于测试循环结构的有效性。在结构化的程序中通常只有3种循环,即简单循环、串接循环和嵌套循环,如图7.7所示。下面分别讨论这3种循环的测试方法。简单循环嵌套循环串接循环图7.73种循环(1)简单循环。应该使用下列测试集来测试简单循环,其中n是允许通过循环的最大次数。
●跳过循环。
●只通过循环一次。
●通过循环两次。
●通过循环m次,其中m<n-1。
●通过循环n-1,n,n+1次。(2)嵌套循环。如果把简单循环的测试方法直接应用到嵌套循环,可能的测试数就会随嵌套层数的增加按几何级数增长,这会导致不切实际的测试数目。B.Beizer提出了一种能减少测试数的方法:
●从最内层循环开始测试,把所有其他循环都设置为最小值。
●对最内层循环使用简单循环测试方法,而使外层循环的迭代参数(例如,循环计数器)取最小值,并为越界值增加一些额外的测试。
●由内向外,对下一个循环进行测试,但保持所有其他外层循环为最小值,其他嵌套循环为“典型”值。
●继续进行下去,直到测试完所有循环。(3)串接循环。如果串接循环的各个循环都彼此独立,则可以使用前述的测试简单循环的方法来测试串接循环。但是,如果两个循环串接,而且第一个循环的循环计数器值是第二个循环的初始值,则这两个循环并不是独立的。当循环不独立时,建议使用测试嵌套循环的方法来测试串接循环。课堂练习:课堂练习:课堂练习:7.7黑盒测试技术黑盒测试着重测试软件功能。它不能取代白盒测试,是与白盒测试互补的测试方法。黑盒测试力图发现下述类型的错误:(1)功能不正确或遗漏了功能;(2)界面错误;(3)数据结构错误或外部数据库访问错误;(4)性能错误;(5)初始化和终止错误。设计黑盒测试方案时,应考虑下述问题:(1)怎样测试功能的有效性?(2)哪些类型的输入可构成好测试用例?(3)系统是否对特定的输入值特别敏感?(4)怎样划定数据类的边界?(5)系统能够承受什么样的数据率和数据量?(6)数据的特定组和将对系统运行产生什么影响?应用黑盒测试技术,能够设计出满足下述标准的测试用例集:(1)所设计出的测试用例能够减少为达到合理测试所需要设计的测试用例的总数;(2)所设计出的测试用例能够告诉我们,是否存在某些类型的错误,而不是仅仅指出与特定测试相关的错误是否存在。7.7.1等价划分等价划分是用黑盒法设计测试方案的一种技术。其基本思想是:选取少量最有代表性的输入数据,以期用较小的代价暴露出较多的程序错误。如果把所有可能的输入数据(有效的和无效的)划分成若干个等价类,则可以合理地做出下述假定:每类中的一个典型值在测试中的作用与这一类中所有其它值的作用相同。因此,可以从每个等价类中只取一组数据作为测试数据。这样选取的测试数据最有代表性,最可能发现程序中的错误。
使用等价划分法设计测试方案首先需要划分输入数据的等价类,确定输入数据的有效等价类和无效等价类。
等价类划分的几条启发式规则:如果规定了输入值的范围,则可划分出一个有效的等价类(输入值在此范围内),两个无效的等价类(输入值小于最小值或大于最大值);如果规定了输入数据的个数,则类似地可划分出一个有效的等价类(输入值个数等于此值),两个无效的等价类(输入值个数少于或多于该值);
如果规定了输入数据的一组值,而且程序对不同输入值做不同处理,则每个允许的输入值是一个有效的等价类,此外还有一个无效的等价类(任一个不允许的输入值);如果规定了输入数据必须遵循的规则,则可划分出一个有效的等价类(符合规则),若干个无效的等价类(从各种不同角度违反规则);如果规定了输入数据为整型,则可划分出正整数、零和负整数等三个有效的等价类;如果程序处理的对象是表格,则应该使用空表,以及含一项或多项的表。
以上列出的启发式规则只是测试时可能遇到的情况中很少的一部分。为了正确划分等价类,一是要注意积累经验,二是要正确分析被测程序的功能。划分出等价类后,根据等价类设计测试方案时主要使用下面两个步骤:(1)设计一个新的测试方案,以尽可能多的覆盖尚未被覆盖的有效等价类,重复这一步骤直到所有有效等价类都被覆盖为止;(2)设计一个新的测试方案,使它覆盖一个而且只覆盖一个尚未被覆盖的无效等价类,重复这一步骤直到所有无效等价类都被覆盖为止。等价划分法测试用例:讲义P173-P1757.7.2边界值分析经验表明,处理边界情况是最容易发生错误。例如,许多程序错误出现在下标、纯量、数据结构和循环等的边界附近。因此,设计使程序运行在边界情况附近的测试方案,暴露出程序错误的可能性更大一些。使用边界值分析方法设计测试方案,首先应确定边界情况,通常输入等价类和输出等价类的边界,就是应该着重测试的程序边界情况。选取的测试数据应该刚好等于、刚刚小于和刚刚大于边界值。也就是说,按照边界值分析法,应该选取刚好等于、稍小于和稍大于等价类边界值的数据作为测试数据,而不是选取每个等价类内的典型值或任意值作为测试数据。
通常设计测试方案时,总是联合使用等价划分和边界值分析两种技术。补充:边界值分析法的几条启发式规则:如果规定了输入值的范围,则可选择一些恰好取到边界值的例子;另外,再设计一些代表不合理输入数据的例子,它们的值恰好越过边界;如果规定了输入数据的个数,则为最小个数、最大个数、比最小个数少1、比最大个数多1分别设计例子;为每个输出条件使用上面第一条;为每个输出条件使用上面第二条;若程序的输入或输出是有序集合(如顺序文件、线性表等),则应特别注意集合的第一个或最后一个元素。补充:边界值分析法与等价类法的差别:(1)边界值分析法不是从一个等价类中任选一个例子作为代表,而是选一个或几个例子,使得该等价类的边界情况成为测试的主要目标;(2)边界值分析法不仅注意输入条件,它还根据输出的情况(即按输出等价类)设计测试用例。7.7.3错误推测错误推测法在很大程度上靠直觉和经验进行。它的基本想法是列举出程序中可能有的错误和容易发生错误的特殊情况,并且根据他们选择测试方案。7.7.4因果图(补充)1.因果图的使用范围
前面介绍的等价类划分方法和边界值分析方法,都是着重考虑输入条件,但未考虑输入条件之间的联系。如果在测试时必须考虑输入条件的各种组合,可能又会产生一些新的情况。
要检查输入条件的组合不是一件容易的事情,即使把所有输入条件划分成等价类,它们之间的组合情况也相当多。因此必须考虑使用一种适合于描述对于多种条件的组合,相应产生多个动作的形式来考虑设计测试用例,这就需要利用因果图。因果图方法最终生成的就是判定表。它适合于检查程序输入条件的各种组合情况。2.用因果图生成测试用例的基本步骤
1)分析软件规格说明描述中,哪些是原因(即输入条件或输入条件的等价类),哪些是结果(即输出条件),并给每个原因和结果赋予一个标识符。
2)分析软件规格说明描述中的语义,找出原因与结果之间、原因与原因之间对应的关系。根据这些关系,画出因果图。
3)由于语法或环境限制,有些原因与原因之间,原因与结果之间的组合情况不可能出现。为表明这些特殊情况,在因果图上用一些记号标明约束或限制条件。
4)把因果图转换成判定表。
5)把判定表的每一列拿出来作为依据,设计测试用例。3.在因果图中出现的基本符号通常在因果图中用Ci表示原因,用Ei表示结果,其基本符号如图8.17所示。各结点表示状态,可取值“0”或“1”。“0”表示某状态不出现,“1”表示某状态出现。主要的原因和结果之间的关系有:(a)恒等:表示原因与结果之间一对一的对应关系。若原因出现,则结果出现。若原因不出现,则结果也不出现。C1E1(a)恒等(b)非:表示原因与结果之间的一种否定关系。若原因出现,则结果不出现。若原因不出现,反而结果出现。C1E1(b)非(c)或(∨):表示若几个原因中有一个出现,则结果出现,只有当这几个原因都不出现时,结果才不出现。E1C1C2∨(c)或
(d)与(∧):表示若几个原因都出现,结果才出现。若几个原因中有一个不出现,结果就不出现。C1C2∧E1(d)与C1E1(a)恒等C1E1(b)非E1C1C2∨(c)或C1C2∧E1(d)与图8.17因果图的图形符号4.表示约束条件的符号为了表示原因与原因之间,结果与原因之间可能存在的约束条件,在因果图中可以附加一些表示约束条件的符号。若从输入(原因)考虑,有以下4种约束,参看图8.18。(a)E(互斥):它表示a,b两个原因不会同时成立,两个中最多有一个可能成立。Eab(a)E(互斥.排他)(b)I(包含):它表示a,b,c三个原因中至少有一个必须成立。Icba(b)I(包含.或)(c)O(唯一):它表示a和b当中必须有一个,且仅有一个成立。Oab(c)O(唯一)
(d)R(要求):它表示当a出现时,b必须也出现。不可能a出现,b不出现。
(e)M(屏蔽):它表示当a是1时,b必须是0。而当a为0时,b的值不定。abR(d)R(要求)abM(e)M(屏蔽)Eab(a)E(互斥.排他)Icba(b)I(包含.或)Oab(c)O(唯一)abR(d)R(要求)abM(e)M(屏蔽)图8.18因果图的约束符号5.利用因果图设计测试用例的实例【例】有一个处理单价为5角钱的饮料的自动售货机软件测试用例的设计。其规格说明为:若投入5角钱或1元钱的硬币,押下【橙汁】或【啤酒】的按纽,则相应的饮料就送出来。若售货机没有零钱找,则一个显示【零钱找完】的红灯亮,这时在投入1元硬币并押下按纽后,饮料不送出来而且1元硬币也退出来;若有零钱找,则显示【零钱找完】的红灯灭,在送出饮料的同时退还5角硬币。
1)分析这一段说明,列出原因和结果
原因结果
1.售货机有零钱找
2.投入1元硬币
3.投入5角硬币
4.押下橙汁按纽
5.押下啤酒按纽21.售货机零钱找完灯亮22.退还1元硬币23.退还5角硬币24.送出橙汁饮料25.送出啤酒饮料
2)画出因果图,如图8.19所示。所有原因结点列在左边,所有结果结点列在右边。建立四个中间结点,表示处理的中间状态。中间结点:11.投入1元硬币且押下饮料按纽
12.押下【橙汁】或【啤酒】的按纽
13.应当找5角零钱并且售货机有零钱找
14.钱已付清12341413125112524232221售货机有零钱找EE∧∧∧∧∧∨∨该找5角可找5角钱付清押下按纽投入1元硬币投入5角硬币押下橙汁按纽押下啤酒按纽售货机”零钱找完”灯亮退还1元硬币找回5角硬币送出橙汁饮料送出啤酒饮料图8.19因果图中间状态3)由于2与3,4与5不能同时发生,分别加上约束条件E。
4)因果图。
5)转换成判定表,如图8.20所示。判定表中没有被划去的每一列就是一个测试用例。12341413125112524232221售货机有零钱找EE∧∧∧∧∧∨∨该找5角可找5角钱付清押下按纽投入1元硬币投入5角硬币押下橙汁按纽押下啤酒按纽售货机”零钱找完”灯亮退还1元硬币找回5角硬币送出橙汁饮料送出啤酒饮料图8.19因果图约束中间状态
条件111111111111111110000000000000000211111111000000001111111100000000311110000111100001111000011110000411001100110011001100110011001100510101010101010101010101010101010
中间结果11110000000110000000121101101101101101101311000000000000000014110111000000111000
结果2100000000011111111122000000000110000000231100000000000000002410010000000010000025010011000000010000
测试用例图8.20由因果图得到的判定表YYYYYYYYYYYYYYYY序号12345678910123456789201234567893012补充:实用测试策略对软件系统进行实际测试时,应该联合使用各种设计测试方案的方法,形成一种综合策略。通常的做法是,用黑盒法设计基本的测试方案,再用白盒法补充一些必要的测试方案。具体地说,可以使用下述策略结合各种方法:
1.在任何情况下都应该使用边界值分析的方法。经验表明,用这种方法设计出的测试方案暴露程序错误的能力最强。注意,应该既包括输入数据的边界情况又包括输出数据的边界情况。2.必要时用等价划分法补充测试方案。
3.必要时再用错误推测法补充测试方案。
4.对照程序逻辑,检查已经设计出的测试方案。可以根据对程序可靠性的要求采用不同的逻辑覆盖标准,如果现有测试方案逻辑覆盖程度没达到要求的覆盖标准,则应再补充一些测试方案。应该强调指出,即时使用上述综合策略设计测试方案,仍然不能保证测试将发现一切程序错误。但是,这个策略确实是在测试成本和测试效果之间的一个合理的折衷。例:程序TRIANGLE读入三个整数值,这三个整数代表一个三角形的三条边的长度,程序根据这三个值判断三角形属于不等边、等腰或等边三角形中的哪一种。综合使用边界值分析、等价划分和错误推测等技术,可以设计出下述11种应该测试的情况:(1)正常的不等边三角形;(2)正常的等边三角形;(3)正常的等腰三角形,包括两条相等边的三种不同排列方法;
(4)退化的三角形(即两边之和等于第三边),包括三种不同排列方法;(5)三条边不能构成三角形(即两边之和小于第三边),包括三种不同排列方法;(6)一条边的长度为零,包括三种不同排列方法;(7)两条边的长度为零,包括三种不同排列方法;(8)三条边的长度为零;(9)输入数据中包含负整数;
(10)输入数据不全(不足三个正整数);(11)输入数据中包含非整数型的数据。为了测试上述11种情况,设计出的测试数据列在表7.1中:
表7.1程序TRIANGLE的测试数据等边
10,10,10-,-,--,-,-等腰
10,10,1710,17,1017,10,10不等边
8,10,128,12,1010,12,8非三角形
10,10,2110,21,1021,10,10退化情况
10,5,55,10,55,5,10零数据
0,0,0-,-,--,-,-0,0,170,17,017,0,00,10,1212,0,1012,10,0负数据
-10,-10,-10-,-,--,-,--10,-10,17-10,17,-1017,-10,-10-8,10,1717,-8,1010,17,-8遗漏数据
-,-,--,-,--,-,-10,-,--,10,--,-,108,10,-8,-,10-,8,10无效数据
A,B,C-,-,--,-,-=,+,*-,-,--,-,-8,10,A8,A,10A,8,107E3,10.5,A10.5,7E3,AA,10.5,7E3测试功能测试数据abc开始A<B+CB<A+CC<A+BA=BB=CA=CB=C印出“不是三角形”印出“等边三角形”印出“等腰三角形”印出“不等边三角形”停止F10F11FaabcdF14F15F1612345678TTTTTTTT171819202213hjgpn12ilefo21Fkm图7.8程序TRIANGLE的流程图abcdefgkhijlopmn123456782312141520161718212219图7.9和图7.8对应的程序图
表7.2测试数据覆盖程度检验表110,10,101,2,3,4,5,6,7,82a10,10,171,2,3,4,5,15,19,20,82b10,17,101,2,3,4,14,18,19,20,82c17,10,101,2,3,4,14,16,17,19,20,83a8,10,121,2,3,4,14,16,21,22,83b8,12,101,2,3,4,14,16,21,22,83c10,12,81,2,3,4,14,16,21,22,84a10,10,211,2,3,11,12,13,84b10,21,101,2,10,12,13,84c21,10,101,9,12,13,8编号测试数据覆盖的边7.8调试
测试本身的目的是尽可能多地暴露程序中的错误,但是,发现错误的最终目的还是为了改正错误。在成功地测试之后,必须进一步诊断和改正程序中的错误,这就是调试的任务。调试过程由两个步骤组成,它从表示程序中存在错误的某些迹象开始,首先确定错误的准确位置,也就是找出是哪个模块或哪些接口引起的错误;然后,仔细研究这段代码以确定问题的原因。其中第一个步骤所需工作量约占调试总工作量的95%。7.8.1调试过程
7.8.2调试途径常用的调试策略主要由:
1.试探法调试人员分析错误征兆,猜想错误的大致位置,然后使用前述的调试技术,获取程序中被怀疑的地方附近的信息。
2.回溯法调试人员检查错误征兆,确定最先发现“症状”的位置,然后人工沿程序的控制流往回追踪源程序代码,直到找出错误根源或确定故障范围为止。
3.对分查找法类似于数据结构中介绍的“折半查找”的方法。
4.归纳法所谓归纳法就是从个别推断一般的方法。这种方法从线索(错误征兆)出发,通过分析这些线索之间的关系而找出故障,这种方法主要有下述四个步骤:(1)收集有关的数据列出已经知道的关于程序哪些事做得对那些事做得不对的一切数据。
(2)组织数据在这一步特别重要是发现矛盾,即什么条件下出现错误,什么条件下不出现错误。(3)导出假设分析研究线索之间的关系,力求找出它们的规律,从而提出关于故障的一个或多个假设。
(4)证明假设假设不等于事实。证明假设的合理性是极端重要的,不经证明就根据假设排除故障,往往只能消除错误的征兆或只能改正部分错误。证明假设的方法是,用它解释所有原始的测试结果。如果能圆满地解释一切现象,则假设得到证实,否则要么是假设不成立或不完备,要么是有多个故障同时存在。
下图说明了归纳法的调试过程:收集有关数据组织数据研究数据间的关系提出假设排除故障证明假设不能不能能能
5.演绎法所谓演绎法就是从一般原理或前提出发,经过删除和精化的过程推导出结论。用演绎法调试开始先列出所有看来可能成立的原因或假设,然后一个一个地排除列举出的原因,最后
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 浙江省浙南名校联盟2025-2026学年高一上学期11月期中考试生物试题(解析版)
- 2026年四川遂宁数学中考真题(解析版)
- 某纺织厂棉花采购准则
- 某塑料厂生产细则
- 某铝业厂生产安全准则
- 2026天津市南开区美达菲津英中学招聘模拟试卷及答案详解(有一套)
- 2026年张浦镇公开招聘编外工作人员11人简章参考题库及答案详解(真题汇编)
- 2026陕西西安市高陵区市场监督管理局公益性岗位招聘3人参考题库附参考答案详解(A卷)
- 2026江苏徐州医科大学招聘体育专任教师2人模拟试卷及答案详解(各地真题)
- 2026年六安皖西学院公开招聘工作人员18名参考题库(基础题)附答案详解
- 2026年长沙商贸旅游职业技术学院单招职业倾向性测试题库及参考答案详解
- 2026年湖南普通高中学业水平选择性考试历史真题【含答案】
- 2026甘肃省农垦集团有限责任公司招聘生产技术人员78人备考题库及1套完整答案详解
- 2026四川富润企业重组投资有限责任公司应届毕业生招聘4人备考题库含答案详解
- 电梯安装工程技术资料-电梯竣工资料
- 东方福利网人才测评题
- 人教版六年级下册语文《期末》考试卷及答案下载
- 2026年广东广州市地理生物会考试题题库(答案+解析)
- 甘肃省天水市某中学2024-2025学年高一年级上册期末模拟考试生物试题(解析版)
- 九年级语文下册 12《渔家傲·秋思》
- 市政排污口整治与监测技术方案
评论
0/150
提交评论