npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

grunt-mocha-concurrent

v0.2.0

Published

Run mocha tests in parallel using concurrent grunt tasks.

Downloads

1,544

Readme

grunt-mocha-concurrent

Run mocha tests via concurrent grunt tasks.

Installation

npm install grunt-mocha-concurrent --save-dev

Overview

Even though there are lots of posts online that don't recommend running tests in parallel, I've almost halved the time it takes for my tests to run. Sure, it can be harder to debug issues, but since this uses grunt-concurrent to spawn separate processes there won't be any "cross wire" bugs. Besides, if your test fails you can just revert to running your regular serial grunt test task along with a mocha .only. But when things are green then why not go faster? :thumbsup:

Getting started

This plugin requires grunt-mocha-test and grunt-concurrent. grunt-env is optional.

Check that your Gruntfile.js looks something similar to this. It's important that Concurrent.init(grunt); appears after you call initConfig().

const Concurrent = require("grunt-mocha-concurrent");
...
grunt.loadNpmTasks('grunt-mocha-test');
grunt.loadNpmTasks('grunt-concurrent');
grunt.loadNpmTasks('grunt-mocha-concurrent');
...
grunt.initConfig({
  ...
});
Concurrent.init(grunt);

mocha_concurrent task

Simple example

If your tests don't have any central external dependencies like a database, then this is the example for you.

grunt.initConfig({
  ...
  mocha_concurrent: {
    your_target: {
      specs: [
        {
          mochaSpec: {
            options: { 
              reporter: 'dot', 
              timeout: '2000'
            },
            src: ['tests/unit/**/test*.js']
          }
        },
        {
          mochaSpec: {
            options: { 
              reporter: 'dot', 
              timeout: '2000'
            },
            src: ['tests/functional/**/test*.js']
          }
        }        
      ]
    },
  }
  ...
});
...
grunt.registerTask('spec:concurrent', ['mocha_concurrent:your_target']);

When you run grunt spec:concurrent it will run your unit tests and your functional tests in parallel.

mochaSpec is just forwarded directly to grunt-mocha-test so look up their documentation if you want to know more about the options.

Advanced example

Say your functional tests read and/or write to the database. You can't run parallel tests in the same process as your tests will step all over each other. You can't run parallel tests in different processes pointing to the same database either! So we get around this by using a different database instance in each task. :v:

If you use an environment variable to set which database to connect to, then you can use this example. This assumes that your test framework will dynamically create your database/schema for you. I'm using mongodb so this just happens automagically.

grunt.initConfig({
  grunt.loadNpmTasks('grunt-env');
  ...
  mocha_concurrent: {
    your_target: {
      specs: [
        {
          mochaSpec: {
            options: { 
              reporter: 'dot', 
              timeout: '2000'
            },
            src: ['tests/unit/**/test*.js']
          }
        },
        {
          mochaSpec: {
            options: { 
              reporter: 'dot', 
              timeout: '2000'
            },
            src: ['tests/functional/controllers/**/test*.js']
          },
          envSpec: {
            MONGODB_URI: 'mongodb://localhost:27017/my-test-db-1'
          }          
        },
        {
          mochaSpec: {
            options: { 
              reporter: 'dot', 
              timeout: '2000'
            },
            src: ['tests/functional/models/**/test*.js']
          },
          envSpec: {
            MONGODB_URI: 'mongodb://localhost:27017/my-test-db-2'
          }
        }
      ]
    },
  }
  ...
});
...
grunt.registerTask('spec:concurrent', ['mocha_concurrent:your_target']);

When you run grunt spec:concurrent it will run your unit tests and two of your functional test flavours in parallel.

Default Options

grunt.initConfig({
  mocha_concurrent: {
    options: {
      concurrentLimit: 1,   // Number of concurrent tasks to run in parallel. Defaults to number of cpu cores.
      envDefault: {},       // Environment variables to pass to all tasks. Defaults to null.
      envTaskPrefix: "",    // Prefix to use for grunt-env tasks. Defaults to mochaConcurrent-.
      mochaTaskPrefix: "",  // Prefix to use for grunt-env tasks. Defaults to mochaConcurrent-.
    },
    ...
  },
});

Tips

  • You can get fancy and generate your mocha_concurrent target specs depending on what you need. E.g. I looped over each folder under tests/functional/controllers and created a separate spec for each, each with a unique database connection string.
  • If your application is a HTTP API and you call it in your tests, you can also just increment the port number for each spec using the env variable.
  • There is overhead involved in spinning up separate tasks with their own database etc. The more cores you have the more time this will save. Otherwise it may actually be slower than a single task!
  • Clean up old databases after the tests to save space. I defined a global mocha post test using .after() and included it in the mochaSpec src for each spec. Mongoose gives you a way to delete the database.
  • If you don't want grunt to stop when it encounters a failed test, consider using grunt-continue.