Quotes API with full test coverage
A fully tested, continuously integrated & deployed API - all OpenAPI complient!
As the quality and documentation of APIs varid greatly, I wanted mine to be as developer-friendly as possible, so I decided to implement the OpenAPI specification!
With the help of express-openapi
for the actual OpenAPI implementation, swagger-ui-express
consuming said implentation and generating interactive API documentation.
Of course I still had to actually write the schemas and fields to make it usable, so after reading the OpenAPI documentation, and relying on JSDoc comments to get VSCode to help me via autocompletion:
/** @type {import("express-openapi").OperationFunction['apiDoc']} */
I had converted my plain API over to an OpenAPI - further abstracting each of my API methods in the process.
Unit Tests
Being something that other people may rely on, it'd be irresponsible of me to leave the functionality of the API up to chance, so I decided to implement some testing, first testing of the actual API via Unit tests.
initially decided upon using jest
, but found myself struggling to get it to work with ES6 modules, so decided to switch to using mocha
with coverage provided by nyc
.
Of course nyc
was giving me issues with ES6 modules, so I swapped it out for c8
, which finally had everything working together!
Though I had to use nodemon
to get watching tests working, but at this point I wanted to stop working on the test framework and actually write a single test...
Writing Tests
The actual tests themselves were pretty straight-forward, after putting a little more work to export the express server accordingly and writing the setup/teardown code for the tests - using mongodb-memory-server
- to make the testing fully independant!
Since nearly all of these tests are against endpoints, I used supertest
which makes testing HTTP servers easy - and with the easily show coverage I even removed some unnecessary code from the pre-OpenAPI days!
GitHub Action
The goal of this action was to run my tests, and if all pass, push the current branch to deploy
, which my Heroku application is configured to automatically deploy my full application from - in addition it saved my coverage assets so I could inspect the coverage results manually.
E2E Tests
Of course while this project is mostly an API, it does contain a frontend, so I figured I'd write a few tests to ensure it works accordingly - and I decided to use playwright
to do so.
After confusing myself by just copying the coverage instructions without remembering that as I was using C8 already I didn't need to convert my C8 coverage results to istanbul, I only needed to save them in coverage/tmp
where all the other coverage results are already being saved from my backend unit tests, the coverage was working.