paint-brush
Contract Testing: Practical Comparison of PACT, Spring Cloudby@romanglushach
1,335 reads
1,335 reads

Contract Testing: Practical Comparison of PACT, Spring Cloud

by Roman GlushachJuly 27th, 2023
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Contract testing is a method for verifying system integration by individually examining each application to ensure that contracts and interfaces adhere to the agreed-upon alignment. A mock integration point enables the validation of a component’s expected behavior without reliance on that component. In the case of a large and intricate application, it may be necessary to establish an integration point trusted by multiple applications. This trusted integration point’s behaviors are validated by all dependent applications, preventing inadvertent or malicious changes from impacting the entire system. Thus, a system can be constructed in which each component performs a specific task, safeguarding the system against accidental or malicious alterations to any of its components.
featured image - Contract Testing:  Practical Comparison of PACT, Spring Cloud
Roman Glushach HackerNoon profile picture

Contract testing is a method for verifying system integration by individually examining each application to ensure that contracts and interfaces adhere to the agreed-upon alignment. A mock integration point enables the validation of a component’s expected behavior without reliance on that component.


In the case of a large and intricate application, it may be necessary to establish an integration point trusted by multiple applications. This trusted integration point’s behaviors are validated by all dependent applications, preventing inadvertent or malicious changes from impacting the entire system.


Thus, a system can be constructed in which each component performs a specific task, safeguarding the system against accidental or malicious alterations to any of its components.

Why opt for contract testing? What are the advantages of this approach?

Contract testing is an excellent technique for:

  • Identifying irregularities in consumer workflows and addressing them early on
  • Detecting service configuration defects that may impact inter-application communication
  • Ensuring secure connections even when producers make changes to service configurations, providing guarantees to data consumers
  • Allowing producers to perform their tasks without disrupting the consumer’s workflow, which is also beneficial for regression testing
  • Giving consumers the flexibility to specify their requirements and consume only what they need
  • Preventing unexpected API communication failures due to local or mock implementations, resulting in more stable, faster, and reliable testing of the application
  • Rapidly detecting and resolving issues

When is contract testing not the best choice?

It’s important to consider both sides of the coin before making a decision.


Here are the main reasons why contract testing may not be suitable:

  • Contract tests are not a replacement for Unit or Functional (component) tests
  • Contract tests are not intended to substitute for any other type of testing
  • If there is little or no communication between teams where contract tests are being set up, this can result in a stale contract that should not be trusted or relied upon
  • Simply adding contract tests as another layer of test coverage or because it’s a new and trendy technique will not provide any value to your test flows
  • Before making any decisions, it’s important to evaluate the business value, estimated time of arrival for implementation, and consider the minimum viable product that can be provided and presented. It’s also worth noting that integrating new features or tools requires workshops to onboard teams and users.

Where do contract tests fit within the testing pyramid?

Testing pyramid


To gain a better understanding, let’s examine the following table:

Aspec

Unit

Contract

API

Way to execute

local

local

environment

Feedback time

fast

medium

slow

Setup complexity

low

medium

high

Cross-team collaboration

no

yes

yes

What tools are available for contract testing? What are my options?

There are a limited number of battle-tested and production-ready tools available for implementing contract testing.


Some options include:

Which tool is the best fit for my project?

Here is a brief overview of what each tool offers to help you make an informed decision:

Aspect

Pact

Spring Cloud Contract

Deployment / Administration / Hosting

- Pactflow - paid
- Broker - free and open source but you need to host it and maintain it

- uses artifactory

Supported languages

- JS, JVM, Net, Go, Python, Swift, Scala, PHP, Ruby, Rust, C++
- Keep in mind that there are some limitations for specific languages. Meaning that some languages have more features than others

- By default only JVM based languages
- To support other languages you need to use docker image that will download the required contracts from artifactory and expose the endpoints from the image to your service

Supported languages for writing contracts

- It is optimized for use with "pacts" (contracts created by the Pact framework) but can be used for any type of contract that can be serialized to JSON

- Groovy
- Kotlin DSL
- Java
- YAML

Message types support

- REST API contracts
- Async communication - Pact v3 (no offical support for Python)

- REST API contracts
- Async communication via Wiremock

What are the default approaches or workflows used by each tool and how do they differ?

Let’s examine how producer-driven contract testing is implemented:

Producer-driven approach


In a producer-driven approach, the producer generates contracts and shares them with consumers.

Now, let’s delve deeper into how the Spring Cloud Contract tool operates and what happens behind the scenes:

Now, let’s examine the workflow for consumer-driven contract testing:

Consumer-driven approach

The following image provides a visual representation of how Pact operates:

Pact workflow

What are the steps involved in creating a new contract?

Add new contract

  1. Add new contract to repository
  2. Review contract
  3. Implement consumer-side tests
  4. Implement producer-side tests
  5. Merge contract and tests

Updating an existing contract

  1. Updating the contract in the repository
  2. Reviewing the updated contract
  3. Applying changes to each consumer and producer
  4. Merging updated contract and changes

When should contract tests be executed?

Integration into the development pipeline includes:

  1. Build phase: build code and generate contracts
  2. Test phase: perform unit, integration, contract, and other automated tests in parallel. Consider a backup plan for quick production deployment during incidents.
  3. Deploy to production

Conclusion

This article explains what contract testing is, its advantages and disadvantages, and how to make informed decisions.

Next Steps

Let’s explore building a highly scalable solution using GitHub or GitLab pipelines.