Posted on January 21, 2015 by Chris Harrington

Testing a Browserify project with Jasmine and Grunt

The WordPress theme for this site has been built (read: over-engineered) with Browserify and React. Most of it is pretty straightforward, but the widgets on the right are a little more complicated. I’ve only just started working with Browserify in general, so I had a relatively difficult time setting up a workflow for testing some of my modules. If you’re unaware, Browserify works by bundling up all of your CommonJS modules and any modules in your node_modules folder for easy use throughout your application using require. You provide the entry point to your application, and Browserify will step through all of the require statements to pull in all the appropriate files and modules. It’s a neat system and, in general, I’m a big fan of it, but I had to change the way I usually test my JavaScript files. I’m using Grunt for my build tool, so the goal here is to be able to type grunt test from the command line and have all my specs run as per usual.

Dependencies

  • Browserify – used to bundle together both the application source and the Jasmine spec files.
  • Jasmine – the unit testing framework.
  • Grunt – the task runner.
  • grunt-browserify – allows us to run Browserify directly from a Grunt task.
  • grunt-contrib-jasmine – lets us run Jasmine unit tests from a Grunt task.

Browserify Configuration

I mentioned above that Browserify works by providing the entry point into your application (typically an initialize.js or similar), and it’ll recursively step through all of the required modules and files until it’s got a complete set of needed modules, then it’ll bundle up everything into a single file that you include on your app somewhere via a script tag. We can leverage this behaviour for testing, too, by providing all of our spec files instead of just our single entry point. In a Gruntfile, it looks similar to this:

browserify: {
	specs: {
		src: ["test/**/*.test.js"],
		dest: "test/specs.js",
		options: {
			browserifyOptions: {
				debug: true,
				paths: ["./node_modules", "./script/app"],
			}
		}
	}
}

Here, we’re telling Browserify to recursively look in the “test” folder for any scripts that end with “.test.js”, which is how I typically name my spec files. Because my specs will require the source files to test against, Browserify will pull in the correct source files, too. The dest configuration element indicates that Browserify should write the bundle to “test/specs.js”.

Jasmine Configuration

The grunt-contrib-jasmine project allows us to configure a Grunt task to generate a SpecRunner.html file that’ll run against a headless browser (PhantomJS) when executed. To do this, we need to provide it with some configuration, including the location of your source and spec files, minimally. In the previous step, Browserify has bundled up all of our source and spec files into a single file, so this doesn’t really apply to us, but that’s ok, as we can just provide an empty array to the Jasmine Grunt task for the source files and it’ll still run the specs as specified, as such:

jasmine: {
	tests: {
		src: [],
		options: {
			outfile: "test/_SpecRunner.html",
			//keepRunner: true,
			specs: "test/specs.js"      
		}
	}
}

The outfile configuration option tells the Grunt task where to place the temporary SpecRunner.html file. It gets deleted after every run unless you set keepRunner to true, which is useful if you run into some problems and need to see exactly what’s getting run.

Conclusion

That’s it! Here’s the entirety of the Gruntfile which you’ll need:

grunt.initConfig({
        browserify: {
		specs: {
			src: ["test/**/*.test.js"],
			dest: "test/specs.js",
			options: {
				browserifyOptions: {
					debug: true,
					paths: ["./node_modules", "./script/app"],
				}
			}
		}
        },
		
	jasmine: {
		tests: {
			src: [],
			options: {
				outfile: "test/_SpecRunner.html",
				specs: "test/specs.js"      
			}
		}
	}
});
    
grunt.registerTask("test", ["browserify:specs", "jasmine"]);

And now we can run our Jasmine tests via the command line with grunt test. Thanks for reading!