2015-StarWest presentation on REST-assured
Transcript of 2015-StarWest presentation on REST-assured
4
Our Journey
Survey Results &
evaluations
Types of solutions • Home-grown (DIY)
• Open source tools (OST)
• Commercial-off-the-shelve (COTS)
5
Our Journey
Survey Results &
evaluations
Problems we encounter • Sharing code libraries
• Readability and maintenance
• Providing support
6
Our Journey
Survey Results & evaluations
Principles & requirements
• Mature OST over COTS and COTS over DIY
• Simple, easy and readable code
• Easily extended and customized
• Support all aspects of REST testing in Java
7
Our Journey
Survey Results & evaluations
Principles & requirements Proposal
Started in Dec 2010 by Johan Haleby with 40 over releases, has active ownership & user group
9
REST-assured: An Overview
• Java Domain Specific Language (DSL) for testing REST services
• Built on top of HTTPBuilder
• Supports response parsing and assertions
• Supports BDD syntax
10
REST-assured: a BDD language
given(). …). …).
when(). …
then(). …
GET http://example.com/customers/12345 Accept: application/json
Test setup
Test action
Test verification
11
REST-assured: a DSL
given(). baseUri("http://example.com"). contentType(ContentType.JSON).
when(). get("/customers/12345").
then(). statusCode(200);
GET http://example.com/customers/12345 Accept: application/json
12
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
REST-assured: Complexity made simple
given(). keystore( "pathToKeyStore", "password"). …
13
REST-assured: Complexity made simple
Supported authentication schemes • Basic Auth
given().auth().basic("username", "password");
• OAuth
given().auth().oauth(consumerKey, consumerSecret, accessToken, secretToken);
given().auth().oauth2(…);
• Others • Form, certificate, digest
14
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(). …
15
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));
16
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)…
// Overwrite default content type with XML
given().spec(requestSpec).contentType(ContentType.XML)…
17
REST-assured: More requests reusability
• 7 ways to add cookies and headers in request spec
• 23 ways to add parameters
• 19 ways to add request body
• Other useful methods
addHeader(…)
addCookie("Version", "1")
addQueryParam(…)
addPathParams(…)
addMultiPart(
new File("customer.json"))
setBody(…)
addRequestSpecification(..)
log(LogDetail.ALL) http://rest-assured.googlecode.com/svn/tags/2.4.1/apidocs/com/jayway/restassured/builder/RequestSpecBuilder.html
18
REST-assured: Assertions made easy
when().
post("/customers").
then().
cookie("Version", "1").
statusLine(containsString("Bad Request")).
header("Authorization", containsString("basic")).
body(equalTo(”<customer></customer>"));
http://rest-assured.googlecode.com/svn/tags/2.4.1/apidocs/com/jayway/restassured/response/ValidatableResponse.html
19
REST-assured: Complex assertions made easy
{ "firstName": "J",
"lastName": "D",
"phone": [
{ "type": "work",
"number": "6501234566" },
{ "type": "work",
"number": "6501234567" },
{ "type": "fax",
"number": "6501234568” } ]
}
1. … .then(). body("phone.type", hasItems("work", "fax"));
2. from(response.asString()). getList("phone", HashMap.class);
3. from(response.asString()). get("phone.findAll { phone->
phone.type == \"work\" }");
4. What about XML? • Use XmlPath
20
REST-assured: Summary
• Code readability and simplicity = more maintainable code!
• Can be used with standard tools (e.g. IDE, test harness, static analysis tools)
• Can easily scale with large test suites and complex requests
• Shared code ownership
– Can reside in same repository as source code so
ü Both Dev & QE own the tests!
22
REST-assured CLI: Jumpstart your testing
1. Creates test project modules 2. Creates maven poms with necessary
dependencies 3. Creates REST-Assured sample tests 4. Runs tests without recompilation
http://github.com/eing/restassured_cli
24
Resources • REST-assured 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/
Thank you ! (Please fill in the feedback form)
[email protected] github.com/eing eingong.blogspot.com @eingong
Q & A
26
FAQ: SOAP support
SOAP is HTTP based, so yes! REST-assured 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
27
FAQ: Asynchronous responses
Awaitability (https://code.google.com/p/awaitility/wiki/Usage)
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 );
28
FAQ: 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
29
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
30
FAQ: E2E services integration testing
Paycheck service
Employee service
Company service
CRUD
Request Specifications
BaseUri BasePath
ContentType Headers
SessionId …
Domain Services Library
String companyId = new CompanyServiceObject(). create(“company name”);
String employeeId =
new EmployeeServiceObject(). create(companyId);
String paycheckId =
new PaycheckServiceObject(). create(employeeId, currentMonth);