Contract Testing and API Testing: What You Need to Know
Before starting, let’s look at API and API testing. If you’re a pro in that, skip the first three paragraphs and dive directly into the juicy party.
API stands for application programming interface. It enables the communication and data transfer between two software systems.
Little side note: Every developer develops toward an API since the computer exists. Every computer library exposes its functionality via an API. Therefore, every software developer is an API tester or at least a consumer 😉.
Today, the typical kind of API technology-wise is REST API or GraphML API, where you request data stateless via internet protocols.
The APIs need to be tested to ensure the programming interface's functionality,liability, performance, and security. API testing is a type of software testing. From a software architecture perspective, it's performed on the business logic layer.
Contract testing is a different name for API testing. There are different opinions out there about the definition. Some say it’s a lightweight form of API testing; other seven combine the names to API contract testing.
Recently, everybody talks about contract testing. This comes from the bad image testers and managers have about end-to-end testing, as it involves the UI layer. Which,for some, makes it complicated to test. The idea is to remove the user interface layer and only test the API.
That stems from the microservice culture. You have many different microservices that communicate with the application through APIs and orchestrate them. You could say that you only need to test the APIs as they reflect the logic.
From this perspective, only the microservices get tested, not the application itself.Therefore, bugs a user might run into don't get detected, as the user doesn't interact with the API; he interacts with the application's UI.
Before we dive deeper into why that is, let's jump back in time and look at a similar scenario from the 90s with the database.
In the past, the idea was to have the logic close to the data. First, there were databases and then database management systems. The difference is that data is stored in the database, and authorizations and logic are stored in the database management system. They're known as stored procedures.
You don't add data with highly transactional data; you use stored procedures. For example, you say you want to add a credit card, and the stored procedure does it for you with the entered data. This means that the logic for the data is in the same system as the data. As the logic is already in the database, the conclusion was that you only need to test the database.
However,the customer doesn't call stored procedures on the database directly. He works with a graphical user interface that calls the stored procedures from the database.
It's the same situation as with API, aka contract testing today. There is an application that calls the APIs, but the user doesn't do it directly. You could argue that the business logic is abstracted from it. But the actual logic isn't abstracted. The API doesn't cover things like the following:
- What happens if the connection is lost?
- What happens if the returned results aren’t as expected?
- How is versioning between server and client handled?
It's often overlooked that even if the logic is in the controller, meaning you have separated business logic, the application only calls the different endpoints and doesn't have actual logic itself; it never covers the whole story. It leaves behind the user perspective and interactions. Ultimately, you don't test an application to move your task to done on the board. You test to ensure everything works as expected, and therefore, your users/customers are happy,and you don't get a loss in your revenue or bad reputation.
Let's look closely at it: The call of the endpoints is a workflow that needs to be tested. There is one approach to recreate that with Postman scripts. But this way, you are rebuilding the software, and the actual software doesn't get tested either.
Don't get me wrong, contract testing is valuable, no question. For sure, it can replace one or the other end-to-end test. But if you use it isolated, you don't get the desired results.
To recap,the end-user doesn't call any API; he/she works with the application's user interface, which calls the APIs. The application has a logic itself, which is not covered by the API. Usually, this happens at the client the end-user uses:
- How do I access the API?
- What are the secrets to call the API?
- What are possible result values?
- You need latency strategies, in case the network is slow
- You need caching in your application.
All of this is not tested via API testing and might lead to severe problems on your customers' site.
We're a bit old-fashioned and stick to the established name API testing. With TestResults.io, you get model-based API testing. There are no raw calls; it's always an abstraction of the application behind. For example, it allows in the test case to say: "I want to create a login," and the login itself knows which API calls it needs to make. You don't need a Postman script with five calls to execute; the model abstraction in TestResults.io handles this for you.
A great way to use API testing is in combination with UI testing. This way, you can create test data through the API and then check in the UI how you can interact with this data.
End-to-end testing expanded with the options of API testing. You get the best of both worlds.