You are on page 1of 75

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

You might also like