This repository shows how Pact, PactFlow and Cypress could work together to provide increased confidence and reliability for web applications that rely on backend API communication.
The end-to-end project is based off the PactFlow CI/CD workshop at https://docs.pactflow.io/docs/workshops/ci-cd/.
It is using a public tenant on PactFlow, which you can access here using the credentials dXfltyFMgNOFZAxr8io9wJ37iUpY42M
/O5AIZWxelWbLvqMd8PkAVycBJh2Psyg1
. The latest version of the Example Consumer/Example Provider pact is published here.
NOTE: this repository took inspiration from the great work over at https://github.com/YOU54F/cypress-pact.
The following is an over simplified view of how this would work in a full end-to-end workflow:
http://localhost:3000
.pacts/pactflow-example-consumer-cypress-pactflow-example-provider.json
if test run was successful.dXfltyFMgNOFZAxr8io9wJ37iUpY42M
/ password: O5AIZWxelWbLvqMd8PkAVycBJh2Psyg1
, example build https://github.com/pactflow/example-consumer-cypress/workflows)can-i-deploy
to see if the Web App is compatible with the Product API and if it is safe to release to production.npm i
to install cypress and related dependenciesmake mocked
(this uses a stubbed backend provided by PactFlow)npm cypress:open:stubbed
npm cypress:run:stubbed
There is also a Makefile
to run via the CLI which is used by CI (GitHub Actions).
Running UI tests can suffer from a number of issues:
In order to combat some of the issues from above, teams may choose to fake out a backend.
The Cypress documentation contains an excellent guide on the tradeoffs of stubbing vs e2e tests:
Real Server (End to End tests issuing real network requests)
Real Server:
Pros | Cons |
---|---|
More likely to work in production | Requires seeding data |
Test coverage around server endpoints | Much slower |
Great for traditional server-side HTML rendering | Harder to test edge cases |
Stubbing:
Pros | Cons |
---|---|
Control of response bodies, status, and headers | No guarantee your stubbed responses match the actual data the server sends |
Can force responses to take longer to simulate network delay | No test coverage on some server endpoints |
No code changes to your server or client code | Not as useful if you’re using traditional server side HTML rendering |
Fast, < 20ms response times | - |
Pact tests are generally authored at a unit test layer, and we (currently) discourage the use of it at the UI layer for a number of reasons. Teams using both tools could reduce the overlapping test areas and corresponding maintenance if the two tools were better integrated.
Currently, Pact tests are written as "white box" style tests, meaning they are generally authored by developers who maintain the code base. The Cypress experience is suited to a wider range of test authors who may benefit from writing and contributing to Pact tests.
Whilst we currently recommend avoiding doing Pact testing through a UI test, sometimes old code bases are a bit harder to pick apart and test at the "right layer", making unit testing much more difficult. So difficult that you just don't do it. You know the kinds of problems I'm talking about. Having a Pact test run "from the outside" has significant advantages for these use cases.
By integrating Pact with Cypress, there is an opportunity to reduce some of the downsides of stubbing in Cypress, namely:
Additionally, we can bring in new test authors to the Pact ecosystem, and reduce duplication for teams already using both tools, thereby saving time to value and reducing maintenance costs.
cypress-pact
plugin that natively maps over the cy.server
and cy.request
interfaces to create a seamless Cypress experienceA separate solution is proposed, that makes use of the more advanced route2
functionality, which is able to proxy all network requests. This would be useful for a broader application when a "provider driven" workflow is implemented in PactFlow, removing the drawbacks of this kind of contract test.