如何使用 JUnit进行自动化测试.doc_第1页
如何使用 JUnit进行自动化测试.doc_第2页
如何使用 JUnit进行自动化测试.doc_第3页
如何使用 JUnit进行自动化测试.doc_第4页
如何使用 JUnit进行自动化测试.doc_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

如何使用JUnit进行自动化测试 1 如何利用JUnit在 Eclipse中开发自动化脚本JUnit可以和很多开发工具进行集成来进行单元测试,我们这里选取较常用的java开发工具Eclipse来使用JUnit4进行单元测试。如何在开发工具Eclipse里进行单元测试首先新建一个项目叫JUnit_Test,我们编写一个Calculator类,这是一个能够简单实现加减乘除、平方、开方的计算器类,然后对这些功能进行单元测试。这个类并不是很完美,我们故意保留了一些Bug用于演示,这些Bug在注释中都有说明。该类代码如下:package andycpp;public class Calculatorprivate static int result; / 静态变量,用于存储运行结果public void add(int n)result = result + n;public void substract(int n)result = result - 1; /Bug: 正确的应该是 result =result-npublic void multiply(int n) / 此方法尚未写好public void divide(int n)result = result / n;public void square(int n)result = n * n;public void squareRoot(int n)for (; ; ) ; /Bug : 死循环public void clear() / 将结果清零result = 0;public int getResult()return result;第二步,将JUnit4单元测试包引入这个项目:在该项目上点右键,点“属性”,如图:在弹出的属性窗口中,首先在左边选择“Java Build Path”,然后到右上选择“Libraries”标签,之后在最右边点击“Add Library”按钮,如下图所示:然后在新弹出的对话框中选择JUnit4并点击确定,如上图所示,JUnit4软件包就被包含进我们这个项目了。 第三步,生成JUnit测试框架:在Eclipse的Package Explorer中用右键点击该类弹出菜单,选择“New JUnit Test Case”。如下图所示:在弹出的对话框中,进行相应的选择,如下图所示: 点击“下一步”后,系统会自动列出你这个类中包含的方法,选择你要进行测试的方法。此例中,我们仅对“加、减、乘、除”四个方法进行测试。如下图所示:之后系统会自动生成一个新类CalculatorTest,里面包含一些空的测试用例。你只需要将这些测试用例稍作修改即可使用。完整的CalculatorTest代码如下:package andycpp;import static org.junit.Assert.*;import org.junit.Before;import org.junit.Ignore;import org.junit.Test;public class CalculatorTestprivate static Calculator calculator = new Calculator();Beforepublic void setUp() throws Exceptioncalculator.clear();Testpublic void testAdd()calculator.add(2);calculator.add(3);assertEquals(5, calculator.getResult();Testpublic void testSubstract()calculator.add(10);calculator.substract(2);assertEquals(8, calculator.getResult();Ignore(Multiply() Not yet implemented)Testpublic void testMultiply()Testpublic void testDivide()calculator.add(8);calculator.divide(2);assertEquals(4, calculator.getResult();第四步,运行测试代码:按照上述代码修改完毕后,我们在CalculatorTest类上点右键,选择“Run As JUnit Test”来运行我们的测试,如下图所示:运行结果如下:进度条是红颜色表示发现错误,具体的测试结果在进度条上面有表示“共进行了4个测试,其中1个测试被忽略,一个测试失败”2 JUnit重要元素TEST方法的前面使用Test标注,以表明这是一个测试方法。对于方法的声明也有如下要求:名字可以随便取,没有任何限制,但是返回值必须为void,而且不能有任何参数。Test public void testAdd() calculator.add(2); calculator.add(3); assertEquals(5, calculator.getResult(); Before 方法的前面使用Before标注,表示该测试类中,所有的测试方法在执行前,都会运行该方法。After方法的前面使用After标注,表示该测试类中,所有的测试方法在执行结束,都会运行该方法。BeforeClass方法的前面使用BeforeClass标注,表示该测试类首先会执行该方法。AfterClass方法的前面使用AfterClass标注,表示该测试类所有测试方法执行结束后,执行该方法。Ignore函数的前面加上Ignore标注,这个标注的含义就是“某些方法尚未完成,暂不参与此次测试”。这样的话测试结果就会提示你有几个测试被忽略,而不是失败。一旦你完成了相应函数,只需要把Ignore标注删去,就可以进行正常的测试。3 如何结合EasyMock去写单元测试EasyMock主要是起到分层测试的作用,即我不关心哪一层,那一层就可以用mock的方法,把它虚拟出来一个对象,而不真的去创建这个对象。为了说明EasyMock作用和用法,我们选取自动化测试COE中提供的demo作为例子。我们选取其中的两个类CalculateService类和CalculateModel类,由于是以面向接口编程的思想开发的代码,所以这两个类之间是通过接口建立起关系的。这两个类的关系如下图3.1 简单的单元测试写法CalculateService类的代码如下package service;import javax.script.ScriptEngine;import javax.script.ScriptEngineManager;import javax.script.ScriptException;public class CalculateService implements ICalculateServiceOverridepublic String calculate ( String text )ScriptEngine jse = new ScriptEngineManager().getEngineByName( JavaScript );if ( null != text )tryObject value = jse.eval( text );if ( value != null )return String.valueOf( value ); catch ( ScriptException e )e.printStackTrace();return failed;我们先看一下CalculateService的单元测试如何写?第一步要测试这个类,那我们首先要创建一个这样的对象代码如下:Beforepublic void setUp()CalculateService service= new CalculateService();使用Before标签还是 BeforeClass的决定条件在于,你要测试的方法是不是每次都要重新创建一个service第二步明确要测试的方法,并根据要测试的方法,分析测试所需要覆盖的场景。1. 我们要测的方法为calculate;2. 该方法需要覆盖的场景为:1)输入参数text为null2)过程中value是null(这种情况的话,输入参数为”null”)3) 运算中出现异常4) 运算正常输出结果 那我们针对这几个场景,写测试代码如下:Testpublic void should_return_failed_when_input_is_null()assertEquals( failed, service.calculate( null ) );Testpublic void should_return_failed_when_input_is_string_null()assertEquals( failed, service.calculate( null ) );Testpublic void should_return_failed_when_input_is_not_can_calculate()assertEquals( failed, service.calculate( /+*1 ) );Testpublic void should_return_5_when_input_is_1_and_4()assertEquals( 5.0, service.calculate( 1+4 ) );通过调用service类的 calculate方法,并给予不同的输入参数以创建不同的场景,从而验证当前方法是否正确。 上面就是CalculateService的单元测试,那我们下面看下CalculateModel类,并一起来写一下他的单元测试要如何去写?CalculateModel类的代码如下:package model;import service.ICalculateService;public class CalculateModel implements ICalculateModelprivate ICalculateService service;public CalculateModel( ICalculateService service )this.service = service;Overridepublic String calculate( String text )return service.calculate( text );我们可以按照上面的步骤去写测试类第一步创建要测试的对象,这里由于CalculateModel的创建依赖于CalculateService,所以我们要先创建CalculateService;代码如下:Beforepublic void setUp()CalculateService service= new CalculateService (); CalculateModel model = new CalculateModel (service );第二步明确要测试的方法,并根据要测试的方法,分析测试所需要覆盖的场景。1. 我们要测的方法为calculate;2、根据代码我们可以看出该方法需要覆盖的场景只有一个,就是不论输入的参数如何,也不管运算的结果是什么,只要调用了CalculateService的calculate方法,并把结果返回出去即可。测试代码如下:Testpublic void should_return_2_when_input_is_1_multiply_2 ()String text = 1*2;assertEquals( 2, model.calculate( text ) );粗略一看好像没什么问题,但是我们仔细想一下,如果CalculateService的calculate方法出错的话,那么这个测试用例就会报错,因为返回结果就会发生错误。也就是说我们现在在测CalculateModel,但我们同时还要保证CalculateService的正确,这样显然是有问题的,因为CalculateService不是我们这次测试的对象,它在别的测试类中已经覆盖过了。那么如何解决这个问题呢?3.2 结合EasyMock的单元测试写法下面我们用EasyMock来写这个测试用例。首先,因为我们对CalculateService不关心,所以我们用EasyMock来Mock一个CalculateService。Beforepublic void setUp()CalculateService service= createMock( ICalculateService.class ); CalculateModel model = new CalculateModel( service );然后我们重新用EasyMock的方式来编写这个测试方法,由于CalculateService 是被 mock出来的,而非真正的创建这么一个对象,所以对象的方法不会真的运行,所以需要期待调用一下,同时这个方法拥有一个返回值,所以需要我们给它指定一个我们希望的返回值。(如果后面的方法需要依赖这个返回值作为判断执行的条件,如”if(a=0)” 那么我们这个返回值 “a” 就需要根据我们希望测试的场景来给指定)然后我们需要replay一下这个mock对象,以激活它,最后再在程序的结尾verify一下,来验证它的调用是否和我们期待的一致。Testpublic void should_return_2_when_input_is_1_multiply_2()String text = 1*2;expect( service.calculate( text ) ).andReturn( 2 );replay( service );assertEquals( 2, model.calculate( text ) );verify( service );总结一下,EasyMock进行单元测试的过程大致可以划分为以下几个步骤:1、使用 EasyMock 生成 Mock 对象;2、设定 Mock 对象的预期行为和输出;3、将 Mock 对象切换到 Replay 状态;4、调用 Mock 对象方法进行单元测试;5、对 Mock 对象的行为进行验证。3.3 元素这里我们仅介绍我们在自动化测试中会用到的元素,对于其它元素大家可以参考EasyMock官网/api/createMock这个方法的作用是Mock一个我们不希望实际创建的对象。 这个方法有好几个重载方法,我们最常用的是一个参数的,这个参数为我们要Mock对像的类型如:ICalculateService service= createMock( ICalculateService.class );expect这个方法是期待调用Mock对象带返回值的方法。它的后面通常需要and方法来指明它执行的结果。expectLastCallMock对象没有返回值的方法,只需要在测试中直接录制这个方法即可,不需要用expect去期待它执行。但有的时候,我们可能会期望它会有一个异常抛出,或着指定它要执行多少次这个时候,我们就需要用到expectLastCall方法,这个方法的用法如下:service.noReturnMethod();expectLastCall().andThrow( new Exception( 异常 ) );表明在执行Mock对象service的noReturnMethod方法时,期望它向外抛出一个异常。andReturn期望该方法的返回值,参数为 ObjectandThrow 期望该方法抛出一个异常,参数为 ThrowableandAnswer 期望该方法返回一个值或抛出一个异常,这个过程可以通过一段程序来进行。如:expect(service.calculate( “2” ) ).andAnswer( new IAnswer()Overridepublic String answer() throws Throwablereturn 2*5*3;);andDelegateTo用法和andAnswer()方法类似,但需要建立一个类,这个类要实现Mock对象的接口,用法如下:publicclassServiceStubimplementsServicepublicintexecute(intcount)returncount*2;TestpublicvoidtestRuntimeReturn()Businessbusiness=newBusiness();Serviceservice=EasyMock.createMock(Service.class);business.setService(service);EasyMock.expect(service.execute(EasyMock.anyInt().andDelegateTo(newServiceStub();EasyMock.replay(service);business.execute();EasyMock.verify(service);any这里面包括 anyBean(),anyByte(),anyChar(),anyInt(),anyLong(),anyFloat(),anyDouble(),anyShort(),anyObject(),anyString();用法:当期待执行的mock方法参数值不确定时,可以根据参数的类型来模拟。如:expect( service.calculate( anyString() ) ).andReturn( 2 );times用来指定某一方法执行的次数,如果次数不确定那么可以用anyTimes方法。expect( service.calculate(1*2 ) ).andReturn( 2 ).times(2); 表明期望该方法执行两次expect( service.calculate(1*2) ).andReturn( 2 ). anyTimes();表明期望该方法执行若干次。isA用

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论