counterbeing
counterbeing

Reputation: 2791

How To Test a Grunt Plugin

I'm creating my first ever Grunt Plugin. I would really like to practice testing my plugin as I develop. I've selected mocha as my testing framework, as it seems popular, and setup my gruntfile to automatically watch when test files are altered and run them. This all looks good.

But, I've not found a lot of documentation on how to actually test a Grunt Plugin. I've looked at code of about a dozen different grunt plugins, especially the contrib ones, and they don't make a lot of sense to me.

As I try to test my code I'm trying to break things down into very specific functions. So, here is the basic structure of a plugin, with a function in it.

'use strict';

function testOutsideOfTask(){
  return "i am outside";
}

module.exports = function(grunt) {
  grunt.registerMultiTask('example_task', 'I do a thing.', function() {

    function testInsideOfTask(){
      return "i am inside";
    }

  });

};

I've included a couple of methods just explicitly to make sure my testing is working, and it's not. Neither of these methods seem to be accessible... How could I access both of them for testing? Here is the mocha test as I have it.

var grunt = require('grunt');
var assert = require("assert");

describe('testOutsideOfTask', function() {
  it('do something', function() {
    assert.equal("i am outside", testOutsideOfTask());
  });
});

describe('testInsideOfTask', function() {
  it('do something', function() {
    assert.equal("i am inside", testInsideOfTask());
  });
});

They both return something like this. So, somehow it just can't access the functions, however, when I look at other testing examples, they don't seem to specifically require the file that is being tested... For example https://github.com/gruntjs/grunt-contrib-clean/blob/master/test/clean_test.js

1) testOutsideOfTask should do something:
ReferenceError: testOutsideOfTask is not defined

Thanks very much!

Upvotes: 2

Views: 1214

Answers (1)

Ben
Ben

Reputation: 10146

You want to be testing functionality, ideally. Your Grunt plugin should end up as a wrapper around more abstract methods that do what you want but not necessarily tied to how Grunt works; then for the actual plugin you run those methods on each file, log some output etc. Something like this:

var lib = require('./lib.js');

module.exports = function(grunt) {
    grunt.registerMultiTask('test', function() {
        lib.doSomeMethod();
        grunt.log.ok('Something happened');
    });
}

So in that pseudo code you would want to actually test the doSomeMethod function and not that Grunt registered a task or logged to the CLI. That's already well tested.

A lot of Grunt plugins work in this way, in fact many are wrappers around existing node modules. For example, grunt-recess is a wrapper of twitter/recess:

One of my own modules is more Grunt specific, but the tests for that focus on the actual functionality of the module. You can have a look at that here:

https://github.com/ben-eb/grunt-available-tasks/blob/master/test/lib/filterTasks.test.js

I'm also testing with Mocha. I'd recommend that you use grunt-mocha-test to run your tests through Grunt (as well as JSHint and others).

Upvotes: 5

Related Questions