When developers update application components, testing is needed to ensure the changes don’t cause problems with other, dependent components. Typically, integration and end-to-end tests are used. However, this requires a lot of coordination between different developers.
Challenges with Integration Testing
Another issue is the number of component integrations that will require testing. For instance, ten connected components could have up to 45 integrations, with each involving one- or two-way communication. This challenge is exacerbated in serverless architectures as the number of components in an application can be much higher.
Common integration and end-to-end tests present their own challenges. For example, any components involved in the test must be running at the same time. If the components are handled by different developers, they must coordinate their release schedule so the entire workflow can be tested. What’s more, the deployment of these components results in billable usage.
Contract Testing Can Help
Contract testing addresses these challenges by using a broker and a contract to test component integration points.
A contract defines the structure of an expected request and response for a given component. This can include parameters, transport protocol, and body. The contract is then sent to a broker for validation and storage. Rather than messaging each other, components message the broker, which validates requests and responds as appropriate.
In many ways, contract testing is similar to integration testing. However, the broker helps avoid dependency on target components by providing responses on their behalf. Each component is, essentially, isolated from the workflow. We can also avoid components that don’t need testing, such as fully managed services and components that are not yet ready to test.
Contract testing also avoids the need for developers to coordinate release cadences. Once the contract is agreed, they can test requests and responses through a broker instead of with dependent components.
An Open-source Tool for Contract Testing
Open-source tool Pact can be used to help provision the broker along with its database, providing libraries to interact with the broker and run tests. It’s not intended to test the quality or ability of written code, but it verifies requests and responses between components.
It’s important to note that Pact was most likely designed for container-based microservices rather than serverless architectures. With a container architecture, it’s not uncommon for two microservices to talk directly to each other. However, that’s an anti-pattern in serverless where a decoupler such as SQS or SNS should always be involved. Serverless architecture also minimises custom code, preferring fully managed cloud services where possible. Strict contract testing requires testing of both sides, but writing contract tests for managed services that we can’t change offers little value.
A Tailored Approach to Testing
There is no one size fits all solution to testing, and it’s often best to use a combination of approaches.
Integration tests may be best when we want to test interactions with managed cloud services. However, contract testing can add value to serverless architecture if its implementation is adjusted. Microservices will have a managed decoupler between them, and there is little value in testing such a managed service. So, the contract test can focus on the messages exchanged between the microservices.
For example, in the below diagram, instead of writing a contract test between component A and SQS, we focus on the data indirectly exchanged between the two components. The underlying messaging technology could be implemented using SQS or EventBridge. While the technology will not be tested by the contract, it does need to factor in any changes it makes to the message structure.
Watch the video for a step-by-step example of a workflow visualising how this works.
Thomas is a Lead Consultant at Sourced with over 18 years of experience in delivering digital products. He gained a passion for evangelising Serverless architecture through his enthusiasm for cloud and entry into the AWS Ambassador programme.