/pact-demo-1

Pact contract testing example

Primary LanguageJava

Pact example project

This is an example project demonstrating how to test-drive a new endpoint on a Spring Boot provider, starting from the consumer side.

How to use this repository

Like a real project, commits in this repository incrementally add tests and implementation. Use a tool of your choice to view the diffs between each commit.

Some of the commits have failing tests to highlight intermediate steps and to show how failing tests inform us about the next steps.

About the provider test

The provider test is implemented as an integration test, running the whole application in the pact Spring profile. In a real app, this profile should stub out external dependencies to prevent side effects and to make the test predictable and robust.

Running contract tests as integration tests is definitely controversial. In my experience, I have seen more up- than downsides to this approach: it's usually not more complicated to set up preconditions in the database vs. setting up mocks. The tests are also not brittle if the application is designed to be testable and if its output is reproducible (e.g. list item order needs to be stable). On the plus side, this approach allows having an integration-like test for every response case of each endpoint. And who would say no to free integration tests?

How to demo this repository

Prep work:

  1. Run the Pact Broker locally through docker compose up -d in the Broker repo and delete any existing pacts.
  2. Remove any pacts inside the pacts folder in the consumer.

Presentation:

  1. Go through some slides explaining the pains of working without consumer-driver contract tests.
  2. Run mvn spring-boot:run for both projects and watch the console log of the consumer.
  3. In the provider, change the name property in AnimalResponse to type, and watch the consumer log.
  4. Go through some more slides explaining consumer-driven contract testing conceptually.
  5. Explore the tests in the consumer.
  6. Run the listAnimals_returnsAnimals test and verify the creation of the new pact file.
  7. Explore the tests in the provider.
  8. Run the PactIntegrationTest and inspect the error returned from it.
  9. Change type back to name and rerun the test.
  10. Look at the @PactFolder annotation, and notice the dependency on the consumer codebase.
  11. Go to the Pact Broker UI and observe there are no contracts.
  12. Publish to the Pact Broker by running the pact:publish consumer maven goal.
  13. In the Broker, take a look at the newly published contract.
  14. Run the pact:can-i-deploy consumer maven goal to verify if we can deploy the consumer.
  15. In the Broker, note that the new contract has not been verified yet.
  16. Change the @PactFolder("../pact-consumer/pacts") annotation to @PactBroker(host = "localhost", port = "80")
  17. Run the Test and publish results provider maven goal to report the verification results to the Pact Broker. This goal is actually just the mvn test -Dpact.verifier.publishResults=true -f pom.xml command.
  18. Run the pact:can-i-deploy maven goal to verify if we can deploy the provider.
  19. Run the pact:can-i-deploy maven goal to verify if we can deploy the consumer.
  20. Explore the ci-script.sh files in both applications and understand the versioning.
  21. Run the consumer ci-script.sh file and look at the matrix in the Pact Broker.
  22. Run the provider ci-script.sh file and look at the matrix in the Pact Broker.
  23. Rerun the consumer ci-script.sh file now that the provider is deployed to the test environment.
  24. Explain the idea of versions and tagging.
  25. Go through some more slides.

More to discover:

  1. Feature branches (https://github.com/pact-foundation/pact-jvm/tree/master/provider/maven#publishing-pact-files-to-a-pact-broker)
  2. Pending / WIP pacts (https://docs.pact.io/pact_broker/advanced_topics/pending_pacts/ https://docs.pact.io/implementation_guides/jvm/provider/junit/#pending-pact-support-version-413-and-later)