Back to Projects
Case Study

REST API Testing & Automation: TheCatAPI

I picked a public API, tested it end-to-end using Postman, wrote automated test scripts, and found a real bug that most people would have ignored or missed. This is the story of how that happened.

At a Glance

Core Technologies

PostmanJavaScriptJSONREST API
REST API Testing & Automation: TheCatAPI

Why TheCatAPI

I wanted to practise API testing on something real — not a mock server, not a tutorial endpoint, but a live API with actual responses, authentication, and edge cases.

TheCatAPI is a public REST API that serves cat images and breed data. It has both open endpoints and authenticated ones (requiring an API key), which made it a good candidate for testing a full range of scenarios: happy path, negative cases, auth failures, and boundary conditions.

What I Tested

I covered five endpoints across eight test cases:

  • GET /images/search — image retrieval with filters
  • GET /breeds/search — breed lookup with valid and invalid queries
  • POST /favourites — adding an image to favourites (authenticated)
  • DELETE /favourites/{id} — removing a favourite (authenticated)
  • POST /votes — voting on an image (authenticated)

For each endpoint I thought about: what should happen, what could go wrong, and what happens at the edges.

The Bug I Found

This is the part that surprised me.

When I sent GET /images/search?limit=2, I expected 2 images back. I got 10.

I thought maybe I made a mistake. So I tried limit=1000. Still got 10.

The API is completely ignoring the limit parameter. It returns 10 results regardless of what value you pass — no error, no warning, just a silent 200 OK with the wrong count.

Why this matters:

A client application relying on limit=1 to show a single random cat image would unknowingly receive 10 objects every time. That's wasted bandwidth, unexpected UI behavior, and a trust issue — the API says it supports a parameter but doesn't actually use it.

A well-designed API should either enforce the limit or return a 400 Bad Request with a message like "limit must be between 1 and 100". Silent failures are the hardest bugs to catch in production.

Automated Test Scripts

For the GIF image search endpoint, I wrote Postman test scripts to automate response validation:

javascript
pm.test("Status code is 200", function () 
        {  
          pm.response.to.have.status(200); 
        });  

pm.test("Response returns exactly 1 result", function () 
        {  
          var jsonData = pm.response.json();
          pm.expect(jsonData.length).to.equal(1);
        });  

pm.test("Response is an array", function () 
        {
          var jsonData = pm.response.json();
          pm.expect(jsonData).to.be.an('array'); 
        });  

pm.test("Image URL ends with .gif", function () 
        {
          var jsonData = pm.response.json();
          pm.expect(jsonData[0].url).to.include('.gif'); 
        });  

pm.test("Image has required fields", function () 
        {  
          var jsonData = pm.response.json();
          pm.expect(jsonData[0]).to.have.any.keys(
            'id', 'url', 'width','height'
          ); 
});

Result: 5/5 passed.

What I Learned

Negative tests matter as much as positive ones. When I searched for a breed that doesn't exist (q=abcxyz), the API returned an empty array [] — not a 404, not a crash. That's correct behavior. Knowing what "correct" looks like for a negative case is just as important as knowing what success looks like.

Boundary testing reveals what documentation hides. The API documentation says limit is a supported parameter. Boundary testing showed it's not actually enforced. You would never catch this by only running happy path tests.

Silent failures are worse than loud errors. A 400 Bad Request is frustrating but debuggable. A 200 OK with wrong data is dangerous — it looks fine until it breaks something downstream.