I was figuring out how to write test suites for APIs and I started with this tutorial, which structures tests roughly like this:
beforeEach { restore database }
- send a POST request, test the POST response
- create a new resource, send a GET for it, test the GET response
create a new resource, send a PUT with a field update, test the PUT response
etc.
This seems like a reasonable approach, but I didn’t like that all the assertions for each route are stacked inside one test - my feeling was that they should be more granular so that it’s immediately clear from the feedback which part is failing. So I wanted to have multiple it
blocks for each route, but avoid making a new HTTP request inside each test, which feels stupidly redundant. The first thing I tried was to run the tests asynchronously from the request callback, but that didn’t agree with Mocha. There’s supposed to be a workaround for that, which is basically to wrap the tests in the callback in another describe
(Node.js: Run mocha tests in a request callback). I don’t find it very elegant, but it could be the right solution, except I don’t seem to be able to get it to work.
One thing that did work for me was:
beforeAll {
- restore database
- send a POST request, cache the response
send a GET request, cache the response
etc.
}
- test the POST response
- test the GET response
etc.
Here's the code for this approach.
What I like about this is that it minimizes the number of database operations, and even though I don’t reset the database before each test, I could run them in any order despite the fact that some of them (DELETE route tests) actually alter the database. But from what I’ve read about TDD/BDD, I gather that this is not a good design. The obvious flaw is the lack of isolation - if the first request fails, all of them will fail. What this means in practice is that if the API is broken, I would have to fix it in a specific order (POST first, etc.), which is not such a big deal in a small-scale application that I’m writing. But I understand that tests should never depend on external factors, so this is likely to be considered a bad testing practice.
Is the best solution here to go back to the first approach, i.e. place all assertions in one test per route? Or is there a better alternative?
Aucun commentaire:
Enregistrer un commentaire