As software becomes increasingly complex, more and more companies are turning to APIs as a way to organize and manage their application’s functionality. Instead of being one monolithic application where all changes are released at once, now software can be made up of multiple APIs that are dependent upon each other, but which can be released separately at any time. Because of this, it’s possible to have a scenario where one API releases new functionality which breaks a second API’s functionality, because the second API was relying on the first and now something has changed.
The way to mitigate the risk of this happening is through using API contract tests. These can seem confusing: which API sets up the tests, and which API runs them? Fortunately after watching this presentation, I understand the concept a bit better. In this post I’ll be creating a very simple example to show how contract testing works.
Let’s imagine that we have an online store that sells superballs. The store sells superballs of different colors and sizes, and it has uses three different APIs to accomplish its sales tasks:
Inventory API: This API keeps track of the superball inventory, to make sure that orders can be fulfilled. It has the following endpoints:
- /checkInventory, which passes in a color and size and verifies that that ball is available
- /remove, which passes in a color and size and removes that ball from the inventory
- /add, which passes in a color and size and adds that ball to the inventory
Orders API: This API is responsible for taking and processing orders from customers. It has the following endpoints:
- /addToCart, which puts a ball in the customer’s shopping cart
- /placeOrder, which completes the sale
Returns API: This API is responsible for processing customer returns. It has the following endpoint:
- /processReturn, which confirms the customer’s return and starts the refund process
- When the Orders API processes the /addToCart command, it calls the /checkInventory endpoint to verify that the type of ball that’s been added to the cart is available
- When the Orders API processes the /placeOrder command, it calls the /remove command to remove that ball from the inventory so it can’t be ordered by someone else
- When the Returns API runs the /processReturn command, it calls the /add command to return that ball to the inventory
- /checkInventory, where the body contained { “color”: “purple”, “size”: “small” }
- /remove, where the body contained { “color”: “red”, “size”: “large” }
- /add, where the body contained { “color”: “yellow”, “size”: “small” }
That was interesting and quite clear.
Just wondering whether you’ve tried this approach and what software were you using? I hear a lot about Pact, but there’s also Spring Cloud Contracts and apparently Postman can also be used in this way.
I'm glad you liked my post, Nitbuntu! I haven't tried setting up contract testing yet, but when I do, I plan to use Postman.
The pact documentation talks about comparison between contract testing and functional testing here: https://docs.pact.io/consumer/contract_tests_not_functional_tests
and I have not been able to wrap my head around it at all. If you get it, could you maybe help me understand what could be the difference between contract and functional testing of a service?
Also in contract testing is it important for the accuracy of the values in the service's response or is it just the response structure that matters?
Great question, Abhijeet! I think the difference between contract tests and functional tests is that the contract tests only focus on the relationship between the two APIs. In the example in this blog post, we have the Returns API with the /processReturn endpoint. That endpoint adds a ball back to the inventory and starts the process to refund the money to the customer. When the Returns API team provides contract tests to the Inventory API, they're not going to include any tests for refunding money, because that has nothing to do with the Inventory API. Any tests for refunding money would be functional tests for the Returns API.
Does that mean, we need another layer to support contract tests, other than functional. Why I am saying is because let's say I have a functional suite using RestAssured , so now, I need to use another tool/lib for contract tests?
Hi Sunny- no, contract tests don't need another layer; you can simply add new API tests into your existing framework. While there are tools that use mocking or virtualization to simulate an APIs response, you don't have to use them, and you can instead rely on calls to the real service.
I must thank you for the efforts you have put in penning this site. I am hoping to check out the same high-grade content by you later on as well. Keep up the good work
software testing services
software testing companies
Security testing services
Test automation services