您的当前位置:首页如何使用JUnit进行自动化测试

如何使用JUnit进行自动化测试

2023-06-12 来源:爱问旅游网


如何使用JUnit进行自动化测试

1 如何利用JUnit在 Eclipse中开发自动化脚本

JUnit可以和很多开发工具进行集成来进行单元测试,我们这里选取较常用的java开发工具Eclipse来使用JUnit4进行单元测试。如何在开发工具Eclipse里进行单元测试

首先新建一个项目叫JUnit_Test,我们编写一个Calculator类,这是一个能够简单实现加减乘除、平方、开方的计算器类,然后对这些功能进行单元测试。这个类并不是很完美,我们故意保留了一些Bug用于演示,这些Bug在注释中都有说明。该类代码如下:

package andycpp;

public class Calculator

{

private static int result; etEngineByName( \"JavaScript\" );

if ( null != text )

{

try

{

Object value = ( text );

if ( value != null )

{

return ( value );

}

} catch ( ScriptException e )

{

();

}

}

return \"failed\";

}

}

我们先看一下CalculateService的单元测试如何写?

第一步要测试这个类,那我们首先要创建一个这样的对象

代码如下:

@Before

public void setUp()

{

CalculateService service= new CalculateService();

}

使用Before标签还是 BeforeClass的决定条件在于,你要测试的方法是不是每次都要重新创建一个service

第二步明确要测试的方法,并根据要测试的方法,分析测试所需要覆盖的场景。

1. 我们要测的方法为calculate;

2. 该方法需要覆盖的场景为:

1)输入参数text为null

2)过程中value是null(这种情况的话,输入参数为”null”)

3) 运算中出现异常

4) 运算正常输出结果

那我们针对这几个场景,写测试代码如下:

@Test

public void should_return_failed_when_input_is_null()

{

assertEquals( \"failed\

}

@Test

public void should_return_failed_when_input_is_string_null()

{

assertEquals( \"failed\

}

@Test

public void should_return_failed_when_input_is_not_can_calculate()

{

assertEquals( \"failed\

}

@Test

public void should_return_5_when_input_is_1_and_4()

{

assertEquals( \"\

}

通过调用service类的 calculate方法,并给予不同的输入参数以创建不同的场景,从而验证当前方法是否正确。

上面就是CalculateService的单元测试,那我们下面看下CalculateModel类,并一起来写一下他的单元测试要如何去写

CalculateModel类的代码如下:

package model;

import ;

public class CalculateModel implements ICalculateModel

{

private ICalculateService service;

public CalculateModel( ICalculateService service )

{

= service;

}

@Override

public String calculate( String text )

{

return ( text );

}

}

我们可以按照上面的步骤去写测试类

第一步创建要测试的对象,这里由于CalculateModel的创建依赖于CalculateService,所以我们要先创建CalculateService;

代码如下:

@Before

public void setUp()

{

CalculateService service= new CalculateService ();

CalculateModel model = new CalculateModel (service );

}

第二步明确要测试的方法,并根据要测试的方法,分析测试所需要覆盖的场景。

1. 我们要测的方法为calculate;

2、根据代码我们可以看出该方法需要覆盖的场景只有一个,就是不论输入的参数如何,也不管运算的结果是什么,只要调用了CalculateService的calculate方法,并把结果返回出去即可。

测试代码如下:

@Test

public void should_return_2_when_input_is_1_multiply_2 ()

{

String text = \"1*2\";

assertEquals( \"2\

}

粗略一看好像没什么问题,但是我们仔细想一下,如果CalculateService的calculate方法出错的话,那么这个测试用例就会报错,因为返回结果就会发生错误。也就是说我们现在在测CalculateModel,但我们同时还要保证CalculateService的正确,这样显然是有问题的,因为CalculateService不是我们这次测试的对象,它在别的测试类中已经覆盖过了。那么如何解决这个问题呢?

3.1 结合EasyMock的单元测试写法

下面我们用EasyMock来写这个测试用例。

首先,因为我们对CalculateService不关心,所以我们用EasyMock来Mock一个CalculateService。

@Before

public void setUp()

{

CalculateService service= createMock( );

CalculateModel model = new CalculateModel( service );

}

然后我们重新用EasyMock的方式来编写这个测试方法,

由于CalculateService 是被 mock出来的,而非真正的创建这么一个对象,所以对象的方法不会真的运行,所以需要期待调用一下,同时这个方法拥有一个返回值,所以需要我们给它指定一个我们希望的返回值。(如果后面的方法需要依赖这个返回值作为判断执行的条件,如”if(a==0){}” 那么我们这个返回值 “a” 就需要根据我们希望测试的场景来给指定)

然后我们需要replay一下这个mock对象,以激活它,

最后再在程序的结尾verify一下,来验证它的调用是否和我们期待的一致。

@Test

public void should_return_2_when_input_is_1_multiply_2()

{

String text = \"1*2\";

expect( ( text ) ).andReturn( \"2\" );

replay( service );

assertEquals( \"2\

verify( service );

}

总结一下,EasyMock进行单元测试的过程大致可以划分为以下几个步骤:

1、使用 EasyMock 生成 Mock 对象;

2、设定 Mock 对象的预期行为和输出;

3、将 Mock 对象切换到 Replay 状态;

4、调用 Mock 对象方法进行单元测试;

5、对 Mock 对象的行为进行验证。

3.2 元素

这里我们仅介绍我们在自动化测试中会用到的元素,对于其它元素大家可以参考EasyMock

官网

createMock

这个方法的作用是Mock一个我们不希望实际创建的对象。

这个方法有好几个重载方法,我们最常用的是一个参数的,这个参数为我们要Mock对像的类型如:ICalculateService service= createMock( );

expect

这个方法是期待调用Mock对象带返回值的方法。它的后面通常需要and…方法来指明它执行的结果。

expectLastCall

Mock对象没有返回值的方法,只需要在测试中直接录制这个方法即可,不需要用expect去期待它执行。但有的时候,我们可能会期望它会有一个异常抛出,或着指定它要执行多少次这个时候,我们就需要用到expectLastCall方法,这个方法的用法如下:

();

expectLastCall().andThrow( new Exception( \"异常\" ) );

表明在执行Mock对象service的noReturnMethod方法时,期望它向外抛出一个异常。

andReturn

期望该方法的返回值,参数为 Object

andThrow

期望该方法抛出一个异常,参数为 Throwable

andAnswer

期望该方法返回一个值或抛出一个异常,这个过程可以通过一段程序来进行。如:

expect( “2” ) ).andAnswer( new IAnswer< String >()

{

@Override

public String answer() throws Throwable

{

return 2*5*3;

}

});

andDelegateTo

用法和andAnswer()方法类似,但需要建立一个类,这个类要实现Mock对象的接口,用法如下:

publicclassServiceStubimplementsService{

publicintexecute(intcount){

returncount*2;

}

}

@Test

publicvoidtestRuntimeReturn(){

Businessbusiness=newBusiness();

Serviceservice=;

(service);

())).andDelegateTo(newServiceStub());

(service);

();

(service);

}

any

这里面包括 anyBean(),anyByte(),anyChar(),anyInt(),anyLong(),anyFloat(),anyDouble(),anyShort(),

anyObject(),anyString();

用法:当期待执行的mock方法参数值不确定时,可以根据参数的类型来模拟。如:

expect( ( anyString() ) ).andReturn( \"2\" );

times

用来指定某一方法执行的次数,如果次数不确定那么可以用anyTimes方法。

expect( (\"1*2\" ) ).andReturn( \"2\" ).times(2); 表明期望该方法执行两次

expect( (\"1*2\") ).andReturn( \"2\" ). anyTimes();表明期望该方法执行若干次。

isA

用法:当期待执行的mock方法参数值为一个对象,并且不确定具体对象时,可以根据参数的类型来模拟。如:

expect( ( isA ) ).andReturn( \"2\" );

isNull

用法:当期待执行的mock方法参数值为null时,用该方法来声明。

expect( ( isNull()) ).andReturn( \"2\" );

notNull

用法:当期待执行的mock方法参数值不为null时,用该方法来声明。

expect( ( notNull()) ).andReturn( \"2\" );

startWith

用来模糊表达一个值 ,指明这个值以某个字符串开始。

expect( ( startWith(\"1\")) ).andReturn(\"2\");

endWith

用来模糊表达一个值 ,指明这个值以某个字符串开始

expect( ( endWith(\"2\")) ).andReturn(\"2\");

matches

用来模糊表达一个值 ,指明这个值以符合某一正则限定的格式

expect( ( matches(\"[1-9][0-9]\\{4,\\}\")) ).andReturn(\"2\");

replay

在生成 Mock 对象和设定 Mock 对象行为两个阶段,Mock 对象的状态都是 Record 。在这个阶段,Mock 对象会记录用户对预期行为和输出的设定。

在使用 Mock 对象进行实际的测试前,我们需要将 Mock 对象的状态切换为 Replay。在 Replay 状态,Mock 对象能够根据设定对特定的方法调用做出预期的响应。

replay( service );

Verify

在利用 Mock 对象进行实际的测试过程之后,为了验证指定的方法调用真的完成了,我们需要调用 verify 方法进行验证。

verify( service );

因篇幅问题不能全部显示,请点此查看更多更全内容