Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you structure the tests for your server applications in Node.js?

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) :

code hell

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?

like image 251
Samuel Bolduc Avatar asked Dec 12 '13 16:12

Samuel Bolduc


People also ask

What is the best testing framework for nodeJs?

What are the best Node. js unit testing frameworks? According to “The State of JavaScript 2021,” the most popular JavaScript testing frameworks and libraries in 2021 were Testing Library, Vitest, Jest, Cypress, Playwright, and Storybook. Rounding out the top ten are Puppeteer, Mocha, Jasmine, AVA, and WebdriverIO.

Which module is used for testing a node application?

The assert module. The basis for most Node unit testing is the built-in assert module, which tests a condition and, if the condition isn't met, throws an error. Node's assert module is used by many third-party testing frameworks. Even without a testing framework, you can do useful testing with it.


1 Answers

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.

Option 1: Namespacing via dot notation

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

Option 2: Namespacing via folders

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

Option 3: Separate using modules

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

Option 4: Code folding

Sometimes large files are unavoidable and this is why all good text editors have a code folding feature.

like image 74
srquinn Avatar answered Oct 02 '22 22:10

srquinn