Upgrade to Pro — share decks privately, control downloads, hide ads and more …

"Organizing crossplatform API automation testin...

"Organizing crossplatform API automation testing" from Sergey Zenchenko

The presentation is about how to test your server API and share API client between tests and mobile app.
Find more useful slides at Sergey's account: https://speakerdeck.com/sergeyzenchenko

uaMobiTech

July 28, 2016
Tweet

More Decks by uaMobiTech

Other Decks in Programming

Transcript

  1. • > 100 endpoints • ~ 40 team members •

    2 mobile platforms + backend • Micro-services architecture • Need for tests Given
  2. Codeception • PHP sucks • Concurrency support is limited •

    API client is low level and verbose • Hard to maintain large test suite • No static typing • Code is not reusable codeception.com
  3. Runscope • UI Based • Slooooow • Hard to maintain

    large test suite • Code is not reusable runscope.com
  4. Mocha/Supertest/ Chakram • API client is low level and verbose

    • Concurrency support is limited • Hard to maintain large test suite • No static typing • Code is not reusable https://mochajs.org https://github.com/visionmedia/supertest http://dareid.github.io/chakram/
  5. Requirements • Parallel execution • Simple test structure. No async

    in tests • Test should operate with business domain, not with HTTP requests • Work with Objects not JSON and Strings • Static typing • Code reusability
  6. Java to the rescue! • Already used in the Android

    app for UI tests • Can be shared between multiple components • Good concurrency support • Mature test frameworks
  7. Main components • Test framework • Domain models • API

    Client • Support: assertions frameworks, reporting tool, etc
  8. TestNG • xUnit style • Parallel test execution • Powerful

    concurrency management using method and group dependencies • Nice features like data providers testng.org
  9. Models • Request models • Response models • Assertions for

    models attrs., not for JSON/XML attrs. Never work with raw data • Response structure validation should be done by model parser, not by humans
  10. REST-Assured • Simple DSL • Designed especially for testing •

    POJO support • Might be too low level sometimes • No code reuse :( rest-assured.io
  11. Retrofit • One of the most popular API frameworks for

    Java • Code can be reused outside of test project • Can use POJOs • Not flexible enough sometimes square.github.io/retrofit/
  12. Retrofit sample More samples
 See https://github.com/techery/janet-sample-api-integration public static class BlogPost

    { public int id; public String title; public String text; } public interface BlogAPI { @POST("/posts") BlogPost create(@Field("title") String title, @Field("text") String text); } void testBlogPosting() { String title = "Amazing post"; String body = "hey"; BlogPost blogPost = blogAPI.create(title, body); assertThat(blogPost.text, equals(title)); }
  13. Janet • Command based service layer • Protocol agnostic •

    Based on reactive programming approach • Can be used for HTTP with janet-http service • Can be used in any JVM app github.com/techery/janet
  14. Janet Action • Java class that describes operation • Each

    API request is a separate Janet Action • Purely declarative • Annotations are used to map class attrs. to HTTP request values • Action are executed by services. (HTTPService, WebSocketService, SOAPService, YourCustomService)
  15. Step 1: define action More samples
 See https://github.com/techery/janet-sample-api-integration @HttpAction(value =

    "/health_check", method = HttpAction.Method.GET) public class HealthCheckAction { @Query("url") public final String url; public HealthCheckAction(String url) { this.url = url; } @Response public HealthStatus response; }
  16. Step 2: define model More samples
 See https://github.com/techery/janet-sample-api-integration public class

    HealthStatus { @SerializedName("is_available") public Boolean isAvailable; @SerializedName("responseTime") public float responseTime; }
  17. Step 3: write test More samples
 See https://github.com/techery/janet-sample-api-integration public class

    HealthCheckTest { Janet janet; void testHealthCheck() { String originalURL = "https://techery.io/jobs"; final ActionPipe<HealthCheckAction> pipe = janet.createPipe(HealthCheckAction.class); final Observable<ActionState<HealthCheckAction>> observable = pipe.createObservable(new HealthCheckAction(originalURL)); HealthCheckAction action = observable.toBlocking().last().action; HealthStatus response = action.response; assertThat(response).isNotNull(); assertThat(response.isAvailable).isTrue(); assertThat(response.responseTime).isLessThan(100.0f); } }
  18. Step 3: write test with some helpers More samples
 See

    https://github.com/techery/janet-sample-api-integration public class HealthCheckTest extends BaseTest { void testHealthCheck() { String originalURL = "https://techery.io/jobs"; HealthCheckAction action = execute(new HealthCheckAction(originalURL)); HealthStatus response = action.response; assertThat(response).isNotNull(); assertThat(response.isAvailable).isTrue(); assertThat(response.responseTime).isLessThan(100.0f); } }
  19. Step 1: define action More samples
 See https://github.com/techery/janet-sample-api-integration @WsAction(event =

    "health_check") public class HealthCheckAction { @Payload("url") public final String url; public HealthCheckAction(String url) { this.url = url; } @Response public HealthStatus response; }
  20. Step 2: define model More samples
 See https://github.com/techery/janet-sample-api-integration public class

    HealthStatus { @SerializedName("is_available") public Boolean isAvailable; @SerializedName("responseTime") public float responseTime; }
  21. Step 3: write test with some helpers More samples
 See

    https://github.com/techery/janet-sample-api-integration public class HealthCheckTest extends BaseTest { void testHealthCheck() { String originalURL = "https://techery.io/jobs"; HealthCheckAction action = execute(new HealthCheckAction(originalURL)); HealthStatus response = action.response; assertThat(response).isNotNull(); assertThat(response.isAvailable).isTrue(); assertThat(response.responseTime).isLessThan(100.0f); } }
  22. API development workflow 1. New API feature request 2. Team

    defines models and actions 3. Team writes tests for new endpoint 4. Android team can now start implementing feature by mocking actions if required. 5. Tests run on CI to check if feature is working 6. Backend team deploys new API endpoint 7. Tests pass and feature is ready
  23. API development workflow Actions and Models serve as an API

    contract and every team member can contribute to it
  24. Platform structure Janet based API Client Android app API tests

    UI tests API docs (in beta) iOS Client (in future)