多测师是一家拥有先进的教学理念,强大的师资团队,业内好评甚多的接口自动化测试培训机构!

17727591462

联系电话

您现在所在位置:接口自动化测试培训 > 新闻资讯

Java Fluent Restful API自动化测试框架

更新时间:2022-04-21 09:21:43 作者:多测师 浏览:300

  这是一个RestfulAPI自动化测试框架,这是一个能让你写出高可读性测试代码的测试框架!

  项目目标

  话说目前行业内,RestfulAPI自动化测试框架已经不是稀罕物了,各个语言都有自己的实现机制。拿Java的Jersey来讲,它本身就提供了一个API测试框架-JerseyTestFramework.能够帮助我们写API测试,但是这里我们想做的是另一套。

Java Fluent Restful API自动化测试框架

  观察到Jersey使用了Fluentinterface的模式来让代码可读性更高,比如下面:

  StringresponseMsg=target.path("myresource").request().get(String.class);

  那么如果我们也使用FluentInterface模式,是不是也可以让我们的测试代码可读性更高呢?

  比如下面的测试的代码,是不是看起来很清爽,目标更明确呢?

APIRequest.GET(URL).header("Authorization","Bearer"+token).invoke().assertStatus(200).assertBody(expectedBody);

  直接一行代码,搞定一条Case!

  分析需求

  既然是一个API自动化测试框架,那它能做什么呢?

  · 能够发HTTP请求-Get,Post,Put,Delete,甚至Head

  · 能够接受HTTP返回,并且能够方便验证其返回值

  · 能够打印所有Log,包含Request和Response的所有部分,这样当Case出错时,我们容易分析问题所在

  · 能够做好数据分离,用配置文件管理测试数据

  用到的工具

  显然,框架不是工具,它只是对现有工具的组合和再包装,而这个框架也使用了一些流行的工具:

  · JerseyClient2.18我们要使用它来帮助我们发HTTPRequest

  · Junit4测试框架,用它来写Case

  · ApacheCommonsIO提供CommonAPI帮助读写文件

  · SLF4J,打印log怎能少了它

  如何使用

  最终,所有的HTTPRequest都从APIRequest这个类出发,一步步构建,最终调用Invoke方法发送HTTP请求。

  用APIResoponse来管理HTTP的返回,这个方法提供一些公共的方法来验证API的返回。

  建议所有的TestCase都继承与APITest类这样可以方便的管理配置文件,以及获得一些有用的公共方法。

  下面是一些例子:

  1、如何发一个Get请求

APIRequest.GET(uri).header("Authorization",token).invoke().assertStatus(200).assertBodyContains("expectedContent");

  2、如何使用XML或者Json格式的Payload

  Stringpayload=loadFile("xmlfile.xml");

  3、如何运行时定制化Payload填充参数

  Stringpayload=String.format(loadFile("jsonfile.json"),"abc","edf");

  4、如何做数据分离,在Property文件管理参数

  `Stringuri=getValue("get.uri");

  核心实现

  要想使用FluentParagramingModel来写case,那么就得让我们所有的包装方法,都能够返回期望的Class对象,更重要的是,我们是想让Request的返回和验证也能参与到Fluent模式的验证,所以在最终调用方法时,APIRequest和APIResponse就要能和谐的过渡到一起。

  所以我们这样定义APIRequest类:

/**

*GeneralClasstomakeHTTPcalls

*

*@authorCarlJi

*/

publicclassAPIRequest{

privateUriBuilderuri;

privateMap<String,String>params=newHashMap<String,String>();

privateMap<String,String>headers=newHashMap<String,String>();

privateMediaTypecontentType=MediaType.APPLICATION_XML_TYPE;

privateMediaTypeacceptType;

privateStringhttpMethod;

privateStringbody;

privateAPIRequest(Stringuri,Stringmethod)

{

this.uri=UriBuilder.fromUri(uri);

this.httpMethod=method;

}

/**

*BuildaHTTPGetrequest

*

*@paramuri

*TheURIonwhichaHTTPgetrequestwillbecalled

*@return

*{@linkAPIRequest}

*/

publicstaticAPIRequestGET(Stringuri)

{

returnnewAPIRequest(uri,HttpMethod.GET);

}

/**

*BuildaHTTPPostrequest

*

*@paramuri

*TheURIonwhichaPOSTrequestwillbecalled

*@return

*{@linkAPIRequest}

*/

publicstaticAPIRequestPOST(Stringuri)

{

returnnewAPIRequest(uri,HttpMethod.POST);

}

/**

*BuildaHTTPPutrequest

*

*@paramuri

*TheURIonwhichaPUTrequestwillbecalled

*@return

*{@linkAPIRequest}

*/

publicstaticAPIRequestPUT(Stringuri)

{

returnnewAPIRequest(uri,HttpMethod.PUT);

}

/**

*BuildaHTTPDeleterequest

*

*@paramuri

*TheURIthattheDeleteRequestwillbecalled

*@return

*{@linkAPIRequest}

*/

publicstaticAPIRequestDELETE(Stringuri)

{

returnnewAPIRequest(uri,HttpMethod.DELETE);

}

/**

*BuildaHTTPHEADrequest

*

*@paramuri

*TheURIthattheHeadrequestwillbecalled

*@return

*{@linkAPIRequest}

*/

publicstaticAPIRequestHEAD(Stringuri)

{

returnnewAPIRequest(uri,HttpMethod.HEAD);

}

/**

*Addthe{@codevalue}totheendofURItobuildthefinalURI

*

*@paramvalue

*ThevaluethatwillbeappendedtotheURI

*@return

*{@linkAPIRequest}

*/

publicAPIRequestpath(Stringvalue)

{

this.uri.path(value);

returnthis;

}

/**

*BuildtheparameterintherequestURI

*

*@paramkey

*TherequestURIparameterkey

*@paramvalue

*TherequestURIparametervalue

*@return

*{@linkAPIRequest}

*/

publicAPIRequestparam(Stringkey,Stringvalue)

{

params.put(key,value);

returnthis;

}

/**

*Setthecontenttypeintherequestbody

*

*@paramtype

*Thecontenttype{@linkMediaType}

*@return

*{@linkAPIRequest}

*/

publicAPIRequesttype(MediaTypetype)

{

this.contentType=type;

returnthis;

}

/**

*SettheacceptedtypefortheHTTPresponsewhencallingthespecificHTTPrequest

*

*@paramtype

*Theacceptedtypefortheresponseofthisrequest

*@return

*{@linkAPIRequest}

*/

publicAPIRequestaccept(MediaTypetype)

{

this.acceptType=type;

returnthis;

}

/**

*SettheHTTPrequestheadersparameter

*

*@paramkey

*Theheadername

*@paramvalue

*Thecorrespondingvaluefortheheader

*@return

*{@linkAPIRequest}

*/

publicAPIRequestheader(Stringkey,Stringvalue)

{

headers.put(key,value);

returnthis;

}

/**

*Settherequestbody

*

*@parambody

*Thebodyoftherequest

*@return

*{@linkAPIRequest}

*/

publicAPIRequestbody(Stringbody)

{

this.body=body;

returnthis;

}

/**

*InvokejerseyclienttosendHTTPrequest

*

*@return{@linkAPIResponse}

*/

publicAPIResponseinvoke()

{

ClientConfigconfig=newClientConfig();

/**

*Important:JerseyInvocationclasswillcheck"EntitymustbenullforhttpmethodDELETE."

*sowecannotsendDELETErequestwithentityinpayload,

*herewesuppressthischeck

*/

config.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION,true);

Clientclient=ClientBuilder.newClient(config);

//Printalllogsforeachrequestandresponse

client.register(newLoggingFilter(Logger.getLogger(APIResponse.class.getName()),true));

WebTargetwebTarget=client.target(uri);

if(!params.isEmpty())

{

for(Entry<String,String>key:params.entrySet())

{

webTarget=webTarget.queryParam(key.getKey(),key.getValue());

}

}

Invocation.BuilderinvocationBuilder=webTarget.request();

if(acceptType!=null)

{

invocationBuilder=invocationBuilder.accept(acceptType);

}

if(!headers.isEmpty())

{

for(Stringkey:headers.keySet())

{

invocationBuilder.header(key,headers.get(key));

}

}

Responseresponse;

if(body==null)

{

response=invocationBuilder.method(httpMethod,Response.class);

}

else

{

response=invocationBuilder.method(httpMethod,Entity.entity(body,contentType),Response.class);

}

returnnewAPIResponse(response);

}

}

  以上内容为大家介绍了Java Fluent Restful API自动化测试框架,本文由多测师亲自撰写,希望对大家有所帮助。了解更多自动化测试相关知识:https://www.aichudan.com/xwzx/

联系电话

17727591462

返回顶部