Slide 1

Slide 1 text

How to test complex API integrations Elias Nogueira JAVAZONE 2022

Slide 2

Slide 2 text

Elias Nogueira I help professional software engineers (backend, frontend, qa) to develop their quality mindset and deliver bug-free software so they become top-level engineers and get hired for the best positions in the market. 🏒 Backbase πŸ‘¨πŸ’»β€β€ Principal Software Engineer πŸ“ Utrecht, the Netherlands 🌐 eliasnogueira.com 🐦 @eliasnogueira bit.ly/eliasnogueira

Slide 3

Slide 3 text

What problem do we want to solve?

Slide 4

Slide 4 text

Implicitly we want … ● Increase confidence in delivery ● Cover key business scenarios ● The certainty that the test will find a possible failure after some modification

Slide 5

Slide 5 text

API anatomy (testing perspective)

Slide 6

Slide 6 text

Individual APIs API API API API API API API API Each microservice is a small feature that runs in isolation.

Slide 7

Slide 7 text

Individual APIs Unit Tests done! API API API API API API API API Each API must have its unit tests and integration. Integration Tests* done! * API Tests running in an integration layer with or without mocks

Slide 8

Slide 8 text

API API API API API API The problem Integration tests won’t cover real scenarios of dependent APIs because of the mocks. M O CK API M O CK API

Slide 9

Slide 9 text

Possible solution

Slide 10

Slide 10 text

API API API API API API API API Possible solution Create functional tests and e2e to cover possible gaps and decrease the test on the UI. Functional Tests & E2E

Slide 11

Slide 11 text

API API API API API API Possible solution What Add tests to any kind of dependencies, as well for the user journey depends consum es REAL API REAL API

Slide 12

Slide 12 text

Analogy: buying a flight ticket

Slide 13

Slide 13 text

Buying a flight ticket We must make sure each API is self-tested unit -> integration -> functional Search Flight selection Payment Confirmation API API API API

Slide 14

Slide 14 text

Buying a flight ticket We must make sure each API is self-tested unit -> integration -> functional Search Flight selection Payment Confirmation Valid dates Invalid return date No flights found API API API API

Slide 15

Slide 15 text

Buying a flight ticket We must make sure each API is self-tested e2e: buy a round-trip flight Search Flight selection Payment Confirmation Select valid dates API API API API Select a flight with seats available Make a payment with valid data Successful notification E2E Scenario

Slide 16

Slide 16 text

How can test projects be created?

Slide 17

Slide 17 text

Model 1 A test project for all microservices BACKEND TEST TEST PROJECT

Slide 18

Slide 18 text

Model 1 Pros ● Centralization of code in a single project ● Speed and agility in creating tests and solving problems Cons ● Constant changes by several people can have side effects on results

Slide 19

Slide 19 text

Model 2 A test project for each microservice where interactions with the endpoint (s) will be in the test project. BACKEND TEST TEST TEST TEST PROJECT

Slide 20

Slide 20 text

Model 2 Pros ● Organized decentralization of test projects towards an API ● Isolation between APIs Cons ● Possible code duplication

Slide 21

Slide 21 text

Model 3 A test project for each microservice divided into client and test projects BACKEND TEST PROJECT TEST TEST TEST CLIENT CLIENT CLIENT

Slide 22

Slide 22 text

Model 3 Client project We will put here all the necessary logic to make the requests as: β—‹ Exception return β—‹ Transport Objects β—‹ Request call β—‹ Customizations for validations β—‹ Pointing settings (URI, base path, port)

Slide 23

Slide 23 text

Model 3 Test Project We will put here all the methods of using the API we created in the client project, creating the testing logic and validating the results. In summary, all tests are created here!

Slide 24

Slide 24 text

Model 3 Pros ● Greater version management (new features, breaking changes) ● Easy use by other teams β—‹ they just need to consume the customer and create their tests Cons ● Time increase compared to previous models

Slide 25

Slide 25 text

Implementation exemple

Slide 26

Slide 26 text

Implementation example Project separation BACKEND TEST PROJECT TEST TEST TEST CLIENT CLIENT CLIENT COMMONS PARENT

Slide 27

Slide 27 text

Project separation CLIENT TEST COMMONS PARENT Project containing all calls to the microservice, whether the calls were successful or simulating exceptions. Project containing tests for the microservice, testing its functionality and dependencies with other microservices. Code and libraries common to clients such as URL definitions, authentication, and any other shared code. Code and libraries common to tests such as testing data, support functions, or any common code related to tests.

Slide 28

Slide 28 text

Microservice examples Possible graphical interface: Constraint check by CPF We should inform a CPF * Its a Brazilian social security number If a restriction is found, show a message

Slide 29

Slide 29 text

Microservice examples Possible graphical interface: Loan Simulation Fill in loan information

Slide 30

Slide 30 text

Microservice examples We will put here all the necessary logic to make the requests as: RESTRICTIONS GET /api/v1/restricrions/{cpf} GET /api/v2/restricrions/{cpf} Constraint Query API SIMULATIONS GET /api/v1/simulations/ GET /api/v1/simulations/{cpf} POST /api/v1/simulations/ PUT /api/v1/simulations/{cpf} DELETE /api/v1/simulations/{cpf} Credit Simulation API

Slide 31

Slide 31 text

Client’s implementation Methods will be created to simulate all possible calls from each HTTP method CLIENT RESTRICTIONS GET /api/v1/restricrions/{cpf} Constaint Query API Client Method - find CPF Method - find CPF and return an exception

Slide 32

Slide 32 text

CLIENT SIMULATIONS GET /api/v1/simulations/ GET /api/v1/simulations/{cpf} POST /api/v1/simulations/ Credit Simulation Client API Method – find all simulations Method – find a simulation by a given CPF Method – find a simulation by a given CPF and return not found Method – submit a simulation Method – submit a simulation and return unprocessable entity Method – submit a simulation and return conflict Methods will be created to simulate all possible calls from each HTTP method Client’s implementation

Slide 33

Slide 33 text

CLIENT SIMULATIONS POST /api/v1/simulations/ Credit Simulation Client API Method – submit a simulation A test method will be created for one or more use of the methods on the client Test implementation TEST SIMULATIONS should create a successful simulation - Test Credit Simulation Test Project

Slide 34

Slide 34 text

CLIENT SIMULATIONS POST /api/v1/simulations/ Method – submit a simulation and return unprocessable entity A test method will be created for one or more use of the methods on the client TEST SIMULATIONS should show an error regarding an attribute not sent in the request - Test - Test Credit Simulation Client API Credit Simulation Test Project Test implementation Method – submit a simulation should create a successful simulation

Slide 35

Slide 35 text

CLIENT SIMULATIONS POST /api/v1/simulations/ Method – submit a simulation and return conflict TEST SIMULATIONS should show conflict when CPF already exists - Test Credit Simulation Client API Credit Simulation Test Project A test method will be created for one or more use of the methods on the client Test implementation Method – submit a simulation and return unprocessable entity should show an error regarding an attribute not sent in the request - Test - Test Method – submit a simulation should create a successful simulation

Slide 36

Slide 36 text

How to use client <-> test?

Slide 37

Slide 37 text

How to use client <-> test? Through the client version ● We must add the client dependency in the test com.eliasnogueira simulations-client 1.2.5 "devDependencies": { "@eliasnogueira/simulations-client": ”1.2.5", } Java + Maven example Typescript + Node example

Slide 38

Slide 38 text

How to use client <-> test? Pros: association of the client with the microservice version Just as the microservice evolves the client and the test evolve. Adding a changelog with the association of the client version with the microservice version can help fix bugs. Also tags helps if you would like to track the evolution.

Slide 39

Slide 39 text

What can be improved

Slide 40

Slide 40 text

What can be improved? ● All the test presented in the *-test project could be moved to the integration layer β—‹ they will provide you faster feedback ● The *-test projects must have the functional/e2e tests using different APIs we depends on

Slide 41

Slide 41 text

What can be improved? Continuous Delivery API approach build unit tests integration tests e2e API tests local release release/deploy Sift-Left Testing applied https://speakerdeck.com/eliasnogueira/technical-aspects-of-implementing-the-shift-left-approach

Slide 42

Slide 42 text

Recap

Slide 43

Slide 43 text

Recap ● We’ve created a robust model for β—‹ test a microservice in isolation (functional test) β—‹ test a microservice and its dependencies (e2e) ● We’ve modularized the creation of projects β—‹ client: the entire API call for a microservice β—‹ test: test project using the microservice client β—‹ commons: client codes and libraries β—‹ parent: test code and libraries

Slide 44

Slide 44 text

Thank you! SCAN ME You can follow me on Twitter @eliasnogueira and find the practical examples of this presentation. Be sure to simulate the examples in the code!

Slide 45

Slide 45 text

Projects β€’ https://github.com/eliasnogueira/test-parent β€’ https://github.com/eliasnogueira/test-commons β€’ https://github.com/eliasnogueira/restrictions-client β€’ https://github.com/eliasnogueira/restrictions-test β€’ https://github.com/eliasnogueira/simulations-client β€’ https://github.com/eliasnogueira/simulations-test

Slide 46

Slide 46 text

Important note To be able to run the Project locally, after you clone it, you must configure the GitHub Packages in your pom.xml file. You can find the example here: https://docs.github.com/en/packages/working-with-a-github- packages-registry/working-with-the-apache-maven-registry Replace the OWNER by eliasnogueira