본문 바로가기
  • AI (Artificial Intelligence)
Fundamental/TTD (Test-driven development)

Contract Testing for Node.js Microservices with Pact

by 로샤스 2021. 7. 5.

Ref. https://codersociety.com/blog/articles/contract-testing-pact

Contract testing helps ensure the compatibility of microservices and decouples the development and deployment processes of software teams. In this article, you'll learn more about contract testing and how to use Pact to verify and ensure your Node.js microservices' API compatibility.

In this article

Ensuring API compatibility in distributed systems

The use of microservices is growing in popularity for good reasons. They allow software teams to develop, deploy, and scale software independently to deliver business value faster. Large software projects are broken down into smaller modules, which are easier to understand and maintain. While the internal functionality of each microservice is getting simpler, the complexity in a microservice architecture is moved to the communication layer and often requires the integration between services.

However, in microservice architectures, you often find service to service communication, leading to increased complexity in the communication layer and the need to integrate other services.

Figure 1: Distributed systems at Amazon and Netflix

Traditional integration testing has proven to be a suitable tool to verify the compatibility of components in a distributed system. However, as the number of services increases, maintaining a fully integrated test environment can become complex, slow, and difficult to coordinate. The increased use of resources can also become a problem, for example when starting up a full system locally or during continuous integration (CI). Contract testing aims to address these challenges – let's find out how.

What is contract testing?

Contract testing is a technique for checking and ensuring the interoperability of software applications in isolation and enables teams to deploy their microservices independently of one another. Contracts are used to define the interactions between API consumers and providers. The two participants must meet the requirements set out in these contracts, such as endpoint definitions and request and response structures.

Figure 2: A contract that defines a HTTP GET interaction

What is consumer-driven contract testing?

Consumer-driven contract testing allows developers to start implementing the consumer (API client) even though the provider (API) isn’t yet available. For this, the consumer writes the contract for the API provider using test doubles (also known as API mocks or stubs). Thanks to these test doubles, teams can decouple the implementation and testing of consumer and provider applications so that they’re not dependent on each other. Once the provider has verified its structure against the contract requirements, new consumer versions can be deployed with confidence knowing that the systems are compatible.

Figure 3: Consumer-driven contract testing

What is Pact?

Pact is a code-first consumer-driven contract testing tool. Consumer contracts, also called Pacts, are defined in code and are generated after successfully running the consumer tests. The Pact files use JSON format and are used to spin up a Pact Mock Service to test and verify the compatibility of the provider API.

The tool also offers the so-called Pact Mock Provider, with which developers can implement and test the consumer using a mocked API. This, in turn, accelerates development time, as teams don't have to wait for the provider to be available.

Figure 4: Pact overview

Pact was initially designed for request/response interactions and supports both REST and GraphQL APIs, as well as many different programming languages. For Providers written in languages that don't have native Pact support, you can still use the generic Pact Provider Verification tool.

Try out Pact

Why don't we test things ourselves and see how consumer-driven contract testing with Pact actually works? For this, we use Pact JS, the Pact library for JavaScript, and Node.js. We've already created a sample repository containing an order API, which returns a list of orders. Let’s start by cloning the project and installing the dependencies:

$ git clone https://github.com/coder-society/contract-testing-nodejs-pact.git

$ cd contract-testing-nodejs-pact

$ npm install

Writing a Pact consumer test

We created a file called consumer.spec.js to define the expectedinteractions between our order API client (consumer) and the order API itself (provider). We expect the following interactions:

  • HTTP GET request against path /orders which returns a list of orders.
  • The order response matches a defined structure. For this we use Pact’s Matchers.

Verifying the consumer pact against the API provider

We can now use the generated Pact contract file to verify our order API. To do so, run the following command:

This starts the API server and runs the Pact Verifier. After successful verification, we know that the order API and the client are compatible and can be deployed with confidence.

Wrapping up

By now you should have a good understanding of contract testing and how consumer-driven contract testing works. You also learned about Pact and how to use it to ensure the compatibility of your Node.js microservices.

To avoid exchanging the Pact JSON files manually, you can use Pact Broker to share contracts and verification results. This way, Pact can be integrated into your CI/CD pipeline – we will talk more about this in a future blog post.

Visit the Pact documentation to learn more about Pact and consumer-driven contract testing for your microservices.

Kentaro is CEO and Solutions Architect at Coder Society. With his in-depth knowledge of software development and cloud technologies, Kentaro often takes on the lead engineer's role. His analytical, organized, and people-oriented nature makes him an apt advisor on software projects and flexible staffing.

'Fundamental > TTD (Test-driven development)' 카테고리의 다른 글

How to Setup SonarQube locally on Mac  (0) 2023.09.13
Mocha vs. Jest: comparison of two testing tools for Node.js  (0) 2021.07.12
TestDouble  (0) 2021.07.05
[Mockito] Mock 개념(Mock Object)  (0) 2021.07.05
Mock 이란?  (0) 2021.07.05

댓글