Does Pact allow setting provider state from the consumer code base while writing pact fragments

182 views
Skip to first unread message

Indra Nara

unread,
May 29, 2016, 8:46:42 AM5/29/16
to Pact
Does Pact allow setting provider state from the consumer code base while writing pact fragments ? If yes, is there an example you can point me to ?

Indra Nara

unread,
May 29, 2016, 12:27:20 PM5/29/16
to Pact
While I understand that Pact does allow setting states from the provider code base, it is ideal to be able to stage the data that you need from the consumer code base itself. Lets say I need to test the CRUD operations on a resource and if I can setup the resource before doing a read/update, everything is still no the consumer code base and the maintenance is easier. 

Dave Smith

unread,
May 29, 2016, 12:44:46 PM5/29/16
to Pact
The point of this form of testing is that the consumer and the provider can be tested in isolation - to decouple the testing of each service so that you don't need your whole environment running just to test one component. In other words, you use the pact tooling to write the contract files from the consumer code base and test against a stub / mock. When you're happy you send the pact files off to the provider so that he can test his code later as part of a different testing process. Because your consumer is working against a stub, there is no need to set up a database since the stub will always give the same answers. When the provider verifies the contract he will need to inject values into his DB (for example) in order to get the right responses to the requests, which is why provider states are only used during verification.

Does that help?

Indra Nara

unread,
May 29, 2016, 12:50:09 PM5/29/16
to Pact
Thanks for the quick response. I understand how pact decouples consumer from provider and that is great!

What I don't like is touching two different code bases to manage the pact tests. If I can manage both the state and also the actual tests from the consumer end, that would be great. What I am trying to see is that the mock service in this case differentiate between requests that are setting the state vs the actual requests and run the requests that set a state first before the actual requests. The advantage being everything in one place and the provider just has some boilerplate to pull the pact files and run them.

Dave Smith

unread,
May 29, 2016, 4:27:14 PM5/29/16
to Pact
It's an interesting point and I think I understand (please correct me if I'm wrong): The consumer sets up the tests and defines, for instance, that a record with ID 1234 must exist with the provider for the test to pass. However, it is the provider (codebase) that must implement the requirement to have record 1234 in place before the verification tests can be run. This is inconvenient from a maintenance perspective.

I can see how that could seem reasonable when you personally own both code bases and understand what technology drives each. The problem as I see it is that one of Pact's main use cases is cross team decoupling. For example I implement services in Scala and I need to call a provider who is in fact a third party vendor, I have no idea what language their services are written in and I certainly don't know what their choice of database technology is. All I know is that they have an HTTP Rest interface and they're sending me XML. In that scenario I'm not sure how I could ever sensibly implement the provider state logic.

In the end, both sides must communicate and do some work to implement the contract and check that it holds. The only thing Pact really forces is which side owns and is responsible for the maintenance of the contract.

However at this point I think I'll have to differ to someone who knows more about the specific tools you're using in case I've missed something important. Can I ask which language / toolset you're using?

Dave

Indra Nara

unread,
May 29, 2016, 4:59:20 PM5/29/16
to Pact
We are using Dropwizard for a few services and Springboot for a few others. Yes, your scenario of a provider which is developed by a third party is a perfect example for this kind of a scenario. 

Also, I am trying to implement a scenario where for me to 'update' a resource, I would like to do a get first and then use that resource as a body (with a few modifications) to send an update request. This is what we ask our customers to do and how can we test the same exact flow ?

Beth

unread,
May 29, 2016, 5:53:56 PM5/29/16
to Indra Nara, Pact
From the Pact wiki: Each interaction in a pact should be verified in isolation, with no context maintained from the previous interactions. Tests that depend on the outcome of previous tests are brittle and land you back in integration test hell, which is the nasty place you're trying to escape by using pacts.

Pact does not have any awareness of data flows. This is both a strength and a weakness. It's a weakness because in real life, request/response pairs often occur in common sequences. However, it is a strength because when tests depend on data from previous test, they become brittle.

I'd recommend using the type based matching on the provider side so that you don't have to specify exactly what the data is in a certain resource, you just specify the types. This will make the tests less brittle, and mean that the provider team doesn't have to make every value exactly as you wrote in your test. Yes, you have to specify a concrete URL at some stage (/things/1234), because you can't replay a request with a regular expression in it.

Here is the wiki page on regular expression and type based matching: https://github.com/realestate-com-au/pact/wiki/Regular-expressions-and-type-matching-with-Pact





--
You received this message because you are subscribed to the Google Groups "Pact" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pact-support...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Indra Nara

unread,
May 29, 2016, 6:44:02 PM5/29/16
to Pact, naren...@gmail.com
Here is where I am struggling with this. It looks like pact defines a test as an interaction. So, not even a pactFragment is considered a test and that the order of requests within a fragment is also not preserved. 

If I were to test a simple CRUD operation on a resource, I will have to stage data for four independent resources and then perform one operation each on every one of these resources. I feel that we solve the integration hell problem and get into a maintenance nightmare. Also, how can I ensure that I can GET a resource that was previously created via the rest interface ? There is no way with Pact as far as I understand. Please correct me if I am wrong. Thanks a bunch for the timely responses.

Beth

unread,
May 29, 2016, 7:24:42 PM5/29/16
to Indra Nara, Pact
Hi Indra,

That is a functional test, not a contract test. That sort of test should be done by the provider's team. As someone working on the consumer, all you should need to care about is the format of the requests and responses.


Indra Nara

unread,
May 29, 2016, 7:27:58 PM5/29/16
to Pact, naren...@gmail.com
Okay, but how does it become brittle by following the order in a pactFragment ? I also think setting unique data per interaction is a maintenance nightmare. What do you guys think ? Or, is there a better way ?

Beth

unread,
May 29, 2016, 9:11:58 PM5/29/16
to Indra Nara, Pact
Having tests that rely on the success of previous tests can make tests brittle. 
You don't need to set unique data per interaction. You can reuse the same one in every test if you like, but you don't need to. And by using the flexible matching (Pact "terms" and "something likes") for the response, you don't have to care what values each field has - just what data type it is. This massively reduces the amount of maintenance.
Reply all
Reply to author
Forward
0 new messages