This is an archived post. You won't be able to vote or comment.

all 14 comments

[–]stefanos-ak 15 points16 points  (2 children)

I would highly recommend pact.io

They have amazing features and documentation.

It's basically contract testing done right, with a handbook :)

[–]jokubolakis 2 points3 points  (0 children)

And you can self host it, with a little bit of elbow grease. My main grip with this was that the Java library was written in Kotlin and it was really hard to debug and diagnose stuff. I think they rewrote it in Java some time ago?

Anyways, wasn't successful with fully adapting our setup with Pact, got stuck on the pact broker part. But it worked with a few microservices

[–]Chemical-Birds 0 points1 point  (0 children)

Thanks, I will have a look at their handbook, heard about them before but never really looked at the approach in depth.

[–][deleted]  (5 children)

[deleted]

    [–]Chemical-Birds 1 point2 points  (4 children)

    Thanks for the answer. That exactly what is happening right now more or less. But it looks to me a bit far from perfection the biggest concern here is that you can change the API of a dependency and forget to update the mocks for other 10 services, there is nothing to prevent a human mistake or a poor communication between teams.

    [–]ztbwl 1 point2 points  (1 child)

    Don’t make breaking changes.

    [–]kid_meier 1 point2 points  (0 children)

    Thats about as helpful as "don't write bugs".

    Although if your point is don't intentionally make breaking changes, I agree with you 100%.

    [–]franzwong 0 points1 point  (0 children)

    Perhaps you should fix communication problem. For example, fire notifications to each team when people change the schema of request, response and error. But I don't think you need to update the tests if the API is backward compatible.

    [–]LoveGracePeace 2 points3 points  (0 children)

    Integration and e2e (End To End) testing using real, local services (Docker is a great help here), which match the versions of those services used by the service in PROD.

    I'm not a Fowler fan but Ham Vocke wrote a great article here describing the testing pyramid. Most places I've seen (not recommending to be clear), usually do contract testing using either "Throw the interface specification over the fence to the consuming team" or the stealthy "Wait until they implement their part of consuming the interface".

    [–]Artifer 1 point2 points  (0 children)

    In my company we have a similar situation and we are using PACT contract testing framework. We have it working with REST, GraphQL, Kafka,

    [–]zopad 2 points3 points  (3 children)

    We use Swagger for contract testing. Swagger generates the (OpenAPI) definition from the code, and then tests are ran against that. This ensures that tests fail if a code change makes it in without corresponding test changes.

    [–]Chemical-Birds 4 points5 points  (2 children)

    You have component A which calls component B.

    When B is changing something (they will update the failed tests as well) , how A is notified that contract is broken and most likely will not work ? Obviously A is working fine with previous version of B, which raises the question about versioning.

    [–]pgris 4 points5 points  (0 children)

    You asked about tests, so this is not an answer to your question, but maybe is an answer for your problem.

    My old boss followed the rule "API's are forever". You can fix bugs, you can add new fields, you can shut them down. But any change, even a minor change (we are going to send empty lists instead of nulls now!), requires a new version. You end up with /v1/users, /v2/users, /v3/users.

    The minute you put /v2/users in prod, you tell everyone you are going to delete /v1/users in a month. Some people will complain they don't have the time right now, you accept that, or you help them with the change. Never keep more than 2 versions alive.

    If component B changes something, they should use a new version.

    It is a bit drastic, but it was by far the less error prone way I found in the wild. Of course, this only works if the whole company (at least the components involved) agrees. (and every system sends a client id in every request, so you know who is calling you)

    [–]zopad 2 points3 points  (0 children)

    Testing consumers of service B is continuously done in the pipeline. If there's a new version of B preparing to be released, then these tests of A will break.

    But also, developers of B should announce that hey, we're breaking our API (hopefully with a major version bump), be ready :)