




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
项目七开源网络硬盘系统测试7.1问题情境7.2问题分析7.3任务设计与实施7.4知识总结7.5应用实践
有一个开源网络硬盘系统,完成对该系统中部分模块代码的单元测试以及系统的集成测试和压力测试。7.1问题情境
分析系统功能,系统由文件目录维护(新建目录、压缩目录、解压缩、剪切、复制、粘贴)、文件上传、文件下载三个功能模块组成,如图7-1所示。应先完成对每个模块类文件中独立函数的单元测试,再完成对系统核心类——FileAction类中函数调用功能的集成测试,最后完成对系统的压力测试。7.2问题分析图7-1系统运行截图
7.3.1设计完成系统部分模块的单元测试
测试程序开发运行环境:MyEclipse6.6
+
Resin4.1
+
JDK1.5_18
+
Junit4.4。选择packagecom.lhq.prj.dd.core包下的MyUtils类文件作为单元测试类。本例中对isFileExist()方法进行单元测试,建立测试用例。目标函数源代码如下:
/**7.3任务设计与实施 *判断文件是否存在
*
*@paramfileName
*@paramdir
*@returnboolean
*/
public
static
booleanisFileExist(StringfileName,Stringdir){
Filefiles=newFile(dir+fileName);
return(files.exists())?true:false;
}对源代码分析如下:此方法中返回值为boolean类型,有两个分支,即true和false。因此,单元测试需对两条分支分别进行测试。
(1)假设在本地D盘根目录下存在文件jdbcurl.txt,编写测试用例代码如下:
packagecom.lhq.prj.dd.core.test;
importorg.junit.After;
importorg.junit.AfterClass;
importorg.junit.Assert;
importorg.junit.Before;
importorg.junit.Test;
importcom.lhq.prj.dd.core.MyUtils;
public
classMyUtilsTest{
StringfileName;
Stringdir;
@AfterClass
public
static
voidtearDownAfterClass()throwsException{
}
@Before
public
voidsetUp()throwsException{
fileName="jdbcurl.txt";
dir="D:\\";
}
@After
public
voidtearDown()throwsException{
}
@Test
public
final
voidtestIsFileExist(){
//fail("Notyetimplemented");//TODO
Assert.assertTrue(MyUtils.isFileExist(fileName,dir));
}
}
运行测试用例,如图7-2所示。图7-2运行测试开始图7-3测试通过
(2)另外一种情况是,测试本地D盘根目录下不存在的文件test.txt。测试用例代码MyUtilsTest.java如下:
packagecom.lhq.prj.dd.core.test;
importorg.junit.After;
importorg.junit.AfterClass;
importorg.junit.Assert;
importorg.junit.Before;
importorg.junit.Test;
importcom.lhq.prj.dd.core.MyUtils;
public
classMyUtilsTest{
StringfileName;
Stringdir;
@AfterClass
public
static
voidtearDownAfterClass()throwsException{
}
@Before
public
voidsetUp()throwsException{
//fileName="jdbcurl.txt";
fileName="test.txt";
dir="D:\\";
}
@After
public
voidtearDown()throwsException{
}
@Test
public
final
voidtestIsFileExist(){
//fail("Notyetimplemented");//TODO
Assert.assertFalse(MyUtils.isFileExist(fileName,dir));
}
}图7-4测试失败7.3.2设计完成系统的集成测试
本例中需设计并完成对系统中FileAction类的集成测试。为了脱离J2EE容器进行孤立测试,本例中使用EasyMock结合JUnit进行集成测试。
EasyMock主要是为测试提供模拟数据,比如可以模拟HttpServletRequest。使用EasyMock的一般步骤为:
(1)创建一个mock对象;
(2)设置此对象的某个方法的返回值;
(3)保存被mock的对象;
(4)应用mock对象;
(5)验证所设置的mock对象是否按预期运行。
分析FileAction类的源代码,代码涉及父类BaseAction及MyUtils工具类。以createFolder()函数和deleteFiles()函数为例编写测试用例代码FileActionTest.java如下:
packagecom.lhq.prj.dd.action;
importorg.junit.After;
importorg.junit.AfterClass;
importorg.junit.Before;
importorg.junit.Test;
importorg.junit.Assert;
importorg.easymock.classextension.EasyMock;
importorg.easymock.classextension.EasyMockSupport;
importcom.lhq.prj.dd.action.FileAction;
importcom.opensymphony.xwork2.ActionSupport;
public
classFileActionTestextendsEasyMockSupport{
FileActionfileActionObj;
FileActionfileActionObj2;
@AfterClass
public
static
voidtearDownAfterClass()throwsException{
}
@Before
public
voidsetUp()throwsException{
fileActionObj=EasyMock.createMockBuilder(FileAction.class).addMockedMethods("getRootPath","getName","getPath").createMock();
fileActionObj2=EasyMock.createMockBuilder(FileAction.class).addMockedMethod("getRootPath").createMock();
}
@After
public
voidtearDown()throwsException{
}
@Test
public
final
voidtestCreateFolder()throwsException{
//fail("Notyetimplemented");//TODO
EasyMock.expect(fileActionObj.getRootPath()).andReturn("D:\\resin-4.0.1\\webapps\\
dogdisk\\");
EasyMock.expect(fileActionObj.getName()).andReturn("test");
EasyMock.expect(fileActionObj.getPath()).andReturn("");
EasyMock.replay(fileActionObj);
Assert.assertEquals(ActionSupport.SUCCESS,fileActionObj.createFolder());
EasyMock.verify(fileActionObj);
}
@Test
public
final
voidtestDeleteFiles()throwsException{
EasyMock.expect(fileActionObj2.getRootPath()).andReturn("D:\\resin-4.0.1\\webapps\\
dogdisk\\");
fileActionObj2.setPaths(newString[]{"test2","test3"});
EasyMock.replay(fileActionObj2);
Assert.assertEquals(ActionSupport.SUCCESS,fileActionObj2.deleteFiles());
EasyMock.verify(fileActionObj2);
}
}测试之前,在目录D:\resin-3.1.9\webapps\dogdisk\root下创建文件夹test2和test3,作为deleteFiles()函数的测试文件夹,如图7-5所示。图7-5执行测试前的目录结构对createFolder()函数执行testCreateFolder()进行测试,如图7-6所示。在D:\resin-3.1.9\webapps\dogdisk\root目录下创建test目录,如图7-7所示。对deleteFiles()函数执行testDeleteFiles()进行测试,删除D:\resin-3.1.9\webapps\dogdisk\root目录下的test2和test3目录。执行测试结果如图7-8所示。图7-6执行测试程序图7-7执行测试后的目录结构图7-8执行测试后的结果7.3.3设计完成系统的压力测试
JMeter是Apache组织的开放源代码的工具,它是功能和性能测试的工具,最新的版本是1.9.1,可以到/jmeter/index.html下载源代码并查看相关文档。
JMeter可以用于测试静态或者动态资源(文件、Servlets、Perl脚本、java对象、数据库和查询、ftp服务器或者其他的资源)的性能。JMeter用于测试在服务器、网络或者其他对象上附加高负载后这些对象的受压能力,或者分析它们提供的服务在不同负载条件下的总性能情况。用户可以用JMeter提供的图形化界面分析性能指标或者在高负载情况下测试服务器/脚本/对象的行为。
使用JMeter测试Web应用的步骤如下:
第一步:准备测试环境。本书中使用Resin作为Web服务器进行测试,被测试的内容是上述系统的首页。
第二步:安装启动JMeter。可以到/site/downloads/downloads_
jmeter.cgi下载JMeter的release版本,然后将下载的.zip文件解压缩到D:/jakarta-jmeter-2.3.4目录下。接着使用
%jakarta-jmeter-2.3.4%/bin下面的jmeter.bat批处理文件来启动JMeter的可视化界面,下面的工作都将在这个可视化界面上进行操作。JMeter的可视化界面的屏幕截图如图7-9所示。图7-9JMeter的可视化界面第三步:建立测试计划(TestPlan)。测试计划描述了执行测试过程中JMeter的执行过程和步骤。一个完整的测试计划包括一个或者多个线程组(ThreadGroups)、逻辑控制(LogicController)、实例产生控制器(SampleGeneratingControllers)、侦听器(Listener)、定时器(Timer)、比较(Assertions)、配置元素(ConfigElements)。打开JMeter时,它已经建立了一个默认的测试计划。一个JMeter应用的实例只能建立或者打开一个测试计划。现在开始填充一个测试计划的内容,这个测试计划向一个jsp文件和一个servlet发出请求,我们需要JMeter模拟五个请求者(也就是五个线程),每个请求者连续请求两次,下面几步是详细的操作步骤。
第四步:增加负载信息设置。向测试计划中增加相关负载设置,让Jmeter知道需要模拟五个请求者,每个请求者在测试过程中连续请求两次。详细步骤为:选中可视化界面中左边树的测试计划节点,单击右键,选择添加—线程组,界面右边将会出现设置信息框。线程组有如下三个和负载信息相关的参数:
(1)线程数:设置发送请求的用户数目。
(2)
Ramp-UpPeriod:每个请求发生的总时间间隔,单位是秒。若请求数目是5,而这个参数是10,那么每个请求之间的间隔就是10/5,也就是2秒。
(3)循环次数:请求发生的重复次数。如果选择后面的“永远”(默认),那么请求将一直继续;如果不选择“永远”,而在输入框中输入数字,那么请求将重复指定的次数;如果输入0,那么请求将被执行一次。根据任务要求的设计,我们应该将线程数设置为5,Ramp-UpPeriod设置为0(也就是同时并发请求),不选中“永远”,在循环次数后面的输入框中输入2,设置后的屏幕截图如图7-10所示。图7-10设置好参数的线程组第五步:增加默认HTTP属性。实际的测试工作往往是针对同一个服务器上的Web应用展开的,所以Jmeter提供了这样一种设置:在默认HTTP属性中设置需要被测试服务器的相关属性,在以后的HTTP请求设置中就可以忽略这些相同参数的设置,以减少设置参数录入的时间。
可以通过下面的步骤来设置默认HTTP属性:
(1)选中可视化界面中左边树的测试计划节点,单击右键,选择添加—配置元件—请求默认值,界面右边将会出现设置信息框。
(2)默认HTTP属性的主要参数:
服务器名称或IP:被测试服务器的IP地址或者名称。
端口号:服务器提供服务的端口号。
Connect:连接超时时间(毫秒)。
Response:响应超时时间(毫秒)。
协议:发送测试请求时使用的协议。
contentencoding:字符集设置。
路径:默认的起始位置。比如将路径设置为/diskdog,那么所有的HTTP请求的url中都将增加
/diskdog路径。
测试计划将针对本机的Web服务器上的Web应用进行测试,所以协议应该是http,IP使用localhost。因为这个Web应用发布的context路径是
/diskdog,所以这里的路径设置为/diskdog,因为使用Tomcat服务器,所以端口号是8080。设置后的屏幕截图如图7-11所示。图7-11测试计划中使用的默认HTTP参数第六步:增加HTTP请求。现在需要增加HTTP请求,这是测试的内容主体部分。可以通过下面的步骤来增加HTTP请求:
(1)选中可视化界面中左边树的ThreadGroup节点,单击右键,选择添加—sampler—HTTP请求,界面右边将会出现设置信息框。
(2)增加的属性中有发送HTTP时方法的选择,可以选择为GET或者POST。我们现在增加一个HTTP请求,由于已经设置了默认的HTTP属性,所以和默认HTTP属性中相同的属性不再重复设置。设置后的屏幕截图如图7-12所示。图7-12设置好的jsp测试请求第七步:增加Listener。增加listener是为了记录测试信息,并且可以使用Jmeter提供的可视化界面查看测试结果。其中有多种结果分析方式可供选择,可以根据自己习惯的分析方式选择不同的结果显示方式,这里使用表格的形式来查看和分析测试结果。读者可以通过下面的步骤来增加listener:
(1)选中可视化界面中左边树的测试计划节点,单击右键,选择添加—监听器—用表格查看结果,界面右边将会出现设置信息和结果显示框。
(2)可以通过界面上面的文件名属性设置,将测试结果保存到某个文件中,界面下面将使用表格显示测试结果。
在界面的最下面还可以看到一些统计信息,最关心的应该是Average,也就是相应的平均时间。
第八步:开始执行测试计划。可以通过单击菜单栏运行—启动,开始执行测试计划。图7-13和图7-14分别是第一次、第二次执行该测试计划的结果。图7-13第一次执行后的结果显示图7-14第二次执行后的结果显示从上面两幅图中可以看到,第一次执行时的几个时间较长,这是由于jsp执行前都需要被编译成
.class文件,所以第二次执行的结果才是正常的结果。
JMeter用于进行功能或者性能测试,通过使用JMeter提供的功能,我们可以可视化地制定测试计划,包括规定使用什么样的负载、测试什么内容、传入什么参数。同时,它也提供了多种图形化的测试结果显示方式,使我们能够简便地开始测试工作并分析测试结果。
7.4.1单元测试
下面举例说明单元测试。
假如写了如下的加法函数:
intadd(inta,intb)
{7.4知识总结
returna-b;
}
该函数可实现两数相加,并得到结果。例如输入两个1,就会返回它们的和2,编写其驱动程序并执行。
voidtest_add()
{
inta=1;
intb=1;
intret=add(a,b);
ASSERT(ret==2);
}
intmain()
{
test_add();
}
该函数的执行结果不是2,而是0,说明此函数存在错误。
1.引言
单元测试是在软件开发过程中要进行的最低级别的测试活动。在单元测试活动中,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。
在传统的结构化编程语言,比如C语言中,要进行测试的单元一般是函数或子过程。在像C++这样的面向对象的语言中,要进行测试的基本单元是类。对Ada语言来说,开发人员可以选择是在独立的过程和函数上还是在Ada包的级别上进行单元测试。单元测试的原则同样被扩展到第四代语言(4GL)的开发中,在这里基本单元被典型地划分为一个菜单或显示界面。单元测试不仅仅作为无错编码的一种辅助手段在一次性的开发过程中使用,而且在软件修改或是移植到新的运行环境的过程中还将重复使用。因此,所有的测试都必须在整个软件系统的生命周期中进行维护。
单元测试(模块测试)是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否正确。通常而言,一个单元测试用于判断某个特定条件(或者场景)下某个特定函数的行为。例如,可能把一个很大的值放入一个有序列表中去,然后确认该值出现在列表的尾部;或者可能会从字符串中删除匹配某种模式的字符,然后确认字符串确实不再包含这些字符了。不同情况下单元的概念有以下几种:
“单元”:明确的功能、规格定义,明确的与其他部分的接口定义;
结构化程序设计:函数或子过程;
面向对象:类或类的方法;
一个菜单、屏幕显示界面或对话框等。
经常与单元测试联系起来的另外一些开发活动包括代码走读(CodeReview)、静态分析(StaticAnalysis)和动态分析(DynamicAnalysis)。静态分析就是对软件的源代码进行研读,查找错误或收集一些度量数据,并不需要对代码进行编译和执行。动态分析就是通过观察软件运行时的动作来提供执行跟踪、时间分析以及测试覆盖度方面的信息。
2.单元测试的定义
单元测试也称模块测试,是针对最小的可测试软件元素——模块进行正确性检验的测试工作,其目的在于发现各模块内部可能存在的各种差错。单元测试的依据是详细设计描述。单元测试的内容包括单元的内部结构(如逻辑和数据流)以及单元的功能和可观测的行为。通常,我们使用白盒测试方法测试单元的内部结构,使用黑盒测试方法测试单元的功能和可观测的行为。
3.单元测试的原因
在编写代码时,一定会反复调试以保证它能够编译通过。如果代码未通过编译,没有任何人会愿意将其交付给负责人。但即使代码通过了编译,只是说明它的语法正确,却无法保证它的语义也一定正确,即这段代码的行为一定是正确的。
4.单元测试的特点
(1)单元测试是一种验证行为。程序中的每一项功能都通过单元测试来验证它的正确性,它为以后的开发提供支援。就算是开发后期,我们也可以轻松地增加功能或更改程序结构,而不用担心在这个过程中会破坏重要的东西。而且它为代码的重构提供了保障。这样,我们就可以更好地对程序进行改进。
(2)单元测试是一种设计行为。编写单元测试将使我们从调用者的角度观察、思考。特别是先写测试(testfirst),迫使我们把程序设计成易于调用和可测试的,即迫使我们解除软件中的耦合。
(3)单元测试是一种编写文档的行为。单元测试所编写的文档是一种无价的文档,是展示函数或类如何使用的最佳文档。这份文档是可编译、可运行的,并且它能保持是最新的,永远与代码同步。
(4)单元测试具有回归性。自动化的单元测试避免了代码回归。单元测试脚本编写完成之后,可以快速运行测试。
5.单元测试的范畴
如果要给单元测试定义一个明确的范畴,指出哪些功能属于单元测试,这似乎很难。但下面讨论的四个问题,基本上可以说明单元测试的范畴,即单元测试所要做的工作。
(1)单元测试的行为和期望的一致吗?这是单元测试最根本的目的,我们就是用单元测试的代码来证明它所做的就是我们所期望的。
(2)单元测试的行为一直和期望的一致吗?编写单元测试程序,如果只测试代码的一条正确路径,让它正确走一遍,并不算是真正的完成。软件开发是一项复杂的工程,在测试某段代码的行为是否和期望的一致时,需要确认:在任何情况下,这段代码是否都和期望一致,譬如在参数很可疑、硬盘没有剩余空间、缓冲区溢出、网络掉线的情况下。
(3)可以依赖单元测试吗?不能依赖的代码是没有多大用处的。既然单元测试是用来保证代码的正确性的,那么单元测试也一定要值得依赖。
(4)单元测试说明意图了吗?单元测试能够帮助测试人员充分了解代码的用法。从效果上看,单元测试就像是能执行的文档,它说明了在用各种条件调用代码时,期望这段代码完成的功能。
6.单元测试环境
单元测试环境建立的原因是由于一个模块或一个方法与外界的联系是必然的。在单元测试时,如果模块不是独立的程序,则需要辅助测试模块。
辅助模块有两种:
(1)驱动模块:所测模块的主程序。它接收测试数据,再把这些数据传递给所测试模块,最后输出实测结果。当被测试模块能完成一定功能时,也可以不要驱动模块。
(2)桩模块:用来代替所测模块调用的子模块。
被测试模块、驱动模块和桩模块共同构成了一个测试环境,如图7-15所示。
图7-15单元测试环境
7.单元测试策略
1)自顶向下的单元测试策略
步骤:
(1)从最顶层开始,把顶层调用的单元做成桩模块。
(2)对第二层进行测试,使用上面已测试的单元做驱动模块。
(3)依此类推,直到全部单元测试结束。优点:它可以在集成测试之前为系统提供早期的集成途径。由于详细设计一般都是自顶向下进行设计的,因此自顶向下的单元测试策略在执行上同详细设计的顺序一致。该测试方法可以和详细设计及编码进行重叠操作。缺点:
(1)单元测试被桩模块控制,随着单元一个一个被测试,测试过程将变得越来越复杂,并且测试和维护成本都将不断增加。
(2)低层次的结构覆盖率难以得到保证。
(3)更改任何一个单元时,就必须重新测试该单元下层调用的所有单元(因为上层驱动改变)。
(4)底层单元的测试必须等待顶层单元测试完毕后才能进行,无法进行并行测试,测试周期将被延长。
总结:自顶向下的单元测试策略要做桩模块,其成本要高于孤立的单元测试成本,因此从测试成本方面来考虑,它并不是最佳的单元测试策略。
2)自底向上的单元测试策略
步骤:
(1)先对模块调用图上的最底层模块进行测试,模拟调用该模块的模块为驱动模块。
(2)对上一层模块进行单元测试,用已经被测试过的模块做桩模块。
(3)依此类推,直到全部单元测试结束。
优点:不需要单独设计桩模块。
缺点:
(1)随着单元测试的不断进行,测试过程会变得越来越复杂,测试周期延长,测试和维护的成本都将增加。
(2)随着各个基本单元的逐步加入,系统会变得异常庞大,因此测试人员不容易控制。
(3)越接近顶层的模块的测试其结构覆盖率就越难以保证。
(4)任何一个模块修改之后,直接或间接调用该模块的所有单元都要重新测试(因为调用的下层程序改变)。
(5)并行性不好。
(6)不能和详细设计、编码同步进行。
3)孤立测试
步骤:不考虑每个模块与其他模块之间的关系,分别为每个模块单独设计桩模块和驱动模块,逐一完成所有单元模块的测试。优点:简单、容易操作,因此所需测试时间短,能够达到高覆盖率。
缺点:不能为集成测试提供早期的集成途径,而且依赖结构设计信息,需要设计多个桩模块和驱动模块,增加了额外的测试成本。
总结:该方法是比较理想的单元测试方法,如再辅助以适当的集成测试策略,有利于缩短项目的开发时间。
4)综合测试
在单元测试中,为了有效地减少开发桩模块的工作量,可以考虑综合自底向上测试策略和孤立测试策略。
8.单元测试分析
从如下几方面进行分析和测试:
(1)判断得到的结果是否正确。
(2)判断是否满足所有的边界条件,包括:
输入一个格式错误的数据。
提供一个空值或者不完整的值。
输入与意料之中的值相差很远的值。
若要求唯一,可以输入两个或多个相同的数值来进行测试。
如果要求按照一定的顺序来存储一些数据,那么可以输入一些顺序打乱的数据来做测试。
对于一些做了安全限制的部分,尽量通过各种途径尝试能否绕过安全限制的测试。例如,ATM取款未输入密码,能否显示余额和取款。
如果功能的启用有一定的顺序限制,就用和期望不一致的顺序来进行测试。
(3)分析能否使用反向关联检查。例如,检查插入功能是否正确,可以使用查询验证。
(4)分析是否能使用其他手段来交叉检查一下结果。一般而言,对某个值进行计算会有一种以上的算法,但我们会因考虑运行效率或其他方面的原因而选择其中的一种,例如判断三角形全等。
(5)分析是否可以强制一些错误发生,例如网络故障、内存不足、磁盘空间不足等。
(6)分析模块接口,例如在数据能正确流入、流出模块的前提下,其他测试才有意义。
(7)分析局部数据结构。
(8)分析独立路径,保证每条语句至少被执行一次。
(9)分析出错处理是否正确,预设各种出错处理通路。
9.单元测试用例设计
(1)测试的完整性度量以白盒测试为主:
语句覆盖(100%);
判定覆盖(100%);
条件覆盖;
判定/条件覆盖;
路径覆盖(主要)。
(2)测试用例的四个关键元素:
初始状态声明;
输入数据;
实际测试的代码;
期望输出结果。
1)测试用例设计步骤
步骤1:使被测单元运行,(尽量简单)适合的技术有下面两种:
由模块设计说明导出测试;
对等区间划分。
步骤2:正面测试(PositiveTesting),适合的技术有下面三种:
由设计说明导出测试;
对等区间划分;
状态转换测试。
步骤3:负面测试(NegativeTesting),适合的技术有以下四种:
错误猜测;
边界值分析;
内部边界值测试;
状态转换测试。步骤4:模块设计需求中其他测试用例的设计,例如性能、余量、安全等。
步骤5:覆盖率测试用例设计,适合的技术有以下四种:
分支测试;
条件测试;
数据定义——使用测试;
状态转换测试。
步骤6:测试执行。
步骤7:完善代码覆盖,适合的技术有下面四种:
分支测试;
条件测试;
设计定义——试验测试;
状态转换测试。
2)面向对象应用程序的单元测试用例设计
(1)功能性测试,有以下两种:
类的规格说明(概念和方法);
方法的规格说明(前置/后置条件)。
(2)结构性测试,类作为一个单元来进行测试,有以下两种:
方法的单独测试;
方法的综合测试。
3)基于对象—状态转移图的OO软件测试
节点:表示对象的某个可能状态;
有向边:事件/动作。
如图7-16所示,当对象处于状态A时,若接收到事件e,则执行相应的操作a并转移到状态B。
图7-16对象—状态转换图
(1)状态的处理。列出对象的逻辑状态,而非所有实际状态。理论上,所有数据成员状态的笛卡尔积都应列出,实际上不可能全部列出,类似等价类划分。
(2)主要步骤。
依据设计文档,或者通过分析对象数据成员的取值情况空间,得到被测试类的状态转移图。
给被测试的类加入用于设置和检查对象状态的新方法,例如set()、get()等,导出对象的逻辑状态。
确定状态转移图中的每个状态是哪些方法的合法起始状态,即在该状态时,对象允许执行哪些操作。
在每个状态,从类中方法的调用关系图最下层开始,逐一测试类中的方法。
测试每个方法时,根据对象的当前状态确定对方法的执行路径有特殊影响的参数值,将各种可能组合作为参数进行测试。
4)类的数据流测试
类的数据流测试是一种白盒测试方法,它利用程序的数据流之间的关系来指导测试的选择。对类的数据流应进行三级测试,定义如下:
(1)方法内部测试:测试单个方法,相当于单元测试。
(2)方法间测试:在类中测试一个直接或间接调用的公开方法,相当于集成测试。
(3)类内部测试:测试公开方法在各种调用顺序时的相互作用关系,只能测试其中一个子集。
图7-17单元测试过程
10.单元测试过程单元测试过程包括以下环节:
(1)准备阶段:培训、环境、工具、测试用例等。
(2)代码编制阶段:编码、测试用例的修改等。
(3)代码审查阶段:各种语法检查和算法逻辑等。
(4)单元测试阶段:执行测试用例,并记录测试结果。
(5)评审、提交阶段:评审结论、提交相关文档。
11.单元测试内容
单元测试内容如图7-18所示。
图7-18单元测试内容
1)模块接口测试
模块接口测试是单元测试的基础。只有在数据能正确流入、流出模块的前提下,其他测试才有意义。
测试接口正确与否应该考虑下列因素:
输入的实际参数与形式参数的个数是否相同;
输入的实际参数与形式参数的属性是否匹配;
输入的实际参数与形式参数的量纲是否一致;
调用其他模块时所给实际参数的个数是否与被调模块的形参个数相同;
调用其他模块时所给实际参数的属性是否与被调模块的形参属性匹配;
调用其他模块时所给实际参数的量纲是否与被调模块的形参量纲一致;
调用预定义函数时所用参数的个数、属性和次序是否正确;
是否存在与当前入口点无关的参数引用;
是否修改了只读型参数;
各模块对全程变量的定义是否一致;
是否把某些约束作为参数传递。如果模块内包括外部输入/输出,还应该考虑下列因素:
文件属性是否正确;
OPEN/CLOSE语句是否正确;
格式说明与输入/输出语句是否匹配;
缓冲区大小与记录长度是否匹配;
文件使用前是否已经打开;
是否处理了文件尾;
是否处理了输入/输出错误;
输出信息中是否有文字性错误。
2)局部数据结构测试
检查局部数据结构是为了保证临时存储在模块内的数据在程序执行过程中完整、正确。局部数据结构往往是错误的根源,应仔细设计测试用例,力求发现以下几类错误:
不合适或不相容的类型说明;
变量无初值;
变量初始化或缺省值有错;
不正确的变量名(拼错或不正确地截断);
出现上溢、下溢和地址异常。
3)独立路径测试
在模块中应对每一条独立执行路径进行测试。此时,设计测试用例是为了发现因错误计算、不正确的比较和不适当的控制流造成的错误。独立路径测试和循环测试是最常用且最有效的测试技术。
4)错误处理测试
一个好的设计应能预见各种出错条件,并预设各种出错处理通路。出错处理通路需要认真测试,测试应着重检查下列问题:
输出的出错信息是否难以理解;
记录的错误与实际遇到的错误是否相符;
在程序自定义的出错处理运行之前,系统是否已介入;
异常处理是否得当;
错误陈述中是否能提供足够的定位出错信息。
5)边界条件测试边界条件测试是单元测试中最后也是最重要的一项任务,因为软件经常在边界上失效。采用边界值分析技术,针对边界值及其左右值设计测试用例,即检查以下几种情况:
在n次循环的第0次、1次、n次是否有错误;
运算或判断中取最大值、最小值时是否有错误;
数据流、控制流中刚好等于、大于、小于确定的比较值是否出现错误。
12.单元测试学习中的一些误区
(1)很多人认为单元测试浪费了太多的时间。在许多项目设计过程中,一旦编码完成,开发人员总是迫切希望进行软件的集成工作,因为这样就能够很快看到整个系统的工作情况了。因而像单元测试这样的活动往往不被重视,甚至有时也许会被忽略。然而没有进行单元测试的系统能够正常工作的可能性是很小的,因为没有经过单元测试的系统充满了各式各样的Bug。在实际软件开发过程中,这样一种忽略单元测试的开发步骤常常会导致一些严重结果,如软件无法运行,将要花费更多的时间去解决模块中存在的Bug。在单独模块的情况下,这些Bug可能是琐碎和微不足道的,但是在软件集成为一个系统时这些Bug的影响将被放大,进而使得整个系统无法可靠运行。
(2)根据单元代码,确定单元模块做了什么功能。在实际中,程序员们没有为每个单元模块编写详细的规格说明和注释,当需要测试这些没有规格说明和注释的单元模块时,测试人员往往就会犯一个很大的错误:去阅读这些单元代码并找出这些单元模块做了什么样的功能,即测试人员的测试工作是基于已经写好的代码基础之上的,显然这种测试是没有任何说服力的,往往也是不会发现任何Bug的。
正确的测试应该是:针对单元模块应该有一个详细的规格说明,测试应以规格说明为基础,即对单元模块的测试是基于它的规格说明的,而不是基于代码本身的。可是在实际中会出现这样的情况:一个测试人员要面对的是测试一个没有规格说明的单元模块。这时该怎么做呢?首先通过代码注释或是其他途径了解单元模块要完成什么功能,然后针对分析出的单元功能去测试代码是否已经完成了这些功能和是否存在Bug。
(3)能力较强的程序员写出的模块就可以不进行单元测试。在每个开发团队中都存在着一些编程能力较强的程序员,他们非常擅长编程,他们写的软件总能在第一时间运行。所以就有很多人认为这些优秀程序员编写的单元模块就可以不进行单元测试。这样的理解是完全错误的,因为每个人都会犯错误。
(4)反正要进行集成测试,单元测试就可以不用做。这个观点不成立的原因在于规模越大的代码集成意味着复杂度越高。如果软件的单元模块没有事先进行测试,那么开发人员很可能会花费大量的时间仅仅是为了使软件能够运行,而任何实际的测试方案都无法执行。
一旦软件可以运行了,开发人员又要面对这样的问题:在考虑软件全局复杂性的前提下对每个单元进行全面的测试。这是一件非常困难的事情,甚至在创造一种单元调用的测试条件的时候,都要全面考虑单元被调用时的各种入口参数。在软件集成阶段,对单元功能全面测试的复杂程度远远超过独立进行的单元测试过程。不进行单元测试的结果是测试将无法达到它所应该有的全面性,一些缺陷将被遗漏,并且很多Bug将被忽略。7.4.2集成测试
1.集成测试的定义
根据实际情况将程序模块采用适当的集成测试策略组装起来,对系统的接口以及集成后的功能进行正确性检验的测试工作就是集成测试,如图7-19所示。图7-19集成测试集成测试(也叫组装测试或联合测试)是单元测试的逻辑扩展。它的最简单的形式是:将两个已经测试过的单元组合成一个组件,并且测试它们之间的接口。从这一层意义上讲,组件是指多个单元的集成聚合。在现实方案中,许多单元组合成组件,而这些组件又聚合成程序的更大部分。测试方法是测试片段的组合,并扩展进程,将这个模块与其他组的模块一起测试,最后将构成进程的所有模块一起测试。此外,如果程序由多个进程组成,应该分别测试它们,而不是同时测试所有进程。
2.集成测试与软件开发之间的关系
从软件开发与测试V模型可知,集成测试是和软件开发过程中的概要设计阶段相对应的。概要设计的关于整个系统的体系结构就是集成测试的基础,而集成测试也为软件架构中是否有错误和遗漏提供了服务。两者是相辅相成的。
为了使读者更好地了解集成测试与开发的关系,图7-20给出了软件基本结构图。
图7-20软件基本结构图
3.集成测试的重点
(1)各个模块连接起来后,穿过模块接口的数据是否会丢失,是否能够按期望值传递给另外一个模块。
(2)各个模块连接起来后,需要判断是否仍然存在单元测试时未发现的资源竞争问题。
(3)分别通过单元测试的子功能模块集成到一起能否实现所期望的父功能。
(4)检查引入一个模块后,是否对其他与之相关的模块产生负面影响。
(5)全局数据结构是否正确,是否被不正常修改。
(6)集成后,每个模块的误差是否会累计扩大,是否会达到不可接受的程度。
4.集成测试的层次
对于传统软件来说,按集成粒度不同,可以把集成测试分为3个层次,即:
模块内集成测试;
子系统内集成测试;
子系统间集成测试。
对于面向对象应用系统来说,按集成粒度不同,可以把集成测试分为以下两个层次:
类内集成测试;
类间集成测试。
5.如何进行集成测试
(1)体系结构分析。首先跟踪需求分析,划分出系统结构层次图。其次对系统中各个组件之间的依赖关系进行分析,然后据此确定集成测试的粒度,即集成模块的大小。
(2)模块分析。一般可从以下几个角度进行模块分析:
确定本次要测试的模块;
找出与该模块相关的所有模块,并且按优先级对这些模块进行排列;
从优先级最高的相关模块开始,把被测模块与其集成到一起;
依次集成其他模块。
(3)接口分析。接口的划分要以概要设计为基础,一般通过以下几个步骤来完成:
确定系统的边界、子系统的边界和模块的边界;
确定模块内部的接口;
确定子系统内模块间接口;
确定子系统间接口;
确定系统与操作系统的接口;
确定系统与硬件的接口;
确定系统与第三方软件的接口。
(4)风险分析。风险通常被分为以下三种类型:
项目风险:包括项目管理和项目环境的风险。
商业风险:与领域内的相关概念及规则息息相关。
技术风险:针对应用程序的具体实现而言,主要和代码级的测试有关。风险分析是一个定义风险并且找出阻止潜在的问题变成现实的方法的过程。通常把风险分析分为三个阶段:风险识别、风险评估和风险处理。
(5)可测试性分析。必须尽可能早地分析接口的可测试性,提前为后续的测试工作做好准备。
(6)集成测试策略分析。集成测试策略分析的主要任务就是根据被测对象选择合适的集成测试策略。
6.集成测试策略
1)非增量式测试(也称大爆炸集成)
(1)目的。尽可能缩短测试时间,使用最少的测试用例验证系统。
(2)定义。大爆炸集成也称为一次性组装或整体拼装,这种集成测试的做法就是把所有通过单元测试的模块一次性集成到一起进行测试,不考虑组件之间的互相依赖性及可能存在的风险。
(3)方法。举例来说,假设要对某个系统的部分功能(包括四个模块)进行测试,其功能分解如图7-21所示。
具体测试过程如下:
①对模块A进行测试;
②对模块B进行测试;
③对模块C和模块D进行测试;
④把通过单元测试的所有模块组装到一起进行集成测试。
图7-21程序结构图
图7-22大爆炸法示例图
Tests
TestA(withstubsforBandC) //测试模块A,模块B和C为桩模块
TestB(withdriverforAandstubforD) //测试模块B,A为驱动模块,D为桩模块
TestC(withdriverforA) //测试模块C,A为驱动模块
TestD(withdriverforB) //测试模块D,B为驱动模块
Test(A,B,C,D) //集成测试模块A、B、C、D
(4)优点。
可以并行调试所有模块;
需要的测试用例数目少;
测试方法简单、易行。
(5)缺点。
不能对各个模块之间的接口进行充分的测试。
不能很好地对全局数据结构进行测试。
如果一次集成的模块数量多,集成测试后可能会出现大量的错误。另外,修改了一处错误之后,很可能新增更多的错误,新旧错误混杂,给程序的完善带来很大的麻烦。
即使集成测试通过,也会遗漏很多错误。
(6)适用范围。
只需要修改或增加少数几个模块的前期产品稳定的项目。
功能少,模块数量不多,程序逻辑简单,并且每个组件都已经过充分单元测试的小型项目。
基于严格的净室软件工程(由IBM公司开创的开发零缺陷或接近零缺陷的软件的成功做法)开发的产品,并且在每个开发阶段,产品质量和单元测试质量都相当高的产品。
2)自顶向下集成
(1)目的。从顶层控制(主控模块)开始,采用同设计顺序一样的思路对被测系统进行测试,以验证系统的稳定性。
(2)定义。自顶向下的集成测试就是按照系统层次结构图,以主程序模块为中心,自上而下地按照深度优先或者广度优先策略,对各个模块一边组装一边进行测试。
(3)方法。集成测试的过程如下:
把主控模块作为测试驱动,所有与主控模块直接相连的模块作为桩模块。
根据集成的方式(深度优先或者广度优先),逐渐使用实际模块替换相应的下层桩模块;再用桩代替它们的直接下属模块,与已通过测试的模块或子系统组装成新的子系统。在每个模块被集成时,都必须已经通过了单元测试。
进行回归测试(重新执行以前做过的全部或部分测试),以确定集成新模块后没有引入错误。
从上述过程中的第二步开始重复执行,直到所有模块都已经集成到系统中为止。
按深度优先自顶向下集成的示例如图7-23所示(其程序结构图如图7-21所示)。
图7-23深度优先集成过程示意图
图7-24广度优先集成过程示意图
(4)优点。
在测试的过程中,可以较早地验证主要的控制和判断点。
选择深度优先组合方式,可以首先实现和验证一个完整的软件功能,可先对逻辑输入的分支进行组装和测试,检查并克服潜藏的错误和缺陷,验证其功能的正确性,为此后主要分支的组装和测试提供保证。也能够较早地验证功能的可行性,给开发者和用户带来成功的信心。
只有在个别情况下才需要驱动程序(最多不超过一个),减少了测试驱动程序的开发和维护费用。
可以和开发设计工作一起并行执行集成测试,能够灵活地适应目标环境。
容易进行故障隔离和错误定位。
(5)缺点。
在测试时需要为每个模块的下层模块提供桩模块,桩模块的开发和维护费用大。
底层组件的需求变更可能会影响全局组件,需要修改整个系统的多个上层模块。
要求控制模块具有比较高的可测试性。
可能会导致底层模块,特别是被重用的模块测试不够充分。
(6)适用范围。
控制结构比较清晰和稳定的应用程序。
系统高层的模块接口变化的可能性比较小的应用程序。
低层模块接口还未定义或可能会经常因需求变更等原因被修改的应用程序。
控制模块技术风险较大,需要尽可能提前验证的应用程序。
需要尽早看到系统功能行为的应用程序。
在极限编程(ExtremeProgramming)中使用测试优先的开发方法。
3)自底向上集成
(1)目的。从依赖性最小的底层模块开始,按照层次结构图,逐层向上集成,验证系统的稳定性。其示例如图7-25所示。
图7-25自底向上集成示意图
(2)定义。自底向上集成是从系统层次结构图的最底层模块开始进行组装和集成测试的方式。
(3)方法。
从最底层的模块开始组装,组合成一个能够完成制定的软件子功能的构件;
编制驱动程序,协调测试用例的输入与输出;
测试集成后的构件;
使用实际模块代替驱动程序,按程序结构向上组装测试后的构件;
重复上面的第二步,直到系统的最顶层模块被加入到系统中为止。
(4)优点。
即使数据流并未构成有向的非环状图,生成测试数据也没有困难;
可以尽早地验证底层模块的行为;
提高了测试效率;
对实际被测模块的可测试性要求不高;
减少了桩模块的工作量;
容易对错误进行定位。
(5)缺点。
直到最后一个模块加进去之后才能看到整个系统的框架;
只有到测试过程的后期才能发现时序问题和资源竞争问题;
驱动模块的设计工作量大;
不能及时发现高层模块设计上的错误。
(6)适用范围。
底层模块接口比较稳定的产品;
高层模块接口变更比较频繁的产品;
底层模块开发和单元测试工作完成较早的产品。
4)三明治集成
(1)目的。综合利用自顶向下和自底向上两种集成测试策略的优点。
图7-26三明治集成策略示意图
(2)定义。三明治集成是一种混合增值式测试策略,综合了自顶向下和自底向上两种集成方法的优点,因此也属于基于功能分解集成。
(3)方法。首先,确定以哪一层为界来决定使用三明治集成策略(在图7-26中,我们确定以B模块为界)。其次,对模块B及其所在层下面的各层使用自底向上的集成策略。再次,对模块B所在层上面的层次使用自顶向下的集成策略。然后,把模块B所在层各模块同相应的下层集成。最后,对系统进行整体测试。
(4)优点。除了具有自顶向下和自底向上两种集成策略的优点之外,运用一定的技巧,还能够减少桩模块和驱动模块的开发量。
(5)缺点。在被集成之前,中间层不能尽早得到充分的测试。
(6)适用范围。多数软件开发项目都可以应用此集成测试策略。
7.集成测试过程
根据集成测试不同阶段的任务,可以把集成测试划分为五个阶段:计划阶段、设计阶段、实施阶段、执行阶段、评估阶段,如图7-27所示。
图7-27集成测试过程
(1)计划阶段。一般安排在概要设计评审通过后大约一个星期的时候,参考需求规格说明书、概要设计文档、产品开发、计划时间表来制定。
(2)设计阶段。一般在详细设计开始时就可以着手进行。可以把需求规格说明书、概要设计、集成测试计划文档作为参考依据。
(3)实施阶段。在实施的过程中,我们要参考需求规格说明书、概要设计、集成测试计划、集成测试设计等相关文档来进行。
(4)执行阶段。只要所有的集成测试工作准备完毕,测试人员在单元测试完成以后就可以执行集成测试。
(5)评估阶段。当集成测试执行结束后,要召集相关人员对测试结果进行评估,确定软件是否通过集成测试。
8.集成测试环境
在搭建集成测试环境时,可以从以下几个方面进行考虑:
硬件环境;
操作系统环境;
数据库环境;
网络环境;
测试工具运行环境;
其他环境。
9.集成测试用例设计
(1)为系统运行设计用例。可使用的主要测试分析技术包括:
等价类划分法;
边界值分析法;
基于决策表的测试。
(2)为正向测试设计用例。正向集成测试的一个重点就是验证这些集成后的模块是否实现了预期的功能。基于这样的测试目标,我们可以直接根据概要设计文档导出相关的用例。可使用如下几种主要测试分析技术:
输入域测试;
输出域测试;
等价类划分;
状态转换测试;
规范导出法。
在集成测试中的逆向测试包括分析被测接口是否实现了需求规格没有描述的功能,检查规格说明中可能出现的接口遗漏或者判断接口定义是否有错误,以及可能出现的接口异常错误,包括接口数据本身的错误、接口数据顺序错误等。可使用下面几种主要测试分析技术:
错误猜测法;
基于风险的测试;
基于故障的测试;
边界值分析;
特殊值测试;
状态转换测试。
(3)为满足特殊需求设计用例。在大部分软件产品的开发过程中,模块设计文档已经明确地指出了接口要达到的安全性指标、性能指标等。因此应该在对模块进行单元测试和集成测试阶段就测试这些特殊需求是否达到,为整个系统是否能够满足这些特殊需求把关。可使用的主要测试分析技术是规范导出法。
(4)为高覆盖设计用例。与单元测试所关注的覆盖重点不同,在集成测试阶段我们关注的主要覆盖是功能覆盖和接口覆盖,通过对集成后的模块进行分析,来判断哪些功能以及哪些接口没有被覆盖到,并以此设计测试用例。可使用以下两种主要测试分析技术:
功能覆盖分析;
接口覆盖分析。
(5)测试用例补充。在软件开发的过程中,难免会因为需求变更等原因,而有功能增加、特性修改等情况发生。因此,我们不可能在测试工作的一开始就100%完成所有的集成测试用例的设计,这就需要在集成测试阶段能够及时跟踪项目变化,按照需求增加和补充集成测试用例,保证进行充分的集成测试。
(6)注意事项。在集成测试的过程中,要注意考虑软件开发成本、进度和质量这三个方面的平衡。不能顾此失彼,也就是说要重点突出(在有限的时间内进行穷尽的测试是不可能的)。
10.集成测试与系统测试的区别
(1)测试对象:集成测试的测试对象是由通过了单元测试的各个模块所集成起来的组件;而系统测试的测试对象,除了软件之外,还有计算机硬件及相关的外围设备、数据采集和传输机构、计算机系统操作人员等的整个系统。
(2)测试时间:集成测试是介于单元测试和系统测试之间的测试,在测试时间上先于系统测试。
(3)测试方法:集成测试通常会采用灰盒测试,而系统测试通常使用黑盒测试。
(4)测试内容:集成测试的主要内容是各个单元模块之间的接口,以及各个模块集成后所实现的功能;而系统测试的主要内容是整个系统的功能和性能。
(5)测试目的:集成测试的主要目的是发现单元之间接口的错误以及集成后的软件同软件概要设计说明不一致的地方;而系统测试的主要目的是通过与系统需求定义相比较之后发现软件与系统定义不符合或矛盾的地方。
(6)测试角度:集成测试工作的开展更多的是站在测试工作人员的角度上,而系统测试工作的开展更多的是站在用户的角度来进行。
11.集成测试经验总结
集成测试界于单元测试和系统测试之间,不易正确理解和把握。因此,有些项目在开发过程中使用调试的手段把模块或子系统一个一个地集成起来,并用这种办法来替换集成测试,而忽略了正规的集成测试,致使软件中存在很多隐患,因而无法保证质量。
根据以往项目开发和测试的实践,总结了如下几条集成测试的经验:
(1)根据概要设计尽早进行集成测试计划。
(2)要根据项目的实际情况制定一些覆盖率标准,从而根据覆盖率标准来设计足够多的测试用例,然后通过覆盖率分析来衡量集成测试的充分性,补充测试用例,最终使软件质量得到保证。
(3)在选择集成测试策略时,应当综合考虑软件质量、开发成本和开发进度这三个因素之间的关系。
(4)要根据软件的体系结构特点来选取集成测试策略,尽可能减少桩模块和驱动模块开发的工作量,同时还要兼顾是否容易进行软件缺陷定位。
(5)在测试时,可以根据各种集成测试策略的特点把各种集成测试策略结合起来。
(6)在进行模块和接口划分时,尽量与开发人员多沟通。
(7)当因为需求变更或其他原因更改代码时,应对有改动的模块及与其关联的模块进行回归测试。
(8)从集成测试所使用的测试技术角度来说,可以使用黑盒测试。经过覆盖率分析后,可以针对没有覆盖的代码或路径补充一些白盒测试用例。
(9)在必要的时候,例如单独的手工测试无法完成时,可以选用一些适当的集成测试工具。
(10)对容易出错的模块要进行充分的集成测试。7.4.3确认测试
确认测试又称有效性测试。有效性测试是在模拟的环境下,运用黑盒测试的方法,验证被测软件是否满足需求规格说明书列出的需求。其任务是验证软件的功能和性能及其他特性是否与用户的要求一致。对软件的功能和性能要求在软件需求规格说明书中已经明确规定,它包含的信息就是软件确认测试的基础。
通过集成测试之后,软件已完全组装起来,接口方面的错误也已排除,确认测试即可开始。确认测试应检查软件能否按合同要求进行工作,即是否满足软件需求说明书中的确认标准。
1.确认测试的范围
确认测试的范围与集成测试类似,但并不完全按照集成测试内容进行。它们的不同之处在于:
(1)某些已经测试过的纯粹技术性的特点可能不需要再次测试。
(2)对用户特别感兴趣的功能或性能,可能需要增加一些测试方案。
(3)主要使用生产中的实际数据进行测试。
(4)可能需要设计并执行一些与用户使用步骤有关的测试。确认测试必须有用户参加,或以用户为主进行。用户应该参加测试方案设计,分析并评价测试的输出结果。为了使用户能够积极主动地参与确认测试,特别是用户能有效地使用这个系统,通常在验收之前应由开发部门对用户进行培训。
确认测试一般使用黑盒法。测试计划包括要进行的测试种类和进度安排、测试过程及用来检验软件是否与需求一致的测试方案。通过确认测试要保证软件能够满足所有功能要求、性能要求及其他预定的要求(如可移植性、兼容性和可维护性等),文档资料准确而齐全。如果确认测试发现软件的功能或性能与用户的要求有差距,往往是需求分析阶段有差错。此时的问题涉及面广,一般解决起来也很困难。为了解决确认测试过程中发现的软件错误,通常需要和用户充分协商。
2.软件配置复查
软件配置复查是确认过程的一个重要环节。其目的是保证软件配置的所有成分都齐全,各方面的质量都符合要求,文档要与程序一致,具有维护阶段所必需的细节,而且已经编排好目录。这些文档资料包括:用户资料(例如用户手册、操作手册等)、设计资料(例如设计说明书等)、源程序以及测试资料(例如测试说明书、测试报告等)。
除了按合同规定的内容和要求由人工审查软件配置之外,在确认测试的过程中应该严格遵循用户指南以及其他操作程序,以便检验这些使用手册的完整性和正确性。必须仔细记录发现的遗漏或错误,并且适当地进行补充和更正。7.4.4系统测试
1.定义
系统测试是将已经确认的软件、计算机硬件、外设、网络等其他元素结合在一起,进行信息系统的各种组装测试和确认测试。其目的是通过与系统的需求相比较,发现所开发的系统与用户需求不符或矛盾的地方,从而提出更加完善的方案。其任务是尽可能彻底地检查出程序中的错误,提高软件系统的可靠性,并检验系统“做得怎么样”。系统测试是针对整个产品系统进行的测试,测试的对象不仅仅包括需要测试的产品系统的软件,还要包含软件所依赖的硬件、外设甚至包括某些数据、支持软件及其接口等。因此,必须将系统中的软件与各种依赖的资源结合起来,在系统实际运行环境下进行测试。
系统测试的根本任务就是要证明被测系统的功能和结构的稳定性,系统测试中还包括一些非功能测试,如性能测试、压力测试、可靠性测试等。系统测试的最终目的是为了确保软件产品能够被用户或操作者接受。测试的主要目标不再是找出缺陷,而是证明其性能。系统测试属于黑盒测试范畴,不再对软件的源代码进行分析和测试。
2.系统测试的角色和职责
软件测试工程师:制定系统测试计划和方案并组织评审,按照系统测试方案设计测试用例和测试代码,设计所需测试工具,编写测试规程,执行系统测试用例,提交并跟踪缺陷,完成系统测试报告并组织评审,输出测试案例和总结等经验文档。
在系统测试过程中还可能涉及的主要角色包括:
(1)系统分析设计人员:提出系统测试需求,进行测试需求跟踪及软件系统可测性分析,确定系统测试的对象、范围和方法。
(2)开发人员:需要参与系统测试计划和方案的评审,跟踪解决软件测试人员发现的缺陷,评审系统测试报告。
(3)配置管理人员:对系统测试文档进行配置管理。
(4)质量保证人员:对系统测试过程进行审计。
3.系统测试过程
系统测试过程要经历五个阶段,如图7-28所示。
图7-28系统测试过程
(1)计划阶段:制定测试计划。
(2)设计阶段:对系统进行详细的测试分析,然后设计一些典型的、满足测试需求的测试用例,同时给出系统测试的大致过程。
(3)实施阶
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 产后修复中心合同范本
- 劳务代管合同范本
- 加盟托管经营合同范本
- 出租吊车服务合同范本
- 单位代建房合同范例
- 2013版建设合同范本
- 单位监控安装合同范本
- 个人雇佣出海作业合同范本
- 加工货款合同货款合同范本
- 个人山林承包合同范本
- 《ISO 41001-2018 设施管理- 管理体系 要求及使用指南》专业读与应用指导材料之2:“4 组织环境-4.2 理解相关方的需要和期望”
- 2024年中国冻虾仁市场调查研究报告
- DB13(J)-T 8543-2023 公共建筑节能设计标准(节能72%)
- 2024年国家公务员考试行政职业能力测验真题及答案
- 某港口码头工程施工组织设计
- 资产运营总经理岗位职责
- (完整文本版)日文履历书(文本テンプレート)
- 110kV变电站专项电气试验及调试方案
- 2023三年级语文下册 第八单元 语文园地配套教案 新人教版
- 全国川教版信息技术八年级下册第一单元第1节 《设计创意挂件》教学设计
- 2024时事政治必考试题库(预热题)
评论
0/150
提交评论