Categories
API Testing Automated Testing

API “approval” testing using Jest

I recently added some API integration testing examples to my Playwright/Jest e2e automated testing repository using Supertest.

I wanted to also explore the use of Jest for approval testing of REST JSON APIs.

Jest has in built support for snapshot testing which is most commonly used to test how React components are rendered – however Jest snapshot testing can also be used to test any serializable values.

Snapshot tests are an example of what are are also known as approval tests: whereby the expected output of a test is generated the first time it is run and compared against this on subsequent runs. Changes to the output can be “approved” which become the new baseline.

These are no where near as common as “assertion” based tests whereby an automated test performs some action and asserts some results.

Assertion tests can be used to assist test driven development, whereas approval tests are generated after the fact so they can be useful for outside-in software development, API integration testing of known endpoints, and for legacy code where no assertion based or lower level tests exist.

I wrote the same integration tests in both approval and assertion style to show how these differ.

Say we have an endpoint that returns all the blog posts we have seeded into our system, we could write some assertions on the content:

const response = await request.get('/posts')
expect(response.status).toBe(200)
expect(response.body.length).toBe(3)
expect(response.body[0].id).toBe(1)
expect(response.body[0].title).toBe('Post 1')
expect(response.body[1].id).toBe(2)
expect(response.body[1].title).toBe('Post 2')
expect(response.body[2].id).toBe(3)
expect(response.body[2].title).toBe('Post 3')

Since we’re testing an existing endpoint with known “approved” behaviour we can generate and test a snapshot of it:

  const response = await request.get('/posts')
  expect(response.status).toBe(200)
  expect(response.body).toMatchSnapshot()

The first time we run this the following is generated in a separate file:

// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`can GET a REST API and check response using approval style 1`] = `
Array [
  Object {
    "id": 1,
    "title": "Post 1",
  },
  Object {
    "id": 2,
    "title": "Post 2",
  },
  Object {
    "id": 3,
    "title": "Post 3",
  },
]
`;

We commit this to our codebase and if any of the body returned for this endpoint is changed our test fails (with an option to approve the new result as the new baseline).

The benefit of these approval tests is they are quicker to write for an existing endpoint (since they are generated automatically) and are complete in that any change to the body returned will be highlighted – compared to our assertion based tests which only test specific things.

The downside to these tests is they are generated after the fact – so aren’t compatible with test driven development – and need to take into account if there is any dynamic content that changes between test runs – so these generally aren’t good for non-deterministic systems.

Feel free to check out the source code for these API integration tests and let me know what you think and whether you’ve had experience, good or bad, with approval testing.

One reply on “API “approval” testing using Jest”

Leave a Reply

Your email address will not be published. Required fields are marked *