@mogronalol Simulating APIs for Effective Testing: (Micro)Service Virtualisation 1 Andrew Morgan @mogronalol OpenCredo & Spectolabs
@mogronalol
Simulating APIs for Effective Testing: (Micro)Service Virtualisation
1
Andrew Morgan @mogronalol
OpenCredo & Spectolabs
@mogronalol 2
About Me
• Consultant at OpenCredo • Background mainly with
Java and now Go • Spectolabs
Andrew Morgan @mogronalol
@mogronalol 3
Agenda
• The problems with operating and testing distributed systems and microservices
@mogronalol 3
Agenda
• The problems with operating and testing distributed systems and microservices
• Overview of Service Virtualisation / Api Simulation
@mogronalol 3
Agenda
• The problems with operating and testing distributed systems and microservices
• Overview of Service Virtualisation / Api Simulation• Improving our Tests
@mogronalol 3
Agenda
• The problems with operating and testing distributed systems and microservices
• Overview of Service Virtualisation / Api Simulation• Improving our Tests• Data Synchronisation
@mogronalol 3
Agenda
• The problems with operating and testing distributed systems and microservices
• Overview of Service Virtualisation / Api Simulation• Improving our Tests• Data Synchronisation• Summary
@mogronalol 4
Agenda
• The problems with operating and testing distributed systems and microservices
• Overview of Service Virtualisation / Api Simulation • Improving our Tests • Data Synchronisation • Summary
@mogronalol 9
Airline Booking Application
• Microservice architecture• Integration with third party services
@mogronalol 9
Airline Booking Application
• Microservice architecture• Integration with third party services• Integration with legacy internal services
@mogronalol 9
Airline Booking Application
• Microservice architecture• Integration with third party services• Integration with legacy internal services• Heavy resource consumption
@mogronalol 9
Airline Booking Application
• Microservice architecture• Integration with third party services• Integration with legacy internal services• Heavy resource consumption• A standard CI/CD pipeline
@mogronalol 16
Non Deterministic
assertThat(booking.getDate()) .isEqualTo(LocalDate.of(2013,1,8));
Consumer
Booking Service {
“date” : “2013-01-08”, … }
@mogronalol 16
Non Deterministic
assertThat(booking.getDate()) .isEqualTo(LocalDate.of(2013,1,8));
Consumer
Booking Service {
“date” : “2013-01-08”, … }
@mogronalol 16
Non Deterministic
assertThat(booking.getDate()) .isEqualTo(LocalDate.of(2013,1,8));
Consumer
Booking Service {
“date” : “2016-02-07”, … }
@mogronalol 17
Fault Injection
Consumer
Producer
Consumer
Producer
4xx, 5xx, timeouts
Operationally challenging to trigger
faults
@mogronalol 18
Agenda
• The problems with operating and testing distributed systems and microservices
• Overview of Service Virtualisation / Api Simulation • Improving our Tests • Data Synchronisation • Summary
@mogronalol 19
Service Virtualisation
• Emulation of real service• Non-intrusive• Lightweight - or should be
@mogronalol 22
Creating Data
https://github.com/tomakehurst/wiremock
@mogronalol 25
Not Mocking
Service Under Test
Virtual Service
Mocks bleed into the architectural boundary of your
application
@mogronalol 27
Agenda
• The problems with operating and testing distributed systems and microservices
• Overview of Service Virtualisation / Api Simulation • Improving our Tests • Data Synchronisation • Summary
@mogronalol 29
JUnit Example
@Testpublic void shouldBeAbleToRetrieveABooking() throws URISyntaxException { // Given final int bookingId = 1; // When final Booking booking = bookingServiceGateway.getBooking(bookingId); // Then assertThat(booking.getCustomer()).isEqualTo(“Andrew Morgan”); assertThat(booking.getDate()).isEqualTo(LocalDate.of(2016,3,1));}
@mogronalol 29
JUnit Example
@Rule public HoverflyRule hoverflyRule = HoverflyRule.inCaptureMode(“src/test/resources/external.json").build();
@Testpublic void shouldBeAbleToRetrieveABooking() throws URISyntaxException { // Given final int bookingId = 1; // When final Booking booking = bookingServiceGateway.getBooking(bookingId); // Then assertThat(booking.getCustomer()).isEqualTo(“Andrew Morgan”); assertThat(booking.getDate()).isEqualTo(LocalDate.of(2016,3,1));}
@mogronalol 30
JUnit Example{ "data": [ { "request": { "path": "/api/bookings/1", "method": "GET", "destination": "www.my-test.com", "query": null, "body": "" }, "response": { "status": 200, "body": “{\”customer\”:\”Andrew Morgan\", \”date\”: \”2016-03-01\”}}}”, "headers": { "Content-Type": [ "application/json" ] } } } ]}
@mogronalol 31
JUnit Example
@Testpublic void shouldBeAbleToRetrieveABooking() throws URISyntaxException { // Given final int bookingId = 1; // When final Booking booking = bookingServiceGateway.getBooking(bookingId); // Then assertThat(booking.getCustomer()).isEqualTo(“Andrew Morgan”); assertThat(booking.getDate()).isEqualTo(LocalDate.of(2016,3,1));}
@Rule public HoverflyRule hoverflyRule = HoverflyRule.buildFromClassPathResource(“external.json").build();
@mogronalol 33
Deployment and Infrastructure
Consumer External Producer
Internal Producer
Internal Producer
Internal Producer
@mogronalol 33
Deployment and Infrastructure
Consumer
Virtual Service
Virtual Service
Virtual Service
Virtual Service
@mogronalol 34
CLI Example
$ hoverctl start —proxy-port 8080$ hoverctl import accounts-service-simulation.json
@mogronalol 34
CLI Example
$ hoverctl start —proxy-port 8080$ hoverctl import accounts-service-simulation.json
$ hoverctl start —proxy-port 8081
@mogronalol 34
CLI Example
$ hoverctl start —proxy-port 8080$ hoverctl import accounts-service-simulation.json
$ hoverctl start —proxy-port 8081$ hoverctl import payments-service-simulation.json
@mogronalol 34
CLI Example
$ hoverctl start —proxy-port 8080$ hoverctl import accounts-service-simulation.json
$ hoverctl start —proxy-port 8081$ hoverctl import payments-service-simulation.json
$ curl http://www.account-service.com/api/v1/accounts/1 —proxy http://localhost:8080
[{"name":"foo"}]
@mogronalol 34
CLI Example
$ hoverctl start —proxy-port 8080$ hoverctl import accounts-service-simulation.json
$ hoverctl start —proxy-port 8081$ hoverctl import payments-service-simulation.json
$ curl http://www.account-service.com/api/v1/accounts/1 —proxy http://localhost:8080
[{"name":"foo"}]
$ curl http://www.payment-service.com/api/v1/payments/1 -proxy http://localhost:8081
[{“amount":"£23.27"}]
@mogronalol 41
Agenda
• The problems with operating and testing distributed systems and microservices
• Overview of Service Virtualisation / Api Simulation • Improving our Tests • Data Synchronisation • Summary
@mogronalol 44
Integration Contract Testing
http://martinfowler.com/bliki/IntegrationContractTest.html
@mogronalol 44
Integration Contract Testing
Scheduled Build
http://martinfowler.com/bliki/IntegrationContractTest.html
@mogronalol 44
Integration Contract Testing
Scheduled Build
Reproduce Simulations
http://martinfowler.com/bliki/IntegrationContractTest.html
@mogronalol 44
Integration Contract Testing
Scheduled Build
Reproduce Simulations Diff
http://martinfowler.com/bliki/IntegrationContractTest.html
@mogronalol 44
Integration Contract Testing
Scheduled Build
Reproduce Simulations Diff
Integration Testing or
Contract Diff
http://martinfowler.com/bliki/IntegrationContractTest.html
@mogronalol 44
Integration Contract Testing
Scheduled Build
Reproduce Simulations Diff
No diff?
Integration Testing or
Contract Diff
http://martinfowler.com/bliki/IntegrationContractTest.html
@mogronalol 44
Integration Contract Testing
Scheduled Build
Reproduce Simulations Diff
No diff?
Diff?
Integration Testing or
Contract Diff
http://martinfowler.com/bliki/IntegrationContractTest.html
@mogronalol 45
Ownership
Own Consumer Own Producer Strategy
Integration Contract Testing
Virtual Service as First Class Citizen
@mogronalol 46
Virtual Service as First Class Citizen
Run and Capture
Service Tests
Transform to simulation
@mogronalol 46
Virtual Service as First Class Citizen
Run and Capture
Service Tests
Transform to simulation
Publish Virtual Service
@mogronalol 46
Virtual Service as First Class Citizen
Run and Capture
Service Tests
Parse Contract
Transform to simulation
Publish Virtual Service
@mogronalol 46
Virtual Service as First Class Citizen
Run and Capture
Service Tests
Parse Contract
Transform to simulation
Parse Documentati
on
Publish Virtual Service
@mogronalol 47
Ownership
Own Consumer Own Producer Strategy
Integration Contract Testing
Virtual Service as First Class Citizen
@mogronalol 47
Ownership
Own Consumer Own Producer Strategy
Integration Contract Testing
Consumer Driven Contract Testing
Virtual Service as First Class Citizen
@mogronalol 48
Consumer Driven Contract Testing
http://www.martinfowler.com/articles/consumerDrivenContracts.html
@mogronalol 48
Consumer Driven Contract Testing
Consumer Defines Contract
http://www.martinfowler.com/articles/consumerDrivenContracts.html
@mogronalol 48
Consumer Driven Contract Testing
Consumer Defines Contract
http://www.martinfowler.com/articles/consumerDrivenContracts.html
Generate Producer
Stubs
@mogronalol 48
Consumer Driven Contract Testing
Consumer Defines Contract
http://www.martinfowler.com/articles/consumerDrivenContracts.html
Generate Producer
Stubs
Implement Consumer
@mogronalol 48
Consumer Driven Contract Testing
Consumer Defines Contract
http://www.martinfowler.com/articles/consumerDrivenContracts.html
Generate Producer
Stubs
Implement Consumer
@mogronalol 48
Consumer Driven Contract Testing
Consumer Defines Contract
http://www.martinfowler.com/articles/consumerDrivenContracts.html
Generate Producer
Stubs
Generate Producer Contract
Tests
Implement Consumer
@mogronalol 48
Consumer Driven Contract Testing
Consumer Defines Contract
Implement Producer
http://www.martinfowler.com/articles/consumerDrivenContracts.html
Generate Producer
Stubs
Generate Producer Contract
Tests
Implement Consumer
@mogronalol 48
Consumer Driven Contract Testing
Consumer Defines Contract
Implement Producer
http://www.martinfowler.com/articles/consumerDrivenContracts.html
Generate Producer
Stubs
Generate Producer Contract
Tests
Implement Consumer
Run Consumer Contract
Tests
@mogronalol 48
Consumer Driven Contract Testing
Consumer Defines Contract
Implement Producer
http://www.martinfowler.com/articles/consumerDrivenContracts.html
Generate Producer
Stubs
Generate Producer Contract
Tests
Implement Consumer
Run Consumer Contract
Tests
@mogronalol 49
Consumer Driven Contract Testing
http://www.martinfowler.com/articles/consumerDrivenContracts.html
@mogronalol 49
Consumer Driven Contract Testing
Change producer
http://www.martinfowler.com/articles/consumerDrivenContracts.html
@mogronalol 49
Consumer Driven Contract Testing
Change producer
http://www.martinfowler.com/articles/consumerDrivenContracts.html
Run Consumer Contract
Tests
@mogronalol 49
Consumer Driven Contract Testing
Change producer
http://www.martinfowler.com/articles/consumerDrivenContracts.html
Run Consumer Contract
Tests
@mogronalol 51
Testing Pyramid
End to end
Integration / Service Testing
Unit Testing
Consumer Driven Contract Testing
@mogronalol 51
Testing Pyramid
End to end
Integration / Service Testing
Unit Testing
Consumer Driven Contract Testing
@mogronalol 52
Summary
• Cost reduction from simulated services• Easy deployment of simulations• Less dependant on end to end testing
@mogronalol 52
Summary
• Cost reduction from simulated services• Easy deployment of simulations• Less dependant on end to end testing• Better feedback cycle