Running Individual Tests with Karma/Mocha

As your Karma/Mocha test suite grows, it will become slower and slower. There are times when you might want to run some specific test or tests. I’ve been wondering how to achieve this for a while and finally had a little breakthrough. I ended up with syntax like this after I was done:

npm test -- suite/test name to match goes here
npm run test:tdd -- suite/test name to match goes here
As a runtime alternative, you can annotate your code with .only (i.e., describe.only or it.only). Mocha will pick that up and execute literally only those suites or tests. Just be sure not to commit these kind of changes. Thanks for the tip Kevin Lamping!

The Setup

As I assume you can set up Karma/Mocha already, I will focus just on the interesting parts. There are two places to tweak.

First of all you should make you have double dash at the end of your Karma calls like this. Without this it will pass possible additional parameters we pass directly to Karma and that’s specifically something we want to avoid. Instead, we’ll parse the argv ourselves and pass it to Mocha. Adjust your test targets like this:

package.json

{
...
“scripts”: {
...
“test”: “karma start --“,
“test:tdd”: “karma start --auto-watch --no-single-run --“,
...
}
...
}

To finalize the setup, we should capture argv at Karma configuration and then pass it to karma through its grep parameter. That unlocks the power we want:

karma.conf.js

module.exports = function karmaConfig(config) {
...
client: {
args: parseTestPattern(process.argv)
},
...
}
function parseTestPattern(argv) {
var found = false;
var pattern = argv.map(function(v) {
if (found) {
return v;
}
    if (v === '--') {
found = true;
}
}).
filter(function(a) { return a }).
join(' ');
  return pattern ? ['--grep', pattern] : [];
}

The helper function captures the passed argv and constructs a string out of them. This gives us the syntax we wanted.

A simpler alternative would be to allow just “does not crash with a number” kind of format, but then you have to remember to write those “’s when running tests.

You can find the full setup at my React component boilerplate.

Conclusion

Given this is a basic testing need, it’s likely I’m missing something obvious here given it took more lines of code than I would have liked. If you know a better way, let me know!