KEMBAR78
Automate REST Services Testing with RestAssured | PDF
1
Automate REST Services Testing
with REST-Assured
Eing Ong
Principle Software Engineer in Quality
2
Session outline
•  Understanding REST
•  What is REST-Assured
•  REST-Assured CLI
•  Demo
•  Q & A
3
What is a REST call?
GET http://example.com/customer?operation=view&id=12345&format=json
GET http://example.com/customers/12345
Accept: application/json
4
What is REST?
•  Resource identification through URI
•  Uniform interface
•  Self-descriptive messages
•  Stateful interactions through hyperlinks
GET http://example.com/customers/12345
Accept: application/json
What is REST-Assured
6
REST-Assured: An Overview
•  Java Domain Specific Language (DSL) for testing REST
services
•  Built on top of HTTPBuilder
•  Supports POST, GET, PUT, DELETE, OPTIONS, PATCH
and HEAD requests
•  Supports validation and verification of responses
7
REST-Assured: a BDD language
given().
baseUri(“http://example.com”).
contentType(ContentType.JSON).
when().
get(“/customers/12345”).
then().
statusCode(200);
GET http://example.com/customers/12345
Accept: application/json
8
REST-Assured: a BDD language
given().
baseUri(“http://example.com”).
contentType(ContentType.JSON).
when().
get(“/customers/12345”).
then().
statusCode(200);
GET http://example.com/customers/12345
Accept: application/json
Test setup
Test action
Test verification
9
File opsCert = new File(CERTPATH);
opsCertFIS = new FileInputStream(CERTPATH);
fis = new FileInputStream(URL);
bis = new BufferedInputStream(fis);
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(opsCertFIS, CERTPASSWORD.toCharArray());
opsCertFIS.close();
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null);
CertificateFactory cf = CertificateFactory.getInstance(X509);
while (bis.available() > 0) {
java.security.cert.Certificate cert = cf.generateCertificate(bis);
trustStore.setCertificateEntry(URL, cert);
}
bis.close();
fis.close();
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(SUN_X509, "SunJSSE”)
keyManagerFactory.init(keyStore, CERTPASSWORD.toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(SUN_X509, "SunJS
trustManagerFactory.init(trustStore);
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), ne
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, SSLConnectio
PlainConnectionSocketFactory plainSf = new PlainConnectionSocketFactory();
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocket
RestAssured: Complexity made simple
given().
keystore(”pathToKeyStore”,”password”).
…
10
REST-Assured: Complexity made simple
Supports 6 forms of authentication
•  Basic Auth
given().auth().basic("username", "password”);
•  OAuth
given().auth().oauth(consumerKey, consumerSecret, accessToken, secretToken);
given().auth().oauth2(…);
•  Others
•  Form
•  Certificate
•  Digest
11
REST-Assured: Complexity made simple
Session management
given().sessionId("AS34979870H") … or
given().cookie("JSESSIONID", "AS34979870H”) … or
SessionFilter filter = new SessionFilter();
given().auth().form(”first", ”last").filter(filter).get(”/auth”);
given().filter(filter).post(). …
12
REST-Assured: Complexity made simple
•  Serialization
Customer customer = new Customer();
customer.setFirstname(”John");
Response response =
given().body(customer).post("/customers");
•  Deserialization
Customer customer = response.as(Customer.class);
assertThat(customer.getFirstname(), is(expectedFirstname));
13
REST-Assured: Reusability of requests
•  How do we reuse request setup?
–  Add setup steps to RequestSpecification
RequestSpecification requestSpec = new RequestSpecBuilder().
setContentType(ContentType.JSON).build();
// Default JSON content type
given().spec(requestSpec).post();
// Overwrite default content type with XML
given().spec(requestSpec).contentType(ContentType.XML).post();
14
REST-Assured: More requests reusability
•  7 ways to add cookies and headers
in request spec
•  23 ways to add parameters
–  form, query, path
•  19 ways to add request body
•  Other useful methods
addHeader("Cache-Control", "no-cache”)
addCookie(”Version”, “1”)
addQueryParam("country", "US”)
addPathParams("entityType","vendor”)
addFormParameter("State","CA”)
addMultiPart(new File("customer.json"))
setBody("Signature=HmacSHA256”)
addRequestSpecification(anotherSpec)
log(LogDetail.ALL)
http://rest-assured.googlecode.com/svn/tags/2.4.1/apidocs/com/jayway/restassured/builder/RequestSpecBuilder.html
15
REST-Assured: Assertions made easy
when().
post("/customers").
then().
cookie("Version", "1").
statusLine(containsString("Bad Request")).
header("Authorization", containsString("basic")).
body(equalTo(”<customer><id>1</id></customer>"));
http://rest-assured.googlecode.com/svn/tags/2.4.1/apidocs/com/jayway/restassured/response/ValidatableResponse.html
16
REST-Assured: Complex assertions made easy
{
"firstName": ”J”, "lastName": ”D",
”phone": [
{ "type": ”work”,
"number”: "6501234566” },
{ "type": ”work”,
"number”: "6501234567” },
{ "type": "fax”,
"number": "6501234568” }
]
}
1.  when().
get("/customers/1").
then().
body("phone.type", hasItems("work", "fax"));
2.  List<HashMap> phones = JsonPath.
from(resp).getList("phone", HashMap.class);
3.  List<Map> workphones =
from(resp).get("phone.findAll {
phone-> phone.type == "work" }");
4.  What about XML?
•  Use XmlPath
17
REST-Assured: Reusability in response verification
ResponseSpecification responseSpec = new ResponseSpecBuilder().
expectStatusCode(200).
expectContentType(ContentType.JSON).build();
expect().
spec(responseSpec).
body(”lastName", equalTo(lastName)).
when().
get("/customers/” + id);
http://rest-assured.googlecode.com/svn/tags/2.4.1/apidocs/com/jayway/restassured/builder/ResponseSpecBuilder.html
18
REST-Assured: Scalability and maintainability
•  Building readable complex requests
•  Leverage xUnit harness and its extensions
•  Scaling across teams depending on the same service:
Create shareable libraries
•  Reside in same repository as source code:
Both Dev & QE own the tests!
•  Common IDE support
•  Common continuous integration (CI) tools support
REST-Assured
Command Line Interface (CLI)
20
REST-Assured CLI: Jumpstart your testing
1.  Creates test project modules
2.  Creates maven poms with necessary dependencies
3.  Creates REST-Assured sample tests
Jumpstart your REST-Assured testing
https://github.com/eing/restassured-cli
Demo
22
Resources
•  RESTAssured official guide
https://code.google.com/p/rest-assured/wiki/Usage
http://rest-assured.googlecode.com/svn/tags/2.4.1/apidocs/index.html
http://www.jayway.com/2011/06/04/is-your-rest-assured/
http://www.jayway.com/2013/04/12/whats-new-in-rest-assured-1-8/
http://www.jayway.com/2013/11/29/rest-assured-2-0-testing-your-rest-services-is-easier-than-ever/
http://www.jayway.com/2013/12/10/json-schema-validation-with-rest-assured/
•  Blogs
http://www.hascode.com/2011/10/testing-restful-web-services-made-easy-using-the-rest-assured-framework/
http://www.hascode.com/2011/09/rest-assured-vs-jersey-test-framework-testing-your-restful-web-services/
http://giallone.blogspot.com/2013/01/java-rest-assured-or-rest-very-easy.html
Q & A
24
FAQ: SOAP support
SOAP is HTTP based, so yes! RESTAssured can be used for SOAP
given().
header("SOAPAction", “http://example/getVendor”).
contentType("application/soap+xml; charset=UTF-8;").
body(envelope).
when().
post();
https://groups.google.com/forum/#!topic/rest-assured/y5IBklgfY88
25
FAQ: Asynchronous responses
Awaitability (https://code.google.com/p/awaitility/wiki/Usage) is one fluent solution
String batchId =
when().
post("/batch").
then().
statusCode(200).
extract().header("X-AX-TRANSACTIONID");
await().atMost(50, TimeUnit.SECONDS).until(batchActivityCompleted(batchId));
Java 8
await().atMost(50, SECONDS).until(() -> // Code to check completion );
26
FAQ: Coding style auto-formatting
•  Enable formatter markers in comments
// @formatter:off
given().
spec(requestSpec).
when().
get("/photos").
// @formatter:on
https://groups.google.com/forum/#!topic/rest-assured/e6Sx_4way2M
Eclipse: http://stackoverflow.com/questions/1820908/how-to-turn-off-the-eclipse-code-formatter-for-certain-sections-of-java-code
Intellij: http://sqa.stackexchange.com/questions/9781/auto-formatting-restassured-test-cases-in-my-ide
27
FAQ: E2E services integration testing
Paycheck
service
Employee
service
Company
service
CRUD
Request
Specifications
BaseUri
BasePath
ContentType
HTTP actions
Headers
SessionId, …
Domain Services Library
String companyId =
new CompanyServiceObject().
create(“name”);
String employeeId =
new EmployeeServiceObject().
create(companyId);
String paycheckId =
new PaycheckServiceObject().
create(employeeId,
currentMonth);
Thank you !

Automate REST Services Testing with RestAssured

  • 1.
    1 Automate REST ServicesTesting with REST-Assured Eing Ong Principle Software Engineer in Quality
  • 2.
    2 Session outline •  UnderstandingREST •  What is REST-Assured •  REST-Assured CLI •  Demo •  Q & A
  • 3.
    3 What is aREST call? GET http://example.com/customer?operation=view&id=12345&format=json GET http://example.com/customers/12345 Accept: application/json
  • 4.
    4 What is REST? • Resource identification through URI •  Uniform interface •  Self-descriptive messages •  Stateful interactions through hyperlinks GET http://example.com/customers/12345 Accept: application/json
  • 5.
  • 6.
    6 REST-Assured: An Overview • Java Domain Specific Language (DSL) for testing REST services •  Built on top of HTTPBuilder •  Supports POST, GET, PUT, DELETE, OPTIONS, PATCH and HEAD requests •  Supports validation and verification of responses
  • 7.
    7 REST-Assured: a BDDlanguage given(). baseUri(“http://example.com”). contentType(ContentType.JSON). when(). get(“/customers/12345”). then(). statusCode(200); GET http://example.com/customers/12345 Accept: application/json
  • 8.
    8 REST-Assured: a BDDlanguage given(). baseUri(“http://example.com”). contentType(ContentType.JSON). when(). get(“/customers/12345”). then(). statusCode(200); GET http://example.com/customers/12345 Accept: application/json Test setup Test action Test verification
  • 9.
    9 File opsCert =new File(CERTPATH); opsCertFIS = new FileInputStream(CERTPATH); fis = new FileInputStream(URL); bis = new BufferedInputStream(fis); KeyStore keyStore = KeyStore.getInstance("PKCS12"); keyStore.load(opsCertFIS, CERTPASSWORD.toCharArray()); opsCertFIS.close(); KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); trustStore.load(null); CertificateFactory cf = CertificateFactory.getInstance(X509); while (bis.available() > 0) { java.security.cert.Certificate cert = cf.generateCertificate(bis); trustStore.setCertificateEntry(URL, cert); } bis.close(); fis.close(); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(SUN_X509, "SunJSSE”) keyManagerFactory.init(keyStore, CERTPASSWORD.toCharArray()); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(SUN_X509, "SunJS trustManagerFactory.init(trustStore); SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), ne SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, SSLConnectio PlainConnectionSocketFactory plainSf = new PlainConnectionSocketFactory(); Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocket RestAssured: Complexity made simple given(). keystore(”pathToKeyStore”,”password”). …
  • 10.
    10 REST-Assured: Complexity madesimple Supports 6 forms of authentication •  Basic Auth given().auth().basic("username", "password”); •  OAuth given().auth().oauth(consumerKey, consumerSecret, accessToken, secretToken); given().auth().oauth2(…); •  Others •  Form •  Certificate •  Digest
  • 11.
    11 REST-Assured: Complexity madesimple Session management given().sessionId("AS34979870H") … or given().cookie("JSESSIONID", "AS34979870H”) … or SessionFilter filter = new SessionFilter(); given().auth().form(”first", ”last").filter(filter).get(”/auth”); given().filter(filter).post(). …
  • 12.
    12 REST-Assured: Complexity madesimple •  Serialization Customer customer = new Customer(); customer.setFirstname(”John"); Response response = given().body(customer).post("/customers"); •  Deserialization Customer customer = response.as(Customer.class); assertThat(customer.getFirstname(), is(expectedFirstname));
  • 13.
    13 REST-Assured: Reusability ofrequests •  How do we reuse request setup? –  Add setup steps to RequestSpecification RequestSpecification requestSpec = new RequestSpecBuilder(). setContentType(ContentType.JSON).build(); // Default JSON content type given().spec(requestSpec).post(); // Overwrite default content type with XML given().spec(requestSpec).contentType(ContentType.XML).post();
  • 14.
    14 REST-Assured: More requestsreusability •  7 ways to add cookies and headers in request spec •  23 ways to add parameters –  form, query, path •  19 ways to add request body •  Other useful methods addHeader("Cache-Control", "no-cache”) addCookie(”Version”, “1”) addQueryParam("country", "US”) addPathParams("entityType","vendor”) addFormParameter("State","CA”) addMultiPart(new File("customer.json")) setBody("Signature=HmacSHA256”) addRequestSpecification(anotherSpec) log(LogDetail.ALL) http://rest-assured.googlecode.com/svn/tags/2.4.1/apidocs/com/jayway/restassured/builder/RequestSpecBuilder.html
  • 15.
    15 REST-Assured: Assertions madeeasy when(). post("/customers"). then(). cookie("Version", "1"). statusLine(containsString("Bad Request")). header("Authorization", containsString("basic")). body(equalTo(”<customer><id>1</id></customer>")); http://rest-assured.googlecode.com/svn/tags/2.4.1/apidocs/com/jayway/restassured/response/ValidatableResponse.html
  • 16.
    16 REST-Assured: Complex assertionsmade easy { "firstName": ”J”, "lastName": ”D", ”phone": [ { "type": ”work”, "number”: "6501234566” }, { "type": ”work”, "number”: "6501234567” }, { "type": "fax”, "number": "6501234568” } ] } 1.  when(). get("/customers/1"). then(). body("phone.type", hasItems("work", "fax")); 2.  List<HashMap> phones = JsonPath. from(resp).getList("phone", HashMap.class); 3.  List<Map> workphones = from(resp).get("phone.findAll { phone-> phone.type == "work" }"); 4.  What about XML? •  Use XmlPath
  • 17.
    17 REST-Assured: Reusability inresponse verification ResponseSpecification responseSpec = new ResponseSpecBuilder(). expectStatusCode(200). expectContentType(ContentType.JSON).build(); expect(). spec(responseSpec). body(”lastName", equalTo(lastName)). when(). get("/customers/” + id); http://rest-assured.googlecode.com/svn/tags/2.4.1/apidocs/com/jayway/restassured/builder/ResponseSpecBuilder.html
  • 18.
    18 REST-Assured: Scalability andmaintainability •  Building readable complex requests •  Leverage xUnit harness and its extensions •  Scaling across teams depending on the same service: Create shareable libraries •  Reside in same repository as source code: Both Dev & QE own the tests! •  Common IDE support •  Common continuous integration (CI) tools support
  • 19.
  • 20.
    20 REST-Assured CLI: Jumpstartyour testing 1.  Creates test project modules 2.  Creates maven poms with necessary dependencies 3.  Creates REST-Assured sample tests Jumpstart your REST-Assured testing https://github.com/eing/restassured-cli
  • 21.
  • 22.
    22 Resources •  RESTAssured officialguide https://code.google.com/p/rest-assured/wiki/Usage http://rest-assured.googlecode.com/svn/tags/2.4.1/apidocs/index.html http://www.jayway.com/2011/06/04/is-your-rest-assured/ http://www.jayway.com/2013/04/12/whats-new-in-rest-assured-1-8/ http://www.jayway.com/2013/11/29/rest-assured-2-0-testing-your-rest-services-is-easier-than-ever/ http://www.jayway.com/2013/12/10/json-schema-validation-with-rest-assured/ •  Blogs http://www.hascode.com/2011/10/testing-restful-web-services-made-easy-using-the-rest-assured-framework/ http://www.hascode.com/2011/09/rest-assured-vs-jersey-test-framework-testing-your-restful-web-services/ http://giallone.blogspot.com/2013/01/java-rest-assured-or-rest-very-easy.html
  • 23.
  • 24.
    24 FAQ: SOAP support SOAPis HTTP based, so yes! RESTAssured can be used for SOAP given(). header("SOAPAction", “http://example/getVendor”). contentType("application/soap+xml; charset=UTF-8;"). body(envelope). when(). post(); https://groups.google.com/forum/#!topic/rest-assured/y5IBklgfY88
  • 25.
    25 FAQ: Asynchronous responses Awaitability(https://code.google.com/p/awaitility/wiki/Usage) is one fluent solution String batchId = when(). post("/batch"). then(). statusCode(200). extract().header("X-AX-TRANSACTIONID"); await().atMost(50, TimeUnit.SECONDS).until(batchActivityCompleted(batchId)); Java 8 await().atMost(50, SECONDS).until(() -> // Code to check completion );
  • 26.
    26 FAQ: Coding styleauto-formatting •  Enable formatter markers in comments // @formatter:off given(). spec(requestSpec). when(). get("/photos"). // @formatter:on https://groups.google.com/forum/#!topic/rest-assured/e6Sx_4way2M Eclipse: http://stackoverflow.com/questions/1820908/how-to-turn-off-the-eclipse-code-formatter-for-certain-sections-of-java-code Intellij: http://sqa.stackexchange.com/questions/9781/auto-formatting-restassured-test-cases-in-my-ide
  • 27.
    27 FAQ: E2E servicesintegration testing Paycheck service Employee service Company service CRUD Request Specifications BaseUri BasePath ContentType HTTP actions Headers SessionId, … Domain Services Library String companyId = new CompanyServiceObject(). create(“name”); String employeeId = new EmployeeServiceObject(). create(companyId); String paycheckId = new PaycheckServiceObject(). create(employeeId, currentMonth);
  • 28.