DEV Community

Phil
Phil

Posted on

API testing for the win

Once in a while, depending on your product, you may want to steer towards API tests for a few reasons:

  1. If you're working with a small test team, you'll get a pretty big win out of API tests. They're easier to write than UI tests, and you're only dealing with the backend.
  2. Execution times are faster (most of the time, anyway).
  3. Developers typically don't get involved with UI tests, but there may be a comfort level with API tests that might increase engagement when it comes to adding new tests, troubleshooting failures, and reviewing test results.

Let's get right to it. Overall, testing Restful services has always followed a pretty simple pattern:

  1. Depending on the type of request, there may be a payload to send.
  2. Send the request via rest library.
  3. Assert against the response.

Jest works great as a test runner and assertion library. You can use axios/supertest/request/chai as the rest library (I am personally partial to supertest). Tests are easy to write in Typescript and are (in my opinion) less verbose than using Java. Parsing JSON responses using JS is also a dream. Finally, finding some talent familiar with JS should be fairly easy.

In breaking down the above 3 steps you might want to build out a set of utils/helpers/whatever to help you do them:

  1. You may want to follow a pattern where you can build payloads, massage / transform some of it for your scenarios, and return those payloads so they can be sent off to the backend.
  2. You'll want to abstract away some of the get/patch/post/delete requests into their own functions so that you don't need to worry about auth and tokens.
  3. Unfortunately some backend responses can be massive. So asserting against dozens of keys and values can be a counterproductive exercise. Asserting on the status code, and then maybe some important IDs, and other keys that might be important to business logic might be a good place to start.

Then all of a sudden tests look very, very simple to write like this:

import { createUserPayload } from '../helpers/userPayloadHelper'
import { post } from '../helpers/requestHelper'

describe('users API', () => {
  test('create user', async () => {
    const uri = '/users'
    const user = createUserPayload()
    const response = await post(uri, user)

    expect(response.statusCode).toBe(201)
    expect(response.body.name).toBe(user.name)
    expect(response.body.email).toBe(user.email)
  })
})
Enter fullscreen mode Exit fullscreen mode

You'll find a lot of teams that also go with the whole Postman/Newman route that is pretty popular, but I have pretty strong opinions that maintaining code in the long run will always beat out maintaining a Postman collection. Plus you'll be doing your test team a favor getting them to learn to write code, and API tests follow some pretty simple patterns that are pretty hard to screw up even if you try.

Top comments (0)