@Test
publicvoid testGetPersons(){
expect()
.statusCode(200)
.body(hasXPath("//*[self::person and self::person[@id='1'] and self::person/email[text()='test@hascode.com'] and self::person/firstName[text()='Tim'] and self::person/lastName[text()='Testerman']]"))
.body(hasXPath("//*[self::person and self::person[@id='20'] and self::person/email[text()='dev@hascode.com'] and self::person/firstName[text()='Sara'] and self::person/lastName[text()='Stevens']]"))
.body(hasXPath("//*[self::person and self::person[@id='11'] and self::person/email[text()='devnull@hascode.com'] and self::person/firstName[text()='Mark'] and self::person/lastName[text()='Mustache']]"))
.when().get("/service/persons/xml");}

XML verification vs a Schema

Now we’re going to validate the xml returned against a XML schema file

Registering custom parsers for MIME-types

Sometimes you’ve got to handle a RESTful service that returns an invalid content type so that REST-assured does not know which parser to use to process the response. This is not a real problem though because the framework allows you to register parsers for a given content type as shown in the example below:

Troubleshooting

“WARNING: Cannot find parser for content-type: text/json — using default parser.” – The framework does not know for sure which parser to use. Register the corresponding parser like this: e.g. RestAssured.registerParser(“text/json”, Parser.JSON);

“If I use the War file, the path is no longer localhost:8080, but becomes http://localhost:8080/rest-assured-example/.” - specify the changed context path in the get() method or – more comfortable – define it as a global setting e.g. like this one

89 Responses to “Testing RESTful Web Services made easy using the REST-assured Framework”

That’s really nice. How do you get the exported view? Is that a default Jersey feature? I know the wadl is produced, but didn’t know this part. Thanks for your examples too. Very helpful. We are trying to work out whether to use something like this, jbehave, or custom….

Thanks for the .war. I didn’t see it when I was looking at your Bitbucket repository. Now that I’ve got the .war deployed and tomcat running, I tried your example for testGetSingleUser(). I had to change get(“/service/single-user”); to get(“/rest-assured-example/service/single-user”); in order for it to find the resource and return a status code of 200.

I’m using this code
expect().statusCode(200)
.body(hasXPath(“//person[@id='1']/email[.='test@hascode.com'] and firstName=’Tim’ and lastName=’Testerman’”))
.body(hasXPath(“//person[@id='20']/email[.='dev@hascode.com'] and firstName=’Sara’ and lastName=’Stevens’”))
.body(hasXPath(“//person[@id='11']/email[.='devnull@hascode.com'] and firstName=’Mark’ and lastName=’Mustache’”))
.when().get(“/rest-assured-example/service/persons/xml”);

Thanks for any help you can provide so I can understand how this works.

Works for me .. using mvn tomcat:run as well as using a deployed war archive on a tomcat instance. but I’ve noticed that the xpath expression was not well defined and precise enough .. I’ve fixed this and updated the example .. thanks for mentioning!

Hello, Micha. Excellent tutorial. If I use the War file, the path is no longer localhost:8080, but becomes http://localhost:8080/rest-assured-example/. This causes the tests to fail. How do I fix this? I am currently looking at your source code to find it.
Thanks so much !!

Thanks! You just simply need to specify the new context path – one way is to specify it in the get() method but it is way more comfortable to specify it globally using RestAssured.basePath = “yourbasepath”;

No problem Are you getting any error here? Does the file exist in your classpath? Have you modified the original example somehow? Does the servlet container return any error or is there an error displayed in your server’s logs?

Thanks for putting together such a nice tutorial! It is really helpful for me to understand rest-assured better. I am trying to figure out what framework to use for my rest web service testing and have some further questions on rest-assured for you.

Do you happen to have an example to use rest-assured for https web service?

Also for a web service that supports both xml and json, is there any way to write same test to handle both these two response format? If not, the tests will double .

Also for a test case, say, 1. user A (may be an admin user) logs in, 2. A create a user B, 3. A then retrieves user B’s info to verify that user B is created correctly.
step 2 and 3 will need to send out the cookies returned from step 1. Will tester have to set cookie in each request? i was hopping that rest-assured will support updating some default cookies based on server response, then the next http request will by default send the updated cookies. Do you happen to know if this is supported by rest-assured?

Hi, does the test fail because other values are returned? or are you getting an error in your IDE, perhaps have forgotten the static import for equalTo e.g. import static org.hamcrest.Matchers.equalTo;

Have you assured that your REST-service is responsive? By adding .log().all() to the response and request specification you’ll receive detailed information what the client sends to the server and the server’s response.

Again, thank you for this very nice tutorial (today is the third document I read from you about REST-Assured and Jersey Testing Framework… I am evaluating which one to use, and inclining to go with REST-Assured)… this very nice coverage of several capabilities of REST-Assure, with code to test as we read!!

I also had “failing” tests due to the URL/path of the deployed web service (in Tomcat from Eclipse), by adding the following “@Before” it solved the problem (you have also suggested this in another comment above):

In most cases, HTTPS should work out of the box but there are some cases where you might run into trouble:

1) The server uses an invalid certificate (you’re getting an SSLPeerUnverifiedException)given().relaxedHTTPSValidation().when().get("https://yourserver.com");
or using specifications: RestAssured.useRelaxedHTTPSValidation();

You may even specify a Java keystore file if you need to:given().keystore("/pathToJksInClassPath", )..
or using specifications: RestAssured.keystore("/pathToJksInClassPath", );

If you’ve already loaded a keystore, you may use this keystore, too:RestAssured.trustStore(keystore);

2) The server certificate references an invalid hostname
In this case, you don’t need to import a keystore .. simply use:RestAssured.config = RestAssured.config().sslConfig(sslConfig().allowAllHostnames());

or in a concrete requestgiven().config(RestAssured.config().sslConfig(sslConfig().allowAllHostnames()). .. ;

Seems like you’ve managed to handle the HTTPS problems. Is https://stage3.test.com/services/api/v1/product with method=GET and content-type header application/json correct? Are you able to access the webservice using curl or since it’s using GET .. your browser when using the designated target?

This is my code. Actually when I am entering URL using get(), I am getting LOGIN page of ALM.
I want to login using required UN and PWD. I googled for this and got this solution but its not working for me. Please help me for this if you know, What to do in this.

Thnx for your valuable reply and time u have given to me. I used your code. But I am not able to identify how do I check whether I logged in or not. I am using asString() to check whether next page displayed or not but it is showing login page only. Other thing is should I use post() for this or get() will be fine? I did not get form-based authentication? what it means ?

Can I get some examples or applications like you provided where I can work on put() and delete() functionality of rest-assured? I already did get() and post() with the help of your application only. Thanks in advance.

And yes, the last solution you told me about login to QC-ALM not worked. I don’t know what to do. So I skipped that and worked on some other functionality. If you have any other solution, please let me know.

In this I want to login using rest assured(I want to authenticate ALM user with rest assured); step 1 given in this link. If it is successful then I can get or delete any information I want like get a bug or delete bug like that. If login is successful then only I can proceed and rest apis spring security method works for older version of ALM. So for new version it is not working. Can you help me in that?

Hi Pratik,
if you don’t know how to reproduce the login, simply work through the log in process in your browser e.g. Chrome or Firefox with Firebug or HTTPLiveHeaders extension installed and record what exactly is needed to complete the login process as documented in the web site that you’ve posted .. cookies, headers, actions/methods used and parameters passed …
Afterwards you should have gathered everything you need to know to reproduce the login process with rest-assured.

you may use rest-assured with every hostname or ip address you like e.g. expect()…get(“http://www.yourdomain.com/”).
If you’re running multiple tests for a specific base-domain you may set it up for the framework like this: RestAssured.baseURI = “https://jira.atlassian.com”;

Hi,
It was really a nice article. I loved the way you explained. I am beginner and this single article is good enough to learn rearest assured. Can you please provide some examples for POST, PUT and DELETE methods.

lo siento, no hablo español. Could you repeat your question in english please? If you’d like to know how to test a RESTful webservice running on a WildFly application server then Arquillian is your tool of choice and I’m using Arquillian and rest-assured to run tests for a couple of Java EE projects by now and it’s working fine.

My question is: is there any other way to test the REST entries but without using the wildfly? If there is, how could I make this test?
I see that in your example when making calls to the REST entry you do as follows:
“Request URL: / service / single-user” before you raised the Widlfly?

2) Write a rest-assure matcher for every single request, don’t follow any redirect, parse the Location-header and write a new rest-assured request for the following necessary request so that you can be sure that your test-setup follows strictly the web application’s requirements for authentication there, be sure to set all headers needed.

Micha, I appreciate your quick response… No, my request has headers with auth token and body etc.. since I need to update my database with this request… My full code looks like this:
@Test
public void editPublicEvent(){

Micha, please desregard my last message – I found the problem: PUT is working but sometning wrong with my request this time. Your advise to use expect().log().all() was REALLY helpfull..
Thanks so much!!!

FAILED: testGetSingleUser
java.lang.NoClassDefFoundError: org/apache/http/concurrent/Cancellable
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
at java.lang.Class.getConstructor0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at groovyx.net.http.HTTPBuilder.doRequest(HTTPBuilder.java:415)
at groovyx.net.http.HTTPBuilder.request(HTTPBuilder.java:376)
at groovyx.net.http.HTTPBuilder$request.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:132)
at com.jayway.restassured.internal.RequestSpecificationImpl.sendHttpRequest(RequestSpecificationImpl.groovy:716)
at com.jayway.restassured.internal.RequestSpecificationImpl.this$2$sendHttpRequest(RequestSpecificationImpl.groovy)
at com.jayway.restassured.internal.RequestSpecificationImpl$this$2$sendHttpRequest.callCurrent(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:44)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
at com.jayway.restassured.internal.RequestSpecificationImpl.sendRequest(RequestSpecificationImpl.groovy:660)
at com.jayway.restassured.internal.RequestSpecificationImpl.this$2$sendRequest(RequestSpecificationImpl.groovy)
at com.jayway.restassured.internal.RequestSpecificationImpl$this$2$sendRequest.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:132)
at com.jayway.restassured.internal.filter.RootFilter.filter(RootFilter.groovy:28)
at com.jayway.restassured.filter.Filter$filter.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:132)
at com.jayway.restassured.internal.filter.FilterContextImpl.next(FilterContextImpl.groovy:45)
at com.jayway.restassured.filter.FilterContext$next.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:128)
at com.jayway.restassured.internal.RequestSpecificationImpl.invokeFilterChain(RequestSpecificationImpl.groovy:551)
at com.jayway.restassured.internal.RequestSpecificationImpl$invokeFilterChain.callCurrent(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:44)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:157)
at com.jayway.restassured.internal.RequestSpecificationImpl.applyPathParamsAndSendRequest(RequestSpecificationImpl.groovy:880)
at com.jayway.restassured.internal.RequestSpecificationImpl.this$2$applyPathParamsAndSendRequest(RequestSpecificationImpl.groovy)
at com.jayway.restassured.internal.RequestSpecificationImpl$this$2$applyPathParamsAndSendRequest.callCurrent(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:44)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:157)
at com.jayway.restassured.internal.RequestSpecificationImpl.get(RequestSpecificationImpl.groovy:118)
at com.jayway.restassured.specification.RequestSender$get.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:128)
at com.jayway.restassured.internal.ResponseSpecificationImpl.get(ResponseSpecificationImpl.groovy:236)
at pagemodel.snap.Rest.testGetSingleUser(Rest.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:659)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:845)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1153)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
at org.testng.TestRunner.privateRun(TestRunner.java:771)
at org.testng.TestRunner.run(TestRunner.java:621)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:357)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:352)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:310)
at org.testng.SuiteRunner.run(SuiteRunner.java:259)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1199)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1124)
at org.testng.TestNG.run(TestNG.java:1032)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)
Caused by: java.lang.ClassNotFoundException: org.apache.http.concurrent.Cancellable
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
… 73 more

Exception details:
java.lang.NullPointerException
at org.codehaus.groovy.reflection.GeneratedMetaMethod$DgmMethodRecord.loadDgmInfo(GeneratedMetaMethod.java:168)
at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.registerMethods(MetaClassRegistryImpl.java:185)
at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.(MetaClassRegistryImpl.java:95)
at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.(MetaClassRegistryImpl.java:73)
at groovy.lang.GroovySystem.(GroovySystem.java:36)
at org.codehaus.groovy.runtime.InvokerHelper.(InvokerHelper.java:65)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.createMap(ScriptBytecodeAdapter.java:623)
at com.jayway.restassured.internal.ResponseParserRegistrar.(ResponseParserRegistrar.groovy)
at com.jayway.restassured.RestAssured.(RestAssured.java:349)
at com.hascode.ra_samples.TestAssured.setUp(TestAssured.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:24)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
at org.junit.runner.JUnitCore.run(JUnitCore.java:127)
at org.junit.runner.JUnitCore.runClasses(JUnitCore.java:76)
at com.hascode.ra_samples.TestRunner.main(TestRunner.java:9)

I am facing javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure while using rest-assured. I have tried a lot of things but still its not working. Can you have a look at this and let me know if you can help in this?

When i execute this code I am getting the following error->
avax.net.ssl.SSLException: SSL peer shut down incorrectly
at sun.security.ssl.InputRecord.readV3Record(Unknown Source)
at sun.security.ssl.InputRecord.read(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)

/login
/user/
/user/{id}
/user/search
*For all endpoints other than /login an authorization token needs to be passed as an HTTP Header:*

X-Auth-Token:
e.g.

X-Auth-Token: 1234-56789-12345

/login

The service exposes a login endpoint ( /login) which takes a POST request with two parameters: username and password.
Following a successful login, an authentication token will be returned which must be used to make additional requests to the service.

Thing is that on post request on login I will get back token I need to store this token and pass it in susbsquent request. I tried using below code its not working..First .parameters is deprecated not sure how to replace it and with what?Also not sure how to use JsonPath?

in the Jenkins war-file there is an embedded servlet container included and a main-class entry in the manifest file allows you to start this embedded server but it is NOT the default way to run war-files – it’s important to know that!

For your use-case you could download and install a decent servlet container like Tomcat (https://tomcat.apache.org/) or Jetty (http://www.eclipse.org/jetty/), start the server and install the war file .. or if you’ve got the build tool Maven (http://maven.apache.org/) installed – what you’re likely to have installed as a Java developer, simply change into the directory of the sample application and run this command: mvn tomcat:run as documented in my tutorial here.