2015-StarWest presentation on REST-assured

31
1 Automate REST Services Testing with REST-assured Eing Ong Principle Software Engineer in Test

Transcript of 2015-StarWest presentation on REST-assured

1

Automate REST Services Testing with REST-assured

Eing Ong Principle Software Engineer in Test

2

Session outline

•  Why REST-assured •  REST-assured •  Demo: REST-assured CLI •  Q & A

3

Our Journey

Survey

Survey automation frameworks used for Java component services testing

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

What is REST-assured

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!

REST-assured Command Line Interface (CLI)

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

Demo

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);

31

FAQ: Key attributes of a RESTful call

• Uniform interface – Resource identification through URI – Self-descriptive messages

• Stateful interactions through hyperlinks

GET http://example.com/customers/12345 Accept: application/json JSESSIONID=AS34979870H