JUnit单元测试基础基础实验文档格式.docx

上传人:b****5 文档编号:20353865 上传时间:2023-01-22 格式:DOCX 页数:16 大小:255.72KB
下载 相关 举报
JUnit单元测试基础基础实验文档格式.docx_第1页
第1页 / 共16页
JUnit单元测试基础基础实验文档格式.docx_第2页
第2页 / 共16页
JUnit单元测试基础基础实验文档格式.docx_第3页
第3页 / 共16页
JUnit单元测试基础基础实验文档格式.docx_第4页
第4页 / 共16页
JUnit单元测试基础基础实验文档格式.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

JUnit单元测试基础基础实验文档格式.docx

《JUnit单元测试基础基础实验文档格式.docx》由会员分享,可在线阅读,更多相关《JUnit单元测试基础基础实验文档格式.docx(16页珍藏版)》请在冰豆网上搜索。

JUnit单元测试基础基础实验文档格式.docx

使用JUnit设计测试脚本

在Calculator类中添加subtract(),multiply(),divide()后,如何编写手工测试用例和基于JUnit框架的测试用例应该如何编写?

(2)使用默认的TestSuite,显式调用JunitTestRunner

图4:

显式调用JunitTestRunner

/*

*调用由TestRunner自动创建的TestSuite对象

*默认的TestSuite对象将扫描测试类,找出所有以test开头的方法,

*为每一个testXXX方法都创建一个TestCase实例。

*要调用的方法的名称会传给TestCase的构造函数,

*这样每个实例就拥有了一个独一无二的标示。

*/

publicstaticTestSuitesuite(){

returnnewTestSuite(TestCalculatorWithJunit.class);

}

publicstaticvoidmain(String[]args){

//junit.textui.TestRunner.run(TestCalculatorWithJunit.class);

junit.swingui.TestRunner.run(TestCalculatorWithJunit.class);

(3)创建TestAll

缺省的TestSuite设计目的在于让测试人员可以轻松应对简单的测试情形。

但是当要组合多个Suite,把它作为主Suite的一部分,特别是这些suite来自不同的包;

或者要运行多个Suite、在一个Suite中选一些测试来执行……等情况下,这就需要创建自己的suite对象。

JunitFramework中,Test接口如下:

publicinterfaceTest{

/**

*Countsthenumberoftestcasesthatwillberunbythistest.

*/

publicabstractintcountTestCases();

*RunsatestandcollectsitsresultinaTestResultinstance.

publicabstractvoidrun(TestResultresult);

而TestSuite的addTest():

publicvoidaddTest(Testtest){

fTests.addElement(test);

即可以为TestSuite添加TestSuite也可以添加TestCase,这就为创建特殊的suite或者组合出TestAll创造了方便。

通常情况下,TestAll仅仅包括一个静态的suite(),该方法会注册应用程序需要定期执行的所有Test对象(包括TestCase和TestSuite)。

TestAll的suite()方法细节如下:

publicstaticTestsuite(){

TestSuitesuite=newTestSuite("

Alltestswillbeexecuted"

);

suite.addTestSuite(TestCalculatorWithJunit.class);

returnsuite;

}

JUnit单元测试的步骤

1.Junit三重唱

当你需要编写更多的TestCase的时候,你可以创建更多的TestCase对象。

当你需要一次执行多个TestCase对象的时候,您可以创建一个TestSuite对象或使用缺省的TestSuite对象进行封装。

为了执行TestSuite,需要使用TestRunner。

通过TestRunner的执行生成TestResult对象。

(如图5所示)

图5:

JUnit成员三重唱,共同产生测试结果

(1)TestCase测试用例

用户定义的TestCase必须扩展junit.framework.TestCase类,它以testXXX方法的形式包含了一个或多个测试。

一个测试用例把具有公共行为的测试归入一组。

(2)TestSuite测试套装

一个测试套装可以把多个测试用例或测试套装封装为一组

(3)TestRunner测试运行器

测试运行器用来运行测试套装,Junit提供良种典型的测试运行器:

junit.swingui.TestRunner和junit.textui.TestRunner

2.JUnit核心类

JUnit核心类及其简介如下表所示:

表1:

JUnit核心类

3.JUnit单元测试的步骤

(1)重载setUp(),封装测试环境初始化及测试数据准备;

(2)设计测试方法,以testXXX命名。

(3)在测试方法中使用断言方法如assertEquals(),assertTrue()等。

JUnit中断言方法如表2所示。

(4)设计测试套件,或使用缺省的测试套件,调用TestRunner执行测试脚本,生成测试结果;

(5)重载tearDown()析构测试环境,执行收尾动作

表2:

断言方法

assertEquals(expected,actual)

assertEquals(message,expected,actual)

assertEquals(expected,actual,delta)-usedondoublesorfloats,wheredeltaisthedifferenceinprecision

assertEquals(message,expected,actual,delta)-usedondoublesorfloats,wheredeltaisthedifferenceinprecision

assertFalse(condition)

assertFalse(message,condition)

assertNotNull(object)

assertNotNull(message,object)

assertNotSame(expected,actual)

assertNotSame(message,expected,actual)

assertNull(object)

assertNull(message,object)

assertSame(expected,actual)

assertSame(message,expected,actual)

assertTrue(condition)

assertTrue(message,condition)

案例分析

1.三角形问题

设计类Triangle及其测试类TestTriangle,其类图如图6所示。

Triangle中包含三个属性borderA,borderB,borderC,一个构造函数,isTriangle()判断三角形三边是否构成三角形,isType()判断在输入的三边形成三角形的情况下所形成的三角形的具体类型:

等边三角形、等腰三角形还是不等边三角形。

图6:

Triangle及其测试类

TestTriangle类定义如下:

(1)重载setUp()方法,进行测试准备,封装测试的预期结果。

(2)定义测试方法testIsTriangle()和testIsType()

(3)在测试方法中使用断言

(4)定义suite()方法,使用缺省的TestSuite

returnnewTestSuite(TestTriangle.class);

(5)通过缺省的TestSuite调用TestRunner生成测试结果。

//调用SWINGUI或TEXTUI执行测试

//junit.textui.TestRunner.run(TestTriangle.class);

junit.swingui.TestRunner.run(TestTriangle.class);

2.[作业]设计类NextDay,该类包含year,month,day三个属性,该类可以根据用户输入的year,month,day的值输出用户输入日期对应的下一天。

设计NextDay的测试类TestNextDay对其中核心方法,综合使用等价类划分和健壮性测试方法设计测试用例执行单元测试。

建议NextDay结构如图7所示。

图7:

NextDay

3.测试Controller构件

通过上述案例我们已经初步了解了JUnit单元测试的机制。

现在我们将通过一个控制器构件的测试,讨论如何定义测试需求、设计测试用例、实现和执行测试脚本。

控制器构件是一个常见的应用模式,它可以以多种方式出现在软件系统中,例如在Web应用中控制器构件接收HTTP请求、进行请求分发给适合的处理器构件。

(1)设计控制器构件

按照控制器构件的规格说明:

接收请求;

对请求执行常用计算;

选择合适的请求处理器;

路由请求;

可能会提供一个顶层的处理器用于处理错误或异常。

鉴于此我们设计4个对象(如图8所示):

Request,Response,RequestHandler,Controller。

Controller接受Request,分发给RequestHandler,并返回Response对象。

图8:

测试对象控制器构件

(2)定义控制器构件的实现基类

阅读《JUnitinAction》,按照图8编写DefaultController类;

设计错误访问类ErrotResponse,如图9所示。

图9:

ErrorResponse

(3)0次迭代

定义测试类框架,实例化DefaultController,此时测试方法定义为testMethod():

publicclassTestDefaultController0extendsTestCase{

privateDefaultControllercontroller;

//以setUp()为扩展点,实例化DefaultController对象

protectedvoidsetUp(){

controller=newDefaultController();

//首先定义新的测试方法,为了有测试可以运行

publicvoidtestMethod(){

/*为暂时没有实现的测试代码抛出异常,这样避免了测试通过,

*提醒必须实现其代码

thrownewRuntimeException("

Implementme!

"

(4)测试需求

Controller的目的在于处理请求并响应,但是在处理请求之前必须首先设计添加RequestHandler来做实际的处理工作。

所以要紧的是先测试是否可以添加RequestHandler。

为了判断测试是否成功需要比较测试预期结果和实际执行结果。

检查addHandler()发现:

voidaddHandler(Requestrequest,Responseresponse)

而DefaultController中getHandler()签名如下:

RequestHandlergetHandler(Requestrequest)

单元测试的要点在于一次只测试一个对象。

为了创建单元测试必须两种对象:

领域对象,代表被测试对象;

测试对象,即和领域对象交互的对象,他们是测试领域对象的环境需求。

在本轮迭代中,我们唯一用到的领域对象是DefaultController,其它都是测试对象。

鉴于此,设计TestDefaultController1如下:

增加一个RequestHandler,引用一个Request;

获得一个RequestHandler判断传递的是否是同一个Request;

检查获取的RequestHandler是否就是添加的那个。

那么,把测试类放在何方?

有两种可选方案,其一把测试类作为同一包中的公共类;

其二,作为testcase的内部类,如图10所示。

图10:

迭代1

迭代1TestDefaultController1的测试方法:

publicvoidtestAddHandler(){

//实例化测试对象

Requestrequest=newTestRequest();

RequestHandlerhandler=newTestHandler();

//把待测试对象controller添加到合适的测试处理器

controller.addHandler(request,handler);

RequestHandlerhandler2=controller.getHandler(request);

//监测读取的对象是否为刚刚传入的对象

assertSame(handler2,handler);

迭代2TestDefaultController2:

测试DefaultController的核心—请求处理

publicvoidtestProcessRequest(){

//创建测试对象,并添加测试处理器

//调用processRequest()

Responseresponse=controller.processRequest(request);

//验证reponse对象不是null

assertNotNull("

Mustnotreturnanullresponse."

response);

//把测试结果和预期的TestResponse对象进行比较

assertEquals(TestResponse.class,response.getClass());

迭代2代码重构TestDefaultController2Refact:

分离初始化逻辑到setUp()

TestDefaultController2Refact中定义属性:

privateRequestrequest;

privateRequestHandlerhandler;

setUp():

request=newTestRequest();

handler=newTestHandler();

同时修改testAddHandler()和testProcessHandler()

迭代3TestDefaultControllerMockExceptionCond:

模拟异常条件

在TestDefaultControllerMockExceptionCond创建内部类TestExceptionHandlerimplementsRequestHandler

privateclassTestHandlerimplementsRequestHandler{

publicResponseprocess(Requestrequest)throwsException{

returnnewTestResponse();

}

定义测试方法testProcessRequestAnswerErrorResponse():

publicvoidtestProcessRequestAnswerErrorResponse(){

TestRequestrequest=newTestRequest();

TestExceptionHandlerhandler=newTestExceptionHandler();

Mustnotreturnanullresponse"

response);

assertEquals(ErrorResponse.class,response.getClass());

运行测试脚本,测试方法testProcessRequestAnswerErrorResponse()运行失败如图11所示,我们需要做两件事情:

为测试请求换名,因为Fixture中已经有了一个叫做Test的请求;

其次,需要在类中增加更多的异常处理代码,以免运行时候发生RuntimeException。

图11:

testProcessRequestAnswerErrorResponse()运行失败

迭代3代码优化:

TestDefaultControllerMockExceptionCondEvolution

定义TestDefaultControllerMockExceptionCondEvolution的内部类

TestRequestimplementsRequest{

privatestaticfinalStringDEFAULT_NAME="

Test"

;

privateStringname;

publicTestRequest(Stringname){

this.name=name;

publicTestRequest(){

this(DEFAULT_NAME);

publicStringgetName(){

returnthis.name;

重构TestDefaultControllerMockExceptionCondEvolution中的testProcessAnswerErrorResponse:

TestRequestrequest=newTestRequest("

testError"

迭代4TestDefaultControllerException:

测试异常

测试异常情况如下:

其一,测试请求处理器为定义异常;

测试注册同名请求异常。

在TestDefaultControllerException添加测试方法testGetHandlerNotDefined()和testAddRequestDuplicateName()。

……

publicvoidtestGetHandlerNotDefined(){

testNotDefined"

try{

fail("

Anexceptionsholdberaisediftherequested"

+"

handlerhasnotbeenregistered."

}catch(RuntimeExceptionexception){

assertTrue(true);

publicvoidtestAddRequestDuplicateName(){

TestHandlerhandler=newTestHandler();

//Registrationofhandlerforthefirsttime.

//Registrationofhandlerforthesecondtime.

controller.addHandler(request,handler);

Anexceptionshouldberaisedifthedefault"

TestRequesthasalreadlybeenregistered."

经过多次迭代后得到的测试脚本的类图如图11所

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 电力水利

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1