Share
Contract testing with Pact and Quarkus
Every time you change one microservice, the others break. But you had unit tests! What’s going on? Unit tests aren’t enough to give system-level confidence, even with a microservices architecture. What’s the solution? Integration testing is annoyingly expensive, flaky, and fries your laptop. Remocal development environments are complex to manage. Testing in production is important, but the feedback loop is longer, so it’s not a substitute for local inner-loop testing. Enter contract tests. Contract tests combine the lightness of unit tests with the confidence of integration tests, and should be part of your development toolkit. This session will demo how to use the Pact contract testing framework to catch integration issues early. The demos will be run on Quarkus, but Pact runs on all Java frameworks. In fact, Pact has libraries for almost all of the popular programming languages.
Holly Cummins
Transcript
133 slides
-
@holly_cummins “how do I know the whole system works? the
big microservices question -
@holly_cummins “how do I know the whole system works? …
without losing the goodness of microservices?” the big microservices question -
do you have confidence in how individual services are tested?
v6.2.8 v65.7 v5.1.4 v1.0.5 -
@holly_cummins #RedHat “we made our pipeline enforce releasing all our
microservices at the same time.” true story -
@holly_cummins #RedHat “we made our pipeline enforce releasing all our
microservices at the same time.” true story are you dependent on end-to-end testing? -
@holly_cummins “uh, what do you mean you corrected the typo
in your json?” -
@holly_cummins #RedHat our code our mock our code their actual
code tests ✔ why mocks aren’t enough -
@holly_cummins #RedHat our code our mock our code their actual
code tests ✔ reality ✘ why mocks aren’t enough -
@holly_cummins #RedHat our code their code contract test mock why
mocks aren’t enough -
@holly_cummins #RedHat our code their code contract test mock functional
test why mocks aren’t enough -
@holly_cummins #RedHat our code their code contract test mock functional
test our tests ✔ their tests ✔ reality ✔ why mocks aren’t enough -
@holly_cummins #RedHat our code their code contract test mock functional
test why mocks aren’t enough -
@holly_cummins #RedHat our code their code contract test mock functional
test our tests ✔ their tests ✘ reality ✘ why mocks aren’t enough -
@holly_cummins #RedHat our code their code contract test mock functional
test why mocks aren’t enough -
@holly_cummins #RedHat our code their code contract test mock functional
test our tests ✘ their tests ✔ reality ✘ why mocks aren’t enough -
IBM Cloud © 2020 IBM Corporation the test pyramid end-to-end
tests unit tests -
IBM Cloud © 2020 IBM Corporation the test pyramid end-to-end
tests unit tests contract tests -
IBM Cloud © 2020 IBM Corporation how not to test
a fire alarm -
IBM Cloud © 2020 IBM Corporation how not to test
a fire alarm -
@holly_cummins #RedHat if you remember one thing … • don’t
test the mock! • your consumer test should be testing your code, not what’s coming back from the other side • lots of examples get this wrong :( -
@holly_cummins #RedHat cold person knitter sheep farmer semantics vs syntax
(why sharing expectations about behaviour is important) -
@holly_cummins #RedHat cold person knitter sheep farmer “white sweater, please”
semantics vs syntax (why sharing expectations about behaviour is important) -
@holly_cummins #RedHat cold person knitter sheep farmer “white sweater, please”
semantics vs syntax (why sharing expectations about behaviour is important) -
@holly_cummins #RedHat cold person white sweater knitter sheep farmer “white
sweater, please” semantics vs syntax (why sharing expectations about behaviour is important) -
@holly_cummins #RedHat cold person white sweater knitter sheep farmer “white
sweater, please” white wool semantics vs syntax (why sharing expectations about behaviour is important) -
@holly_cummins #RedHat cold person white sweater knitter sheep farmer “white
sweater, please” “black sweater, please” white wool semantics vs syntax (why sharing expectations about behaviour is important) -
@holly_cummins #RedHat cold person white sweater knitter sheep farmer “white
sweater, please” “black sweater, please” white wool semantics vs syntax (why sharing expectations about behaviour is important) -
@holly_cummins #RedHat cold person white sweater knitter sheep farmer “white
sweater, please” “black sweater, please” white wool black sweater semantics vs syntax (why sharing expectations about behaviour is important) -
@holly_cummins #RedHat cold person white sweater knitter sheep farmer “white
sweater, please” “black sweater, please” white wool black sweater black wool semantics vs syntax (why sharing expectations about behaviour is important) -
@holly_cummins #RedHat cold person white sweater knitter sheep farmer “white
sweater, please” “black sweater, please” “pink sweater, please” white wool black sweater black wool semantics vs syntax (why sharing expectations about behaviour is important) -
@holly_cummins #RedHat cold person white sweater knitter sheep farmer “white
sweater, please” “black sweater, please” “pink sweater, please” white wool black sweater black wool semantics vs syntax (why sharing expectations about behaviour is important) -
@holly_cummins #RedHat cold person white sweater knitter sheep farmer “white
sweater, please” “black sweater, please” “pink sweater, please” white wool black sweater black wool pink sweater semantics vs syntax (why sharing expectations about behaviour is important) -
@holly_cummins #RedHat cold person white sweater knitter sheep farmer “white
sweater, please” “black sweater, please” “pink sweater, please” white wool black sweater black wool pink sweater pink wool semantics vs syntax (why sharing expectations about behaviour is important) -
@holly_cummins #RedHat cold person white sweater knitter sheep farmer “white
sweater, please” “black sweater, please” “pink sweater, please” white wool black sweater black wool pink sweater pink wool semantics vs syntax (why sharing expectations about behaviour is important) what?! pink sheep don’t exist -
@holly_cummins #RedHat cold person white sweater knitter sheep farmer “white
sweater, please” “black sweater, please” “pink sweater, please” white wool black sweater black wool pink sweater pink wool semantics vs syntax (why sharing expectations about behaviour is important) should the knitter ask for white wool and bring in a dyeing service? what?! pink sheep don’t exist -
@holly_cummins #RedHat cold person white sweater knitter sheep farmer “white
sweater, please” “black sweater, please” “pink sweater, please” white wool black sweater black wool pink sweater pink wool semantics vs syntax (why sharing expectations about behaviour is important) should the knitter ask for white wool and bring in a dyeing service? should the farmer dye the wool? what?! pink sheep don’t exist -
@holly_cummins #RedHat Photo of sheep at the Latitude Festival by
Tim Parkinson, https://www.flickr.com/photos/timparkinson -
@holly_cummins #RedHat Photo of sheep at the Latitude Festival by
Tim Parkinson, https://www.flickr.com/photos/timparkinson “pink sheep don’t exist” -
@holly_cummins #RedHat how annoying, the provider is returning 204. the
contract expects 404, so my test is broken. quarkus will return 204 by default. 204 vs 404 - it’s more about the theory behind REST...if a caller asks for a resource the server doesn't have, it should be a 404 - same way if a user types in an invalid URL into the browser it’s too late at night to care about REST theory. I’m just going to update the expectations in the test to match reality. what?! why is my other contract test broken now? oh … because what I’m changing is a mock…. Based on a true story…. -
@holly_cummins #RedHat contract consumer provider contract tests verify Pact (functional
tests) contract testing landscape -
@holly_cummins #RedHat contract consumer tests provider mock Pact contract tests
verify Pact (functional tests) contract testing landscape -
@holly_cummins #RedHat contract consumer tests provider mock Pact declare (Pact)
contract tests verify Pact (functional tests) contract testing landscape Pact file -
@holly_cummins #RedHat contract consumer tests provider mock Pact declare (Pact)
contract tests verify Pact (functional tests) OpenAPI contract testing landscape Pact file -
@holly_cummins #RedHat contract consumer tests provider mock Pact declare (Pact)
contract tests verify Pact (functional tests) OpenAPI OpenAPI + Schemathesis (syntax only, weaker connection to consumer expectations) contract testing landscape Pact file -
@holly_cummins #RedHat contract consumer tests provider mock Pact declare (Pact)
contract tests verify Pact (functional tests) OpenAPI OpenAPI + Schemathesis (syntax only, weaker connection to consumer expectations) contract testing landscape Pact file Microcks -
@holly_cummins #RedHat contract consumer tests provider mock Pact Prism (OpenAPI)
declare (Pact) contract tests verify Pact (functional tests) OpenAPI OpenAPI + Schemathesis (syntax only, weaker connection to consumer expectations) contract testing landscape Pact file Microcks -
@holly_cummins #RedHat contract consumer tests provider mock Pact Prism (OpenAPI)
Microcks (OpenAPI) declare (Pact) contract tests verify Pact (functional tests) OpenAPI OpenAPI + Schemathesis (syntax only, weaker connection to consumer expectations) contract testing landscape Pact file Microcks -
@holly_cummins #RedHat contract consumer tests provider mock Pact Prism (OpenAPI)
Microcks (OpenAPI) declare (Pact) contract tests verify Pact (functional tests) OpenAPI OpenAPI + Schemathesis (syntax only, weaker connection to consumer expectations) contract testing landscape Pact file mock server OpenAPI + Prism Microcks Microcks -
@holly_cummins #RedHat contract consumer tests provider mock Pact Prism (OpenAPI)
Microcks (OpenAPI) declare (Pact) contract tests verify Pact (functional tests) OpenAPI OpenAPI + Schemathesis (syntax only, weaker connection to consumer expectations) contract testing landscape Pact file generate (OpenAPI snapshot of current implementation) mock server OpenAPI + Prism Microcks Microcks -
@holly_cummins #RedHat contract consumer tests provider mock Pact Prism (OpenAPI)
Microcks (OpenAPI) declare (Pact) generate skeleton from OpenAPI contract tests verify Pact (functional tests) OpenAPI OpenAPI + Schemathesis (syntax only, weaker connection to consumer expectations) contract testing landscape Pact file generate (OpenAPI snapshot of current implementation) mock server OpenAPI + Prism Microcks Microcks -
@holly_cummins #RedHat contract consumer tests provider mock Pact Prism (OpenAPI)
Microcks (OpenAPI) declare (Pact) generate skeleton from OpenAPI contract tests verify Pact (functional tests) OpenAPI OpenAPI + Schemathesis (syntax only, weaker connection to consumer expectations) contract testing landscape Pact file dashboard generate (OpenAPI snapshot of current implementation) mock server OpenAPI + Prism Microcks Microcks -
@holly_cummins #RedHat contract consumer tests provider mock Pact Prism (OpenAPI)
Microcks (OpenAPI) declare (Pact) generate skeleton from OpenAPI contract tests verify Pact (functional tests) OpenAPI OpenAPI + Schemathesis (syntax only, weaker connection to consumer expectations) contract testing landscape Pact file dashboard Pact broker generate (OpenAPI snapshot of current implementation) mock server OpenAPI + Prism Microcks Microcks -
@holly_cummins #RedHat contract consumer tests provider mock Pact Prism (OpenAPI)
Microcks (OpenAPI) declare (Pact) generate skeleton from OpenAPI contract tests verify Pact (functional tests) OpenAPI OpenAPI + Schemathesis (syntax only, weaker connection to consumer expectations) contract testing landscape Pact file dashboard Pact broker Microcks generate (OpenAPI snapshot of current implementation) mock server OpenAPI + Prism Microcks Microcks -
@holly_cummins #RedHat contract consumer tests provider mock Pact Prism (OpenAPI)
Microcks (OpenAPI) declare (Pact) generate skeleton from OpenAPI contract tests verify Pact (functional tests) OpenAPI OpenAPI + Schemathesis (syntax only, weaker connection to consumer expectations) contract testing landscape Pact file dashboard Pact broker Microcks generate (OpenAPI snapshot of current implementation) mock server OpenAPI + Prism Microcks Microcks other protocol specs -
@holly_cummins #RedHat contract provider provider-driven contract testing generate (OpenAPI snapshot
of current implementation) -
@holly_cummins #RedHat contract provider contract tests verify provider-driven contract testing
generate (OpenAPI snapshot of current implementation) -
@holly_cummins #RedHat contract consumer provider contract tests verify provider-driven contract
testing generate (OpenAPI snapshot of current implementation) -
@holly_cummins #RedHat contract consumer tests provider mock contract tests verify
provider-driven contract testing generate (OpenAPI snapshot of current implementation) -
@holly_cummins #RedHat contract consumer tests provider mock contract tests verify
OpenAPI provider-driven contract testing generate (OpenAPI snapshot of current implementation) -
@holly_cummins #RedHat contract consumer tests provider mock contract tests verify
OpenAPI provider-driven contract testing generate (OpenAPI snapshot of current implementation) other protocol specs -
@holly_cummins #RedHat contract consumer tests provider mock contract tests verify
OpenAPI provider-driven contract testing generate (OpenAPI snapshot of current implementation) other protocol specs + familiar contract format -
@holly_cummins #RedHat contract consumer tests provider mock contract tests verify
OpenAPI provider-driven contract testing generate (OpenAPI snapshot of current implementation) other protocol specs + familiar contract format + provider does not need comms with consumers -
@holly_cummins #RedHat contract consumer tests provider mock contract tests verify
OpenAPI provider-driven contract testing generate (OpenAPI snapshot of current implementation) other protocol specs + familiar contract format + provider does not need comms with consumers - provider does not get insight into how API is being used -
@holly_cummins #RedHat contract consumer tests provider mock contract tests verify
OpenAPI provider-driven contract testing generate (OpenAPI snapshot of current implementation) other protocol specs + familiar contract format + provider does not need comms with consumers - provider does not get insight into how API is being used - spec-based tests lack depth -
@holly_cummins #RedHat contract consumer tests mock declare (Pact) Pact file
consumer-driven contract testing -
@holly_cummins #RedHat contract consumer tests provider mock declare (Pact) Pact
file consumer-driven contract testing -
@holly_cummins #RedHat contract consumer tests provider mock declare (Pact) contract
tests verify Pact file consumer-driven contract testing -
@holly_cummins #RedHat contract consumer tests provider mock declare (Pact) contract
tests verify OpenAPI Pact file consumer-driven contract testing -
@holly_cummins #RedHat contract consumer tests provider mock declare (Pact) contract
tests verify OpenAPI Pact file other protocol specs consumer-driven contract testing -
@holly_cummins #RedHat contract consumer tests provider mock declare (Pact) contract
tests verify OpenAPI Pact file other protocol specs consumer-driven contract testing + rich semantic testing -
@holly_cummins #RedHat contract consumer tests provider mock declare (Pact) contract
tests verify OpenAPI Pact file other protocol specs consumer-driven contract testing + rich semantic testing + provider can ‘develop to the test’ instead of developing speculatively -
@holly_cummins #RedHat contract consumer tests provider mock declare (Pact) contract
tests verify OpenAPI Pact file other protocol specs consumer-driven contract testing + rich semantic testing + provider can ‘develop to the test’ instead of developing speculatively - existing spec assets cannot be re-purposed -
@holly_cummins #RedHat contract consumer tests provider mock declare (Pact) contract
tests verify OpenAPI Pact file other protocol specs consumer-driven contract testing + rich semantic testing + provider can ‘develop to the test’ instead of developing speculatively - existing spec assets cannot be re-purposed - provider needs to identify consumers -
@holly_cummins #RedHat contract consumer tests provider mock declare (Pact) contract
tests verify OpenAPI Pact file other protocol specs consumer-driven contract testing + rich semantic testing + provider can ‘develop to the test’ instead of developing speculatively - existing spec assets cannot be re-purposed - provider needs to identify consumers - consumers can break provider CI -
@holly_cummins #RedHat some contract testing options • Pact • Microcks
• Spring Cloud Contract -
@holly_cummins #RedHat some contract testing options • Pact • Microcks
• Spring Cloud Contract • OpenAPI + schema validation + mock generation • Prism • Schemathesis -
Want to know/learn/watch more about Quarkus? • Battle of the
frameworks : Quarkus vs SpringBoot (11:10-11:50, MC2) • Stream processing app. with Kafka and Quarkus (12:20-13:00, MC2) • Quarkus on AWS Lambda (14:10-14:25, MC3) • Why and when to write a Quarkus extension (14:35-14:50, MC3) • Quarkus Community BOF (15:05-16:05, MC3) ⇨ OpenId Connect and JWT Security in Quarkus (17:30-18:10, MC2) -
@holly_cummins #RedHat maturity model for quarkus extensions 1. actually works
(a) works in JVM mode -
@holly_cummins #RedHat maturity model for quarkus extensions 1. actually works
(a) works in JVM mode (b)works in dev mode -
@holly_cummins #RedHat maturity model for quarkus extensions 1. actually works
(a) works in JVM mode (b)works in dev mode (c) works in native -
@holly_cummins #RedHat maturity model for quarkus extensions 1. actually works
(a) works in JVM mode (b)works in dev mode (c) works in native 2. developer joy -
@holly_cummins #RedHat maturity model for quarkus extensions 1. actually works
(a) works in JVM mode (b)works in dev mode (c) works in native 2. developer joy (a) use build-time application knowledge to remove boilerplate -
@holly_cummins #RedHat maturity model for quarkus extensions 1. actually works
(a) works in JVM mode (b)works in dev mode (c) works in native 2. developer joy (a) use build-time application knowledge to remove boilerplate 3. developer service (if there is an external service dependency) -
@holly_cummins #RedHat maturity model for quarkus extensions 1. actually works
(a) works in JVM mode (b)works in dev mode (c) works in native 2. developer joy (a) use build-time application knowledge to remove boilerplate 3. developer service (if there is an external service dependency) 4. dev UI -
@holly_cummins #RedHat maturity model for quarkus extensions 1. actually works
(a) works in JVM mode (b)works in dev mode (c) works in native 2. developer joy (a) use build-time application knowledge to remove boilerplate 3. developer service (if there is an external service dependency) 4. dev UI 5. quickstart code template -
@holly_cummins #RedHat maturity model for quarkus extensions 1. actually works
(a) works in JVM mode (b)works in dev mode (c) works in native 2. developer joy (a) use build-time application knowledge to remove boilerplate 3. developer service (if there is an external service dependency) 4. dev UI 5. quickstart code template quarkus-pact