Rock Solid Endpoints: Using Jest snapshot testing for api integrations
Quick Note: A lot of this article is code, and the comments in the code are as much a part of the article as the text. It would be a good idea to read the comments as well as the article text.
You can view the full codebase here
As many of you know, unexpected changes in your api can be disastrous for your service. If you are running a public api, hundreds, thousands, or millions of users could be affected by your mistake. Ensuring you know when your endpoints change is critical, and you can’t always depend on unit tests to tell you. Jest snapshots have been hugely successful in front end testing, so why not apply that same technology to your endpoint integration tests? This article focuses on node based APIs, however, because this is an integration test, you can actually use this method no matter what your server technology is. None of your code needs to be importable by node. We also look at a rest style endpoint for an example, this would work almost exactly the same for a graphQL endpoint.
Jest is a testing framework created by Facebook. Jest has a very powerful feature called “snapshot” testing, where you start by telling jest to take a string, and save it, then subsequent tests check if that string has changed since the first one. A typical example would be rendering a react component with x, y, and z props, then checking if the html produced is different in subsequent tests. Checkout the snapshot testing jest page
There are some prerequisites to your setup that need to be understood.
- There should be some kind of migrations, or schema definitions for initializing your database. It needs to be easy and fast to spin up a new dev database and server. Alternatively, if the setup is very slow, and would bother your developers too much, you could run this test in your CI server.
- It’s best if you can use an environment variable to specify which database and port you use, however, config files would also work if this is run on a CI server.
In this example, I’m going to use sqlLite3, knex, and express. For a more advanced dev environment look into docker for your database, which should allow you to easily spin up database services.
Express Setup for Integration snapshot testing
First lets start with some basic setup files for knex, and express. There are comments throughout the files to explain why things are setup this way. The most important things to notice are that the api port and database file are set by the env variables, in index.js and knexfile.js.
Finally we can setup up our commands to make this all work together.
So we have scripts to start the service in integration mode, if we wanted to debug our integration test, we could open two terminals: In one run
npm run initIntegrationDB && npm run start:integration and in a second
npm run test:integration . Which should check all your endpoints, against previous versions of themselves.
Automating the Tests
We now have enough to manually run integration tests using jest snapshots. However, automation is important, and it’s hard to automate this if you have to manually prep the database, start the server, run the tests, start jest, and then kill the server. Here is a script you can run to start the server, run jest, and kill the server. Hopefully you only need to edit the configuration items at the top to suit your needs, but feel free to deep dive into the whole script as well.
It was pointed out to me, that this ends abruptly.