Testing Java Microservices with
Consumer-driven contracts
Andrew Morgan
@mogronalol
Microservices testing is hard
Consumer driven contract testing
About Me
• Independent Consultant
specialising in microservices
& continuous delivery
• PluralSight Author
• InfoQ Editor
Andrew Morgan
@mogronalol
Agenda
• Introducing microservices testing
challenges
• Consumer-driven contract testing
overview
• Following through the workflow
with Spring Cloud Contract
• Advanced consumer-driven
contract concepts
Agenda
• Introducing microservices testing
challenges
• Consumer-driven contract testing
overview
• Following through the workflow
with Spring Cloud Contract
• Advanced consumer-driven
contract concepts
What are Microservices?
Rewards
Accounts
Payments
Loans
What are Microservices?
HTTP Rewards
Accounts
HTTP
Payments
Loans
What are Microservices?
HTTP Rewards
Accounts
Messaging
HTTP
Payments
Loans
The root cause of testing challenges
REST API
Payments Booking
End-to-end Testing Microservices
Automated tests Browser or other UI Environment
Disadvantages of End-to-end Testing
Build time
Debuggability
Infrastructure cost
Operations
Flakiness
Distributed monolith
Mocking or Stubbing Dependencies
Automated tests Microservice Mock or Stub of
Dependency
Disadvantages of Mocking or Stubbing
False positives
Staleness
Difficult to maintain
The Weak Feedback Loop
Run individual
microservice Build and deploy
tests to stage End-to-end test Release
False positives Slow and flaky
Agenda
• Introducing microservices testing
challenges
• Consumer-driven contract testing
overview
• Following through the workflow
with Spring Cloud Contract
• Advanced consumer-driven
contract concepts
What is Consumer-driven Contract Testing?
Fills the microservices testing gap
Continuous testing against contracts
Consumers drive the implementation of providers
Independently testable and releasable microservices
Test Architecture Overview
???
Consumer Provider
Key Contract Characteristics
An agreed interaction between microservices
Continuously tested
No specific protocol
Not the same stubbing!
Definitely not API documentation!
What is an Interaction?
Scenario:
Should return no flights between London and Paris
What is an Interaction?
Scenario:
Should return no flights between London and Paris
Required Request:
GET /flights?from=London&to=Paris
What is an Interaction?
Scenario:
Should return no flights between London and Paris
Required Request:
GET /flights?from=London&to=Paris
Given Response:
200 []
The Consumer Side
Automated Consuming Stub of provider
tests Microservice microservice
Generates
The interaction our
test depends on
The Provider Side
Contract verification Providing
tests Microservice
Generates
Pre-defined
contract
The Benefits
Fast and reliable feedback
Less money spent on infrastructure
API delivers exactly what is required
Understanding dependency hell
No stale stubs
Easy to work in parallel
Agenda
• Introducing microservices testing
challenges
• Consumer-driven contract testing
overview
• Following through the workflow
with Spring Cloud Contract
• Advanced consumer-driven
contract concepts
Spring Cloud Contract Overview
JVM-based CDC framework
Spring Boot Integration
Groovy Based Contract Definition Language
Message-driven and HTTP-driven interactions
Credit Card Application Feature
Credit Card Application Feature
JUnit Test Credit card Credit score service
applications service
Credit Card Application Feature
JUnit Test Credit card Credit score service
applications service
Applies for credit
card
Credit Card Application Feature
JUnit Test Credit card Credit score service
applications service
Calculates credit
score
Credit Card Application Feature
JUnit Test Credit card Credit score service
applications service
Accepts or rejects based
on credit score
Following the CDC Workflow
Write a Define Build Make Build Make tests
failing test Contract stubs tests verification pass
pass tests
Following the CDC Workflow
Write a
failing test
A Failing Test
A Failing Test
A Failing Test
Implementing Our Endpoint
JUnit Test
Implementing Our Endpoint
JUnit Test Credit card
applications service
Implementing Our Endpoint
JUnit Test Credit card Credit score service
applications service
Does not exist
Implementing Our Endpoint
JUnit Test Credit card Credit score service
applications service
Fails here
Following the CDC Workflow
Write a Define
failing test Contract
Contract Definition Language
Request made
by our test
Response expected
by our test
Following the CDC Workflow
Write a Define Build
failing test Contract stubs
Stub Generation
Contract Spring Cloud Stub Jar
Contract Plugin
wiremock.org
Following the CDC Workflow
Write a Define Build Make
failing test Contract stubs tests
pass
The Stub Runner
Download given stubs
Boots WireMock
Imports stubs into Wiremock
From a Failing Test
Unit test Credit card Credit score
applications service service
Fails here
…to a Passing Test
Unit test Credit card Spring Cloud
applications service Contract Stub
Passes here
Following the CDC Workflow
Write a Define Build Make Build
failing test Contract stubs tests verification
pass tests
Provider Test Generation
Contract Spring Cloud Verification
Contract Plugin Tests
Following the CDC Workflow
Write a Define Build Make Build Make tests
failing test Contract stubs tests verification pass
pass tests
From Failing…
Contract Verification Credit score
Tests service
To Passing…
Contract Verification Credit score
Tests service
Implement me
“Consumer-driven contracts are like TDD
applied at the API level.”
- Marcin Grzejszczak
Agenda
• Introducing microservices testing
challenges
• Consumer-driven contract testing
overview
• Following through the workflow
with Spring Cloud Contract
• Advanced consumer-driven
contract concepts
Does this only work with exact comparisons?
Subsets
Regex
JSON XPath
XML
Ignore casing
Starts with More
What about messaging?
Message-driven CDC
Consumer Provider
Message-driven CDC
Consumer Broker Provider
Why Messaging?
Message schemas and queues are shared
Asynchronous failures are a debugging nightmare!
Brokers are slow
Where do we store our contracts?
Contract Repository
Contract Repository
Talk Summary
Don’t build and test microservices like a monolith
Consumer-driven contracts promote independence
Leverage frameworks like Spring Cloud Contract and
Pact
Questions?
https://www.pluralsight.com/profile/author/andrew-morgan
@mogronalol