Contract testing has been around the same time as that of microservices, and there is a link between them. Microservices architecture with its distributed nature follows contract testing as its crucial testing step. In recent years microservices has gained popularity and hence contract testing is also gaining popularity.
Technology giants like Google, Facebook, Amazon have been using contract testing technique to test their microservices for over a decade. It is not only exclusive to tech giants who build and handle enormous applications but also to any application building organizations. Organizations that follow service-oriented architecture can, also, benefit from contract testing. Thus, it has become an important concept in today’s technology landscape.
What is Contract Testing?
In simple words, it is a testing of integration points in a distributed setup following a common agreement.
The rise of distributed system architecture and Contract Testing:
A summary of an era before the distributed infrastructure.
In the past, most organizations were using monolithic application architecture that often failed due to frequent inconsistencies - A monolithic architecture has all the services bundled as a single stack. A monolithic architecture has a centralized control system and most of the inconsistencies would be because of the centralized control system failure.
These inconsistences had led to severe business impact in the past, and hence many organizations started switching to a distributed architecture for improved consistency and reliability.
A distributed architecture does not have any centralized dependency. In this architecture, systems communicate with each other via message passing mechanism. Thus, in case of system failure, other system (s) can continue to operate.
Now that we are familiar with common application infrastructure and the reason for switching to a distributed one, let us investigate various architecture related testing strategies. Testing strategies vary with organization or project infrastructure. Some testing strategies might work well with one type of infrastructure and while with others it might be a complete failure.
Let us discuss the testing types based on infrastructure architecture:
- Monolithic Application Architecture – Monolithic application heavily depends on a centralized component. Thus, the testing is performed on the main centralized component.
- Distributed Architecture – These architectures have all the components spread out and thus the testing is performed across all those components for redundancy and integration checks.
Where would you use Contract Testing?
We often use contract testing to test an integration point between multiple services. They are used in APIs, microservices and so on. To know more, we need to understand some basic concepts.
Before going into details let us discuss some key concepts:
Consumer: This service depends on a producer to fulfil their task.
Producer: It supplies relevant data to the consumer helping consumer fulfill their task.
An isolated service usually comprises consumer and a producer. These isolated services might need to interact to accomplish a task. A successful interaction would mean a consumer and a producer is following a common contract.
Now that we are aware of how the isolated services work let us investigate contract testing types. They are:
- In consumer-driven contract testing, the consumer oversees contract creation. You might wonder why would a consumer take in charge of contract creation?
- To understand that, let us assume there is a producer with many open service ports. A consumer wants to interact with this producer to access service port A.
- Here consumer needs to let the producer know about their needs. Hence the consumer creates a contract based on their requirements. All the system producers can access this contract.
- In this scenario for a successful interaction between the two parties, we follow the following steps:
- Producers test the consumer's requirements and produce a test response.
- Then the producer compares its response with the consumer's response.
- In case of a match between the responses, the two parties start to interact.
- As compared to the consumer driven-contract testing a producer-driven contract testing is rarely used.
- In this testing, a producer takes charge of creating a contract between them and the consumer. Then the producer runs several build tests to meet the contract.
- If the producer passes all the test cases, then the results get stored in a common repository.
- The consumer then runs the build and test cases. Both parties interact only after passing all the test cases.
When to use Contract Testing?
Certain environments have excellent contract testing compatibilities. API is one of them. In an API environment, the service contract aligns with API specification and that is followed by API producers and consumers. It requires you to invest time on understanding the testing compatibility with your project. After you do a feasibility check it is recommended to look for available accurate service dependent information and dependencies.
It is mostly used for:
- Detecting irregularities in a consumer workflow
- Detecting any service configuration defects
- Keeping the connections safe even when the producer changes any service configuration
Why should one choose Contract Testing?
Contract testing is favored by many organizations for staying ahead and secure in their game because of its invaluable advantages.
Some of the reasons why you should choose contract testing are:
- Producers can carry out their tasks without breaking down consumer's workflow
- The consumer has the freedom to define their requirements
- Smooth microservices integration and testing
- Fights sudden API communication failure
- Smooth environment testing, maintenance and builds
- Fast issue fixing time
Now that we are aware of the advantages, let us see if you are ready to use it.
Are you ready for Contract Testing?
Every project has its requirements. The best way to decide the contract testing feasibility would be based on:
- Project technical dependencies
- Project feasibility
- Subject matter expert's opinion
The next step would be selecting a contract testing tool. Selecting a testing tool depends on:
- Project requirements
- Tool cost and feasibility
- Tool scalability and flexibility
If all the above points are checked and you have sufficient answers, then contract testing might be the right way to go.
Things to know before opting for Contract Testing:
Contract testing establishes an interactive channel between a consumer and a producer. The interactive channel is only possible if both parties agree with a common contract. However, this testing does not check for side effects like validation errors and so on.
Tips before opting for contract testing:
It is always better to prepare mock services. The mock services would behave like a pseudo consumer request.
- The need for a pseudo consumer:
- To conduct a contract testing, there needs to be a consumer and a producer. If a consumer is unavailable because of some unavoidable circumstances. A pseudo consumer would help in evaluating the connectivity before production deployment. Pseudo consumer helps with test impact and data modification awareness before moving to the production.
- It is better to know the full contract-testing coverage. That is how far one can test individual services. Contract testing provides the best result when a service testing depth is clear.
Contract Testing Tools:
There are many tools available on the market. But some popular tools are:
- Pact: It is a command-line tool. This tool has a faster feedback time. It helps with better communication between the consumer and the producer.
- Spring Cloud Contract: This tool is primarily suitable for the JVM environment but can be easily extended to a non-JVM environment. This tool is suitable for producer-driven contract testing.
Contract Testing Use Cases:
This section will give you an idea about scenarios where the contract testing fits the best.
Microservices: The most common use case would be microservices.
Most organizations fail to take software versioning seriously till the end of the SDLC process. It is the same while implementing a microservice. As microservices usually have many components and maintaining them can become increasingly confusing due to:
- Lack of proper versioning, documentation, and failed integrations.
- Increased testing complexity that comes with scale.
API: Contract testing keeps the API producers in sync with the consumers.
- The consumer is ready with all the relevant test cases and stores the result in a computer program.
- The test case is verified by the producer. After the verification, a consumer interacts with the API producers.
It helps with:
- Maintaining a correct interactive session between a consumer and a producer.
- Monitoring the responses between a consumer and a producer.
- Increasing microservice compatibility.
An easy technical summary:
Let us first understand the term test double. A test double is a technical term for a test replica. That is used to understand test behavior in a production environment. Let us think of the test double as a stunt double in action movies.
During contract testing:
- Consumer side bargains to keep the test double aligned with the contract.
- Producer does everything to follow the contract.
The above steps allow the siloed components to effectively talk with each other for a task completion.
By now, many organizations who are dealing with multi-user application have switched to a distributed architecture. They are investing more in keeping their distributed components’ bond stronger. Distributed services might pose some serious challenges like service misalignment. A simple misalignment can risk an organization's value, customer experience, and eventually reputation. If contract testing is followed from the day one of microservice implementation, then it can prevent such service misalignments.
You can choose contract testing based on your project need, costs, technical feasibility, and subject matter expert guidance. Although implementation of contract testing can save a lot of production failure probabilities, and feedback time; improper analysis and planning might not give any desired outcome.
If you are wondering how to introduce contract testing strategy to your SDLC, get in touch with us. We would love to help you build perfect game plan that can improve your application quality.