Reputation: 19183
I'm starting to add tests to our Node.js server apps since we are slowly deploying into production. I have an API with many possible requests to test.
My question is: how do you structure your tests so it doesn't become a big file in which you quickly get lost?
I wrote tests for one API route (I have many other API routes to test) and this is how it looks (in Sublime file overview) :
And this test doesn't even cover all cases yet.
I'm using mocha
, along with should
and expect
for validation, and superagent
for API calls. How would you structure these tests so it doesn't evolve in a hideous big file?
Upvotes: 23
Views: 10672
Reputation: 10501
There are lots of ways to break down the files into smaller, more manageable parts. Most of them pivot around the use of the --recursive
flag in mocha
. In the end, its a matter of personal choice and what works for the team/individual.
Run mocha
without the --recursive
flag and name your files using dot notation. You can then break it down further by HTTP method and even further, if you'd like, by pass/fail. For instance, a user route would have a file name like route.user.get.pass.js
and be in the root of the test/
folder. The code for this file would look like:
describe('GET /users', function () {
describe('when the request is valid', function () {
it('should return 200 OK');
it('should have unicorns');
it('should have ponies too');
});
});
And then another test with file name route.resource.post.fail.js
would look like:
describe('POST /users', function () {
describe('when the request is invalid', function () {
it('should return 400 Bad Request');
...
});
});
This makes grepping individuals tests a breeze when using mocha
's grep feature
Similar to option 1, however, in this case you would use the --recursive
flag when running mocha
and use folders instead of nesting file names.
test/
routes/
users/
post.js
get.js
put.js
models/
User.js
This approach is a combination of the first two and should be run without the --recursive
flag. In the root of the test
directory, you would name the spec file as routes.userSpec.js
with code like:
describe('/users', function () {
describe('GET', function () {
var tests = require('./users/get');
it('should return 200 OK', tests.200);
it('should have unicorns', tests.unicorns);
it('should have ponies too', tests.ponies);
});
describe('POST', function () {
var tests = require('./users/post');
it('should return 200 OK', tests.200);
it('should create unicorns', tests.unicorns);
it('should create ponies too', tests.ponies);
});
});
And then you would define modules in the test/users
folder looking something like:
test/
users/
get.js
post.js
routes.userSpec.js
Sometimes large files are unavoidable and this is why all good text editors have a code folding feature.
Upvotes: 34