Would Heu-risk it? Part 22: The Contract

Picture of a contract and a feather pen

I feel like I cheated a bit with this tool by using a rhyme that makes it both an asset but also a weapon or weak spot. Judge for yourself:

”Mocks, stubs and fakes are all tools we can use
To ease our complexity and dependencies loose
But check all the contracts on which you depend
Don´t assume it´s working, leave no loose-end

So, what does it mean?

First of all: I _love_ the idea of mocking out all dependencies. Isolation of concern, speed, ease of debugging – all the best things possible!
I see why we want to have small small items with a single/few purposes that can be streamlined, re-used and easily replaced.

But: It does not make the _total_ less complex. It just makes the _parts_ less complex and the possibilities for failures between parts endless.

And: Communication is incredibly hard. Please remember that.

So, back to the card. When we have interfaces between services, systems, applications, apps etc: you have to make sure to test that interface. You have to make sure you agree on every in and out of that interface. And you have to make sure you test the ecosystem with AND without all parts.

What happens if one service decides to change from javascript framework 1 to javascript framework 2? What happens when the external service ABC suddenly is taken down for maintenance? What happens when external system 123 is hacked? Or simply when your sister team handling the internal service A12B adds a potential value to their answer?

Contract testing is an incredibly fun, but also complex, part of testing and it is easy to miss scenarios but just as easy to over-complicate things!

Parts can, and should, be tested with all dependencies removed – making sure we test that our small part(s) can handle both wanted and unwanted, expected and unexpected, responses.
Other parts should, or can only, be tested with a single/some dependencies – making sure the contract we agreed on (please make sure you agree on one!) is upheld and that we handle it. And the most common, and/or most critical, error scenarios.
But some things can only be tested in the complete ecosystem. What happens to _my_ service(a) if a second service(b) that a third service(c) relies on goes down?

Say My service ”Add Customer” calls the ”Check Address”-api to get the current address. ”Check Address” calls a third service, ”Preferred Line of Contact”. If that is down, how will the response back to me look?
If ”Preferred Line of Contact” suddenly adds a channel and ”Check Address” can’t handle that, can my service handle that?

Woman trying to handle two old switchboards
Oh noes…

Story time

At more than one point in time during my career, teams have forgotten to update each other on changes to the set of data they accept/don’t accept, expect/don’t expect.

It can be as small as changing from true/false to 1/0, which a lot of times would be interpreted as the same thing – but not always. If you don’t know the tech stack on the other side very well – don’t expect it to work.

Other times they added/removed a certain value and thought it would work ok but as time passed, small changes grew and contracts stopped being relevant.

And then we have a few times when one side changed the contract completely and forgot to tell the people sending and/or receiving data. Of course, resulting in chaos and mayhem.

Communication is hard!

Quote of the day

”…One option is a lot faster than the other, has no dependencies and gets me fairly near the answers I want but omits lower level detail (windspeed, gradient) of the journey that I would learn by timing the walk myself.
This is exactly what contract testing does. It mocks or interrogates a response to allow you to get some of the information about functions you require”

Elisabeth Fiennes

Reading suggestions

Things I’ve learned about contract testing with Pact– Unremarkable tester
REST Practice – Lisi Hocke
End-to-end vs. contract testing – how to choose – Amy Reichert
Contract tests vs functional tests – PACT Foundation
A comprehensive guide to contract testing APIs in a server oriented architecture – Liran Tal, Medium
Introduction to contract testing – Elisabeth Fiennes

Previous posts in the series

Title and linkCategory
Part 1: IntroductionNone
Part 2: Mischievous MisconceptionsTrap
Part 3: The RiftWeapon
Part 4: The FascadeTool
Part 5: The Temptress’ TrailsTrap
Part 6: AlliesWeapon
Part 7: Don’t turn backTool
Part 8: The GluttonTrap
Part 9: Beyond the borderWeapon
Part 10: Forever and neverTool
Part 11: The ShallowsTrap
Part 12: The TwinsWeapon
Part 13: The ObserverTool
Part 14: AlethephobiaTrap
Part 15: Opus interruptusWeapon
Part 16: The IllusionistTool
Part 17: Fools’ assumptionsTrap
Part 18: The UnexpectedWeapon
Part 19: Constantly ConsistentTool
Part 20: Drowning in the deepTrap
Part 21: The Hive Weapon